added keycloakclaims package for convenience
This commit is contained in:
parent
ef64b6cff8
commit
7f3f67364f
78
keycloakclaims/claims.go
Normal file
78
keycloakclaims/claims.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package keycloakclaims
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.icod.de/dalu/ginoidc/ginerror"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Claims represent the condensed and stripped version of Keycloak's JWT claims payload
|
||||||
|
type Claims struct {
|
||||||
|
Sub string `json:"sub,omitempty"`
|
||||||
|
RealmAccess struct {
|
||||||
|
Roles []string `json:"roles,omitempty"`
|
||||||
|
} `json:"realm_access,omitempty"`
|
||||||
|
PreferredUsername string `json:"preferred_username,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromRequest returns a Claims instance or nil if and error occurs.
|
||||||
|
// In case of an error it sets or appends to the "oidcerrors" context value of *gin.Context
|
||||||
|
func FromRequest(cx *gin.Context) *Claims {
|
||||||
|
claimsValue, found := cx.Get("claims")
|
||||||
|
if !found {
|
||||||
|
const errText = "claims not present"
|
||||||
|
errorType := ginerror.Error{
|
||||||
|
Description: errText,
|
||||||
|
Error: errors.New(errText),
|
||||||
|
}
|
||||||
|
if e := addOrExtendErrors(cx, "oidcerrors", errorType); e != nil {
|
||||||
|
log.Println(e.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
claims, ok := claimsValue.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
const errText = "claims are not of type map[string]interface{}"
|
||||||
|
errorType := ginerror.Error{
|
||||||
|
Description: errText,
|
||||||
|
Error: errors.New(errText),
|
||||||
|
}
|
||||||
|
if e := addOrExtendErrors(cx, "oidcerrors", errorType); e != nil {
|
||||||
|
log.Println(e.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := new(Claims)
|
||||||
|
c.Sub, _ = claims["sub"].(string)
|
||||||
|
c.PreferredUsername, _ = claims["preferred_username"].(string)
|
||||||
|
c.RealmAccess, _ = claims["realm_access"].(struct {
|
||||||
|
Roles []string `json:"roles,omitempty"`
|
||||||
|
})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// addOrExtendErrors adds or appends to the options.ErrorContextKeyName values
|
||||||
|
func addOrExtendErrors(cx *gin.Context, key string, newerror ginerror.Error) error {
|
||||||
|
errorsValue, errorsFound := cx.Get("oidcerrors")
|
||||||
|
if !errorsFound {
|
||||||
|
var errs []ginerror.Error
|
||||||
|
errs = append(errs, newerror)
|
||||||
|
// TODO: find a way to get the error context key from options
|
||||||
|
cx.Set("oidcerrors", errs)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
errs, ok := errorsValue.([]ginerror.Error)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("claims: errorsValue is not of type []ginerror.Error")
|
||||||
|
} else {
|
||||||
|
errs = append(errs, newerror)
|
||||||
|
// TODO: find a way to get the error context key from options
|
||||||
|
cx.Set("oidcerrors", errs)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user