You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.5 KiB
Go

package auth
import (
"github.com/gofiber/fiber/v2"
)
// JWTMiddleware provides JWT authentication middleware
type JWTMiddleware struct {
authService *MockAuthService
}
// NewJWTMiddleware creates a new JWT middleware
func NewJWTMiddleware(authService *MockAuthService) *JWTMiddleware {
return &JWTMiddleware{
authService: authService,
}
}
// Authenticate middleware validates JWT tokens
func (m *JWTMiddleware) Authenticate() fiber.Handler {
return func(c *fiber.Ctx) error {
// Extract token from Authorization header
tokenString, err := extractToken(c)
if err != nil {
return unauthorizedError(c, err.Error())
}
// Validate token and set user context
if err := validateAndSetContext(c, m.authService, tokenString); err != nil {
return unauthorizedError(c, ErrInvalidToken, err.Error())
}
return c.Next()
}
}
// RequireRole middleware requires specific roles
func (m *JWTMiddleware) RequireRole(requiredRole string) fiber.Handler {
return func(c *fiber.Ctx) error {
userRoles, ok := c.Locals(RolesKey).([]string)
if !ok {
return forbiddenError(c, ErrNoRolesFound)
}
// Check if user has required role using helper function
if !hasRole(c, requiredRole) {
return forbiddenError(c, ErrInsufficientPermissions, fiber.Map{
"required_role": requiredRole,
"user_roles": userRoles,
})
}
return c.Next()
}
}
// RequireAnyRole middleware requires any of the specified roles
func (m *JWTMiddleware) RequireAnyRole(requiredRoles ...string) fiber.Handler {
return func(c *fiber.Ctx) error {
userRoles, ok := c.Locals(RolesKey).([]string)
if !ok {
return forbiddenError(c, ErrNoRolesFound)
}
// Check if user has any of the required roles using helper function
if !HasAnyRole(c, requiredRoles...) {
return forbiddenError(c, ErrInsufficientPermissions, fiber.Map{
"required_roles": requiredRoles,
"user_roles": userRoles,
})
}
return c.Next()
}
}
// Optional middleware validates token if present, but allows requests without tokens
func (m *JWTMiddleware) Optional() fiber.Handler {
return func(c *fiber.Ctx) error {
// Extract token from Authorization header
tokenString, err := extractToken(c)
if err != nil {
// No token or invalid format, continue without setting user context
return c.Next()
}
// Try to validate token and set user context
// If validation fails, continue without blocking the request
validateAndSetContext(c, m.authService, tokenString)
return c.Next()
}
}