ginoidc/gin.go

68 lines
1.9 KiB
Go
Raw Normal View History

2021-11-16 15:47:43 +01:00
package ginoidc
2021-11-14 16:37:58 +01:00
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...)
}
2021-11-17 11:12:26 +01:00
// onError is called when there's an error.
2021-11-14 16:37:58 +01:00
func onError(c *gin.Context, errorHandler options.ErrorHandler, statusCode int, description options.ErrorDescription, err error) {
c.AbortWithStatusJSON(statusCode, gin.H{"error": err.Error()})
}
2021-11-16 15:55:07 +01:00
// toGinHandler creates a gin.HandlerFunc so the stdlib handler can be used as a gin middleware.
2021-11-14 16:37:58 +01:00
func toGinHandler(parseToken oidc.ParseTokenFunc, setters ...options.Option) gin.HandlerFunc {
opts := options.New(setters...)
2021-11-17 11:12:26 +01:00
var errs []ginerror.Error
2021-11-14 16:37:58 +01:00
2021-11-17 11:12:26 +01:00
return func(c *gin.Context) {
2021-11-14 16:37:58 +01:00
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 {
2021-11-17 11:12:26 +01:00
errs = append(errs, ginerror.Error{
Description: string(options.GetTokenErrorDescription),
2021-11-14 16:37:58 +01:00
Error: err,
})
2021-11-17 11:12:26 +01:00
c.Set(string(opts.ErrorsContextKeyName), errs)
2021-11-16 15:55:07 +01:00
c.Next()
return
2021-11-14 16:37:58 +01:00
}
}
2021-11-17 11:12:26 +01:00
token, err := parseToken(c, tokenString)
2021-11-14 16:37:58 +01:00
if err != nil {
2021-11-16 15:55:07 +01:00
onError(c, opts.ErrorHandler, http.StatusUnauthorized, options.ParseTokenErrorDescription, err)
return
2021-11-14 16:37:58 +01:00
}
2021-11-17 11:12:26 +01:00
tokenClaims, err := token.AsMap(c)
2021-11-14 16:37:58 +01:00
if err != nil {
2021-11-16 15:55:07 +01:00
onError(c, opts.ErrorHandler, http.StatusUnauthorized, options.ConvertTokenErrorDescription, err)
return
2021-11-14 16:37:58 +01:00
}
c.Set(string(opts.ClaimsContextKeyName), tokenClaims)
2021-11-14 16:37:58 +01:00
c.Next()
}
}