package oidcgin import ( "fmt" "net/http" "git.icod.de/dalu/ginoidc/ginerror" "git.icod.de/dalu/oidc" "git.icod.de/dalu/oidc/options" "github.com/gin-gonic/gin" ) // New returns an OpenID Connect (OIDC) discovery handler (middleware) // to be used with `gin`. func New(setters ...options.Option) gin.HandlerFunc { oidcHandler, err := oidc.NewHandler(setters...) if err != nil { panic(fmt.Sprintf("oidc discovery: %v", err)) } return toGinHandler(oidcHandler.ParseToken, setters...) } func onError(c *gin.Context, errorHandler options.ErrorHandler, statusCode int, description options.ErrorDescription, err error) { c.AbortWithStatusJSON(statusCode, gin.H{"error": err.Error()}) } func toGinHandler(parseToken oidc.ParseTokenFunc, setters ...options.Option) gin.HandlerFunc { opts := options.New(setters...) return func(c *gin.Context) { var errorTypes []ginerror.Error ctx := c.Request.Context() tokenString, err := oidc.GetTokenString(c.Request.Header.Get, opts.TokenString) if err != nil { if !opts.Permissive { onError(c, opts.ErrorHandler, http.StatusBadRequest, options.GetTokenErrorDescription, err) return } else { errorTypes = append(errorTypes, ginerror.Error{ Description: options.GetTokenErrorDescription, Error: err, }) } } token, err := parseToken(ctx, tokenString) if err != nil { if !opts.Permissive { onError(c, opts.ErrorHandler, http.StatusUnauthorized, options.ParseTokenErrorDescription, err) return } else { errorTypes = append(errorTypes, ginerror.Error{ Description: options.GetTokenErrorDescription, Error: err, }) } } tokenClaims, err := token.AsMap(ctx) if err != nil { if !opts.Permissive { onError(c, opts.ErrorHandler, http.StatusUnauthorized, options.ConvertTokenErrorDescription, err) return } else { errorTypes = append(errorTypes, ginerror.Error{ Description: options.GetTokenErrorDescription, Error: err, }) } } c.Set(string(opts.ClaimsContextKeyName), tokenClaims) c.Set(string(opts.ErrorsContextKeyName), errorTypes) c.Next() } }