package middleware import ( "net/http" "strconv" "strings" "git.artlef.fr/bibliomane/internal/jwtauth" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" ) func Auth() gin.HandlerFunc { return func(c *gin.Context) { //do not check current user if we are creating an account or logging in if strings.HasPrefix(c.FullPath(), "/ws/auth/") { return } //do not check appinfo if strings.HasPrefix(c.FullPath(), "/ws/appinfo") { return } //do not check static files if strings.HasPrefix(c.FullPath(), "/static/bookcover/") { return } jwtokenStr := jwtFromBearerToken(c.GetHeader("Authorization")) jwtoken, err := jwt.Parse(jwtokenStr, func(token *jwt.Token) (any, error) { return jwtauth.GetJwtKey() }, jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()})) if err != nil { abortError(c) return } //check admin rights if strings.HasPrefix(c.FullPath(), "/ws/admin/") && !hasAdminRights(jwtoken) { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "You do not have the right to access this resource."}) return } username, err := jwtoken.Claims.GetSubject() if err != nil { abortError(c) } else { c.Set("user", username) } } } func jwtFromBearerToken(bearerToken string) string { splitToken := strings.Split(bearerToken, " ") if len(splitToken) == 2 { return splitToken[1] } else { return "" } } func hasAdminRights(token *jwt.Token) bool { claims, ok := token.Claims.(jwt.MapClaims) if !ok { return false } raw, ok := claims["admin"] if !ok { return false } adminStr, ok := raw.(string) if !ok { return false } isAdmin, err := strconv.ParseBool(adminStr) if err != nil { return false } return isAdmin } func abortError(c *gin.Context) { c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "You must be logged in to access this resource."}) }