package middleware import ( "context" "net/http" "strings" "git.unsupervised.ca/walkies/internal/auth" "git.unsupervised.ca/walkies/internal/respond" ) type contextKey string const claimsKey contextKey = "claims" func Authenticate(authSvc *auth.Service) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { header := r.Header.Get("Authorization") if !strings.HasPrefix(header, "Bearer ") { respond.Error(w, http.StatusUnauthorized, "missing or invalid authorization header") return } claims, err := authSvc.Parse(strings.TrimPrefix(header, "Bearer ")) if err != nil { respond.Error(w, http.StatusUnauthorized, "invalid token") return } ctx := context.WithValue(r.Context(), claimsKey, claims) next.ServeHTTP(w, r.WithContext(ctx)) }) } } func RequireAdmin(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { claims := ClaimsFromContext(r.Context()) if claims == nil || claims.Role != "admin" { respond.Error(w, http.StatusForbidden, "admin access required") return } next.ServeHTTP(w, r) }) } func ClaimsFromContext(ctx context.Context) *auth.Claims { claims, _ := ctx.Value(claimsKey).(*auth.Claims) return claims }