docs(example): implement OpenID Provider (#165)
* chore(example): implement OpenID Provider * jwt profile and fixes * some comments * remove old op example * fix code flow example * add service user and update readme * fix password for example use * ignore example and mock folders for code coverage * Update example/server/internal/storage.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update client.go Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
parent
c195452bb0
commit
885fe0d45c
13 changed files with 1280 additions and 427 deletions
115
example/server/login.go
Normal file
115
example/server/login.go
Normal file
|
@ -0,0 +1,115 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
const (
|
||||
queryAuthRequestID = "authRequestID"
|
||||
)
|
||||
|
||||
var (
|
||||
loginTmpl, _ = template.New("login").Parse(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Login</title>
|
||||
</head>
|
||||
<body style="display: flex; align-items: center; justify-content: center; height: 100vh;">
|
||||
<form method="POST" action="/login/username" style="height: 200px; width: 200px;">
|
||||
|
||||
<input type="hidden" name="id" value="{{.ID}}">
|
||||
|
||||
<div>
|
||||
<label for="username">Username:</label>
|
||||
<input id="username" name="username" style="width: 100%">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="password">Password:</label>
|
||||
<input id="password" name="password" style="width: 100%">
|
||||
</div>
|
||||
|
||||
<p style="color:red; min-height: 1rem;">{{.Error}}</p>
|
||||
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>`)
|
||||
)
|
||||
|
||||
type login struct {
|
||||
authenticate authenticate
|
||||
router *mux.Router
|
||||
callback func(string) string
|
||||
}
|
||||
|
||||
func NewLogin(authenticate authenticate, callback func(string) string) *login {
|
||||
l := &login{
|
||||
authenticate: authenticate,
|
||||
callback: callback,
|
||||
}
|
||||
l.createRouter()
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *login) createRouter() {
|
||||
l.router = mux.NewRouter()
|
||||
l.router.Path("/username").Methods("GET").HandlerFunc(l.loginHandler)
|
||||
l.router.Path("/username").Methods("POST").HandlerFunc(l.checkLoginHandler)
|
||||
}
|
||||
|
||||
type authenticate interface {
|
||||
CheckUsernamePassword(username, password, id string) error
|
||||
}
|
||||
|
||||
func (l *login) loginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("cannot parse form:%s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
//the oidc package will pass the id of the auth request as query parameter
|
||||
//we will use this id through the login process and therefore pass it to the login page
|
||||
renderLogin(w, r.FormValue(queryAuthRequestID), nil)
|
||||
}
|
||||
|
||||
func renderLogin(w http.ResponseWriter, id string, err error) {
|
||||
var errMsg string
|
||||
if err != nil {
|
||||
errMsg = err.Error()
|
||||
}
|
||||
data := &struct {
|
||||
ID string
|
||||
Error string
|
||||
}{
|
||||
ID: id,
|
||||
Error: errMsg,
|
||||
}
|
||||
err = loginTmpl.Execute(w, data)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *login) checkLoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("cannot parse form:%s", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
username := r.FormValue("username")
|
||||
password := r.FormValue("password")
|
||||
id := r.FormValue("id")
|
||||
err = l.authenticate.CheckUsernamePassword(username, password, id)
|
||||
if err != nil {
|
||||
renderLogin(w, id, err)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, l.callback(id), http.StatusFound)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue