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