mirror of
https://github.com/hanzo-fi/stack.git
synced 2026-10-30 20:34:43 +00:00
82 lines
2.0 KiB
Go
82 lines
2.0 KiB
Go
package oidc
|
|
|
|
import (
|
|
"embed"
|
|
"html/template"
|
|
"net/http"
|
|
|
|
auth "github.com/formancehq/auth/pkg"
|
|
"github.com/formancehq/auth/pkg/delegatedauth"
|
|
"github.com/google/uuid"
|
|
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
|
"github.com/zitadel/oidc/v2/pkg/oidc"
|
|
"github.com/zitadel/oidc/v2/pkg/op"
|
|
)
|
|
|
|
//go:embed templates
|
|
var templateFs embed.FS
|
|
|
|
func authorizeErrorHandler() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
authError := r.URL.Query().Get("error")
|
|
tpl := template.Must(template.New("error.tmpl").
|
|
ParseFS(templateFs, "templates/error.tmpl"))
|
|
if err := tpl.Execute(w, map[string]interface{}{
|
|
"Error": authError,
|
|
"ErrorDescription": r.URL.Query().Get("error_description"),
|
|
}); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func authorizeCallbackHandler(
|
|
provider op.OpenIDProvider,
|
|
storage Storage,
|
|
relyingParty rp.RelyingParty,
|
|
) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
state, err := delegatedauth.DecodeDelegatedState(r.URL.Query().Get("state"))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
authRequest, err := storage.FindAuthRequest(r.Context(), state.AuthRequestID)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
tokens, err := rp.CodeExchange[*oidc.IDTokenClaims](r.Context(), r.URL.Query().Get("code"), relyingParty)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
userInfos, err := rp.Userinfo(tokens.AccessToken, "Bearer", tokens.IDTokenClaims.GetSubject(), relyingParty)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
user, err := storage.FindUserBySubject(r.Context(), tokens.IDTokenClaims.GetSubject())
|
|
if err != nil {
|
|
user = &auth.User{
|
|
ID: uuid.NewString(),
|
|
Subject: userInfos.Subject,
|
|
Email: userInfos.Email,
|
|
}
|
|
if err := storage.SaveUser(r.Context(), *user); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
authRequest.UserID = user.ID
|
|
|
|
if err := storage.UpdateAuthRequest(r.Context(), *authRequest); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
w.Header().Set("Location", op.AuthCallbackURL(provider)(r.Context(), state.AuthRequestID))
|
|
w.WriteHeader(http.StatusFound)
|
|
}
|
|
}
|