package middleware import ( "context" "net/http" "strings" "github.com/rede5/gohorsejobs/backend/internal/utils" ) type contextKey string const ( UserKey contextKey = "user" ) // AuthMiddleware verifies the JWT token and adds user claims to the context func AuthMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { authHeader := r.Header.Get("Authorization") if authHeader == "" { http.Error(w, "Authorization header required", http.StatusUnauthorized) return } parts := strings.Split(authHeader, " ") if len(parts) != 2 || parts[0] != "Bearer" { http.Error(w, "Invalid authorization header format", http.StatusUnauthorized) return } tokenString := parts[1] claims, err := utils.ValidateJWT(tokenString) if err != nil { http.Error(w, "Invalid or expired token", http.StatusUnauthorized) return } ctx := context.WithValue(r.Context(), UserKey, claims) next.ServeHTTP(w, r.WithContext(ctx)) }) } // RequireRole checks if the authenticated user has the required role func RequireRole(roles ...string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { claims, ok := r.Context().Value(UserKey).(*utils.Claims) if !ok { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // SuperAdmin has access to everything if claims.Role == "superadmin" { next.ServeHTTP(w, r) return } for _, role := range roles { if claims.Role == role { next.ServeHTTP(w, r) return } } http.Error(w, "Forbidden: insufficient permissions", http.StatusForbidden) }) } }