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