diff --git a/internal/api/middleware.go b/internal/api/middleware.go index 34ddc0072..2fbf96611 100644 --- a/internal/api/middleware.go +++ b/internal/api/middleware.go @@ -151,6 +151,33 @@ func (a *API) requireAdminCredentials(w http.ResponseWriter, req *http.Request) return a.requireAdmin(ctx, w, req) } +func (a *API) isAdmin(w http.ResponseWriter, req *http.Request) (context.Context, bool, error) { + t, err := a.extractBearerToken(req) + if err != nil || t == "" { + return nil, false, err + } + + ctx, err := a.parseJWTClaims(t, req) + if err != nil { + a.clearCookieTokens(a.config, w) + return ctx, false, err + } + + claims := getClaims(ctx) + if claims == nil { + return ctx, false, unauthorizedError("Invalid token") + } + + adminRoles := a.config.JWT.AdminRoles + + if isStringInSlice(claims.Role, adminRoles) { + // successful authentication + return ctx, true, nil + } + + return ctx, false, unauthorizedError("User not allowed") +} + func (a *API) requireEmailProvider(w http.ResponseWriter, req *http.Request) (context.Context, error) { ctx := req.Context() config := a.config @@ -170,13 +197,13 @@ func (a *API) verifyCaptcha(w http.ResponseWriter, req *http.Request) (context.C return ctx, nil } - if _, err := a.requireAdminCredentials(w, req); err == nil { - // skip captcha validation if authorization header contains an admin role - return ctx, nil - } else if err != nil { + ctx, isAdminUser, err := a.isAdmin(w, req) + if err != nil { return nil, err } - + if isAdminUser { + return ctx, nil + } verificationResult, err := security.VerifyRequest(req, strings.TrimSpace(config.Security.Captcha.Secret), config.Security.Captcha.Provider) if err != nil { return nil, internalServerError("captcha verification process failed").WithInternalError(err)