wip
This commit is contained in:
102
mangezmieux-backend/internal/middleware/introspect.go
Normal file
102
mangezmieux-backend/internal/middleware/introspect.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
model2 "mangezmieux-backend/internal/acl/model"
|
||||
"mangezmieux-backend/internal/jwt"
|
||||
"mangezmieux-backend/internal/logger"
|
||||
"mangezmieux-backend/internal/responses"
|
||||
"mangezmieux-backend/internal/users/model"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const CtxUser = "user"
|
||||
const CtxUserRight = "userRight"
|
||||
const CtxRole = "role"
|
||||
const CtxToken = "token"
|
||||
|
||||
type IntrospectService interface {
|
||||
Introspect(token string) (user *model.User, err error)
|
||||
GetRole(ctx context.Context, user *model.User) (userRight *model2.UserRight, err error)
|
||||
GetAllRole(ctx context.Context) ([]*model2.Role, error)
|
||||
}
|
||||
|
||||
func GetAuthenticationMiddleware(introspectService IntrospectService, jwtService *jwt.Service) gin.HandlerFunc {
|
||||
|
||||
return func(c *gin.Context) {
|
||||
token, err := getTokenFromGinCtx(c)
|
||||
c.Set(CtxToken, token)
|
||||
|
||||
ctx := c.Request.Context()
|
||||
ctx = context.WithValue(ctx, CtxToken, token)
|
||||
if err != nil {
|
||||
logger.GetLogger().WithError(err).Debug("no token found")
|
||||
responses.JSONErrorWithMessage(c.Writer, responses.ErrBadRequestFormat, err.Error())
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
_, err = jwtService.ValidateToken(token)
|
||||
if err != nil {
|
||||
logger.GetLogger().WithError(err).Debug("error during token validation")
|
||||
responses.JSONErrorWithMessage(c.Writer, responses.ErrBadRequestFormat, err.Error())
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
user, err := introspectService.Introspect(token)
|
||||
if err != nil {
|
||||
logger.GetLogger().WithError(err).Debug("error during introspect")
|
||||
responses.JSONErrorWithMessage(c.Writer, responses.ErrBadRequestFormat, err.Error())
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Set(CtxUser, user)
|
||||
|
||||
userRight, err := introspectService.GetRole(ctx, user)
|
||||
if err != nil {
|
||||
logger.GetLogger().WithError(err).Debug("error during getting role for user")
|
||||
responses.JSONErrorWithMessage(c.Writer, responses.ErrBadRequestFormat, err.Error())
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Set(CtxUserRight, userRight)
|
||||
|
||||
roles, err := introspectService.GetAllRole(ctx)
|
||||
if err != nil {
|
||||
logger.GetLogger().WithError(err).Debug("error during getting role map")
|
||||
responses.JSONErrorWithMessage(c.Writer, responses.ErrBadRequestFormat, err.Error())
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Set(CtxRole, roles)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// getTokenFromGinCtx allow to get the access token of the request in the Authorization request header.
|
||||
// It will split the header and remove the Bearer part to extract only the token.
|
||||
func getTokenFromGinCtx(c *gin.Context) (string, error) {
|
||||
auth := c.GetHeader("Authorization")
|
||||
if auth != "" {
|
||||
authSplitted := strings.SplitN(auth, " ", 2)
|
||||
if len(authSplitted) != 2 {
|
||||
return "", errors.New("malformed authorization header")
|
||||
}
|
||||
|
||||
if strings.ToUpper(authSplitted[0]) != strings.ToUpper("Bearer") && strings.ToUpper(authSplitted[0]) != strings.ToUpper("JWT") {
|
||||
return "", errors.New("unsupported authentication scheme")
|
||||
}
|
||||
|
||||
return authSplitted[1], nil
|
||||
}
|
||||
|
||||
if cookie, err := c.Cookie("token"); err == nil {
|
||||
return cookie, nil
|
||||
}
|
||||
|
||||
return "", errors.New("no token found in the request")
|
||||
}
|
||||
Reference in New Issue
Block a user