NAM-APJATEL-BACKEND/middleware/auth_middleware.go

95 lines
3.2 KiB
Go

package middleware
import (
"log"
"net/http"
"strings"
"users_management/m/config"
"users_management/m/model/entity"
"users_management/m/usecase"
"users_management/m/utils"
"users_management/m/utils/common"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// ConditionalAuthMiddleware checks config to decide whether to apply auth
func ConditionalAuthMiddleware(userUC usecase.UsersUsecase, authUC usecase.AuthUsecase, cfg *config.Config) gin.HandlerFunc {
return func(c *gin.Context) {
// If auth is disabled, skip authentication but set default values
if !cfg.AuthConfig.UserAuthEnabled {
log.Println("Authentication disabled - skipping auth middleware")
// Set default values for when auth is disabled
c.Set("userID", uuid.New()) // Generate a dummy UUID
c.Set("userName", "system")
c.Set("userRole", "Admin") // Default role when auth is disabled
c.Set("token", "no-auth-mode")
c.Next()
return
}
// If auth is enabled, run the local auth middleware
LocalAuthMiddleware(userUC, authUC)(c)
}
}
// LocalAuthMiddleware handles local JWT authentication
func LocalAuthMiddleware(userUC usecase.UsersUsecase, authUC usecase.AuthUsecase) gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
common.ErrorResponses(c, http.StatusUnauthorized, "Authorization token required")
c.Abort()
return
}
token = strings.TrimPrefix(token, "Bearer ")
c.Set("token", token)
// Validate JWT token locally
_, username, err := utils.ValidateJWT(token)
if err != nil {
log.Printf("JWT validation error: %v", err)
common.ErrorResponses(c, http.StatusUnauthorized, "Invalid or expired token")
c.Abort()
return
}
// Get user from local database
user, err := userUC.GetUserByUsername(username)
if err != nil {
log.Printf("User not found: %s", username)
common.ErrorResponses(c, http.StatusUnauthorized, "User not found")
c.Abort()
return
}
// Check if user is approved
switch user.Status {
case entity.UserStatusPending:
common.ErrorResponses(c, http.StatusForbidden, "Your account is pending approval from an administrator. Please wait for approval before accessing the system.")
c.Abort()
return
case entity.UserStatusRejected:
common.ErrorResponses(c, http.StatusForbidden, "Your account has been rejected. Please contact an administrator for more information.")
c.Abort()
return
case entity.UserStatusApproved:
// User is approved, continue with normal flow
c.Set("userID", user.ID)
c.Set("userName", user.Username)
c.Set("userRole", user.Role.Name)
default:
common.ErrorResponses(c, http.StatusForbidden, "Your account status is invalid. Please contact an administrator.")
c.Abort()
return
}
c.Next()
}
}