130 lines
2.7 KiB
Go
130 lines
2.7 KiB
Go
package middleware
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/wmms/wmms/internal/service"
|
|
"github.com/wmms/wmms/pkg/response"
|
|
)
|
|
|
|
const (
|
|
AuthorizationHeader = "Authorization"
|
|
BearerPrefix = "Bearer "
|
|
UserIDKey = "user_id"
|
|
UsernameKey = "username"
|
|
RoleKey = "role"
|
|
)
|
|
|
|
// AuthMiddleware validates JWT tokens
|
|
func AuthMiddleware() gin.HandlerFunc {
|
|
authSvc := service.NewAuthService()
|
|
|
|
return func(c *gin.Context) {
|
|
authHeader := c.GetHeader(AuthorizationHeader)
|
|
if authHeader == "" {
|
|
response.Unauthorized(c, "missing authorization header")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
if !strings.HasPrefix(authHeader, BearerPrefix) {
|
|
response.Unauthorized(c, "invalid authorization format")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
tokenString := strings.TrimPrefix(authHeader, BearerPrefix)
|
|
|
|
token, err := authSvc.ValidateToken(tokenString)
|
|
if err != nil {
|
|
response.Unauthorized(c, "invalid or expired token")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
// Set user info in context
|
|
c.Set(UserIDKey, token.UserID)
|
|
c.Set(UsernameKey, token.Username)
|
|
c.Set(RoleKey, token.Role)
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// AdminOnly middleware restricts access to admin role only
|
|
func AdminOnly() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
role, exists := c.Get(RoleKey)
|
|
if !exists {
|
|
response.Unauthorized(c, "unauthorized")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
if role != "admin" {
|
|
response.Forbidden(c, "admin access required")
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// GetCurrentUserID returns the current user's ID from context
|
|
func GetCurrentUserID(c *gin.Context) int64 {
|
|
if id, exists := c.Get(UserIDKey); exists {
|
|
return id.(int64)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// GetCurrentUsername returns the current username from context
|
|
func GetCurrentUsername(c *gin.Context) string {
|
|
if username, exists := c.Get(UsernameKey); exists {
|
|
return username.(string)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetCurrentRole returns the current user's role from context
|
|
func GetCurrentRole(c *gin.Context) string {
|
|
if role, exists := c.Get(RoleKey); exists {
|
|
return role.(string)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// OptionalAuth middleware extracts user info if token is present but doesn't require it
|
|
func OptionalAuth() gin.HandlerFunc {
|
|
authSvc := service.NewAuthService()
|
|
|
|
return func(c *gin.Context) {
|
|
authHeader := c.GetHeader(AuthorizationHeader)
|
|
if authHeader == "" {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
if !strings.HasPrefix(authHeader, BearerPrefix) {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
tokenString := strings.TrimPrefix(authHeader, BearerPrefix)
|
|
|
|
token, err := authSvc.ValidateToken(tokenString)
|
|
if err != nil {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
c.Set(UserIDKey, token.UserID)
|
|
c.Set(UsernameKey, token.Username)
|
|
c.Set(RoleKey, token.Role)
|
|
|
|
c.Next()
|
|
}
|
|
}
|