package middleware import ( "net/http" "strings" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" ) var jwtSecret []byte func SetJWTSecret(secret string) { jwtSecret = []byte(secret) } type Claims struct { UserID int64 `json:"user_id"` Email string `json:"email"` Username string `json:"username"` IsAdmin bool `json:"is_admin"` jwt.RegisteredClaims } func AuthRequired() gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"}) c.Abort() return } tokenString := strings.TrimPrefix(authHeader, "Bearer ") if tokenString == authHeader { c.JSON(http.StatusUnauthorized, gin.H{"error": "Bearer token required"}) c.Abort() return } claims := &Claims{} token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { return jwtSecret, nil }) if err != nil || !token.Valid { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) c.Abort() return } c.Set("user", claims) c.Next() } } func AdminRequired() gin.HandlerFunc { return func(c *gin.Context) { userVal, exists := c.Get("user") if !exists { c.JSON(http.StatusUnauthorized, gin.H{"error": "Not authenticated"}) c.Abort() return } claims := userVal.(*Claims) if !claims.IsAdmin { c.JSON(http.StatusForbidden, gin.H{"error": "Admin access required"}) c.Abort() return } c.Next() } } func CORSMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE, PATCH") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() } } func LoggerMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Next() status := c.Writer.Status() if status >= 400 { // Log error responses } } } func RateLimitMiddleware(requestsPerMinute int) gin.HandlerFunc { return func(c *gin.Context) { c.Next() } }