fix(auth): export IsAdmin, fix bearer token fallback chain

This commit is contained in:
Claus Lohmar 2026-06-14 14:58:02 +00:00
parent 7c0d5a7b91
commit 1780cea340
2 changed files with 20 additions and 19 deletions

View file

@ -25,7 +25,7 @@ func (rc *RoleChecker) RequireAdmin(next http.Handler) http.Handler {
return
}
isAdmin, err := rc.isAdmin(userID)
isAdmin, err := rc.IsAdmin(userID)
if err != nil || !isAdmin {
http.Error(w, `{"error":"forbidden"}`, http.StatusForbidden)
return
@ -35,8 +35,8 @@ func (rc *RoleChecker) RequireAdmin(next http.Handler) http.Handler {
})
}
// isAdmin checks if a user has the admin role.
func (rc *RoleChecker) isAdmin(username string) (bool, error) {
// IsAdmin checks if a user has the admin role.
func (rc *RoleChecker) IsAdmin(username string) (bool, error) {
var role string
err := rc.db.QueryRow("SELECT role FROM users WHERE username = ?", username).Scan(&role)
if err == sql.ErrNoRows {

View file

@ -1,6 +1,7 @@
package main
import (
"context"
"flag"
"fmt"
"log/slog"
@ -130,26 +131,26 @@ func main() {
}
uiHandler.RegisterRoutes(mux, combinedAuth)
// --- Admin routes: session+role OR bearer token ---
adminRoleAuth := func(next http.Handler) http.Handler {
return sessionStore.SessionMiddleware(roleChecker.RequireAdmin(next))
}
// --- Admin auth: session (with admin role) OR bearer token ---
bearerAuth := admin.TokenAuthMiddleware(cfg.Admin.SecretToken)
// Combined: try session+role first, fall back to bearer token
adminAuth := func(next http.Handler) http.Handler {
return adminRoleAuth(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Check if session user exists and has admin role
userID, ok := auth.GetUserID(r)
if ok {
// Session is valid — already verified by RequireAdmin
_ = userID
next.ServeHTTP(w, r)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// First, try session-based authentication
cookie, err := r.Cookie("nextwks_session")
if err == nil && cookie != nil {
session, err := sessionStore.ValidateSession(cookie.Value)
if err == nil && session != nil {
isAdmin, _ := roleChecker.IsAdmin(session.UserID)
if isAdmin {
ctx := context.WithValue(r.Context(), auth.ContextUserID, session.UserID)
next.ServeHTTP(w, r.WithContext(ctx))
return
}
// No valid session — try bearer token
}
}
// Fall back to bearer token
bearerAuth(next).ServeHTTP(w, r)
}))
})
}
adminHandler.RegisterRoutes(mux, adminAuth)