gohorsejobs/backend/internal/middleware/auth.go
Tiago Yamamoto 1c7ef95c1a first commit
2025-12-09 19:04:48 -03:00

70 lines
1.7 KiB
Go

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)
})
}
}