package user import ( "net/http" "strings" "github.com/gin-gonic/gin" "openteam/server/internal/pkg/httpx" "openteam/server/internal/pkg/jwt" "openteam/server/internal/store" ) const ( ctxUserKey = "current_user" ctxClaimsKey = "current_claims" ) // Current returns the authenticated user (set by Middleware). func Current(c *gin.Context) *store.User { if v, ok := c.Get(ctxUserKey); ok { if u, ok := v.(*store.User); ok { return u } } return nil } // Claims returns the JWT claims of the current request. func Claims(c *gin.Context) *jwt.Claims { if v, ok := c.Get(ctxClaimsKey); ok { if cl, ok := v.(*jwt.Claims); ok { return cl } } return nil } // Middleware authenticates the management API via an access token. func (s *Service) Middleware(secret string) gin.HandlerFunc { return func(c *gin.Context) { auth := c.GetHeader("Authorization") if !strings.HasPrefix(auth, "Bearer ") { httpx.Fail(c, http.StatusUnauthorized, "missing bearer token") return } token := strings.TrimPrefix(auth, "Bearer ") claims, err := jwt.Parse(secret, token) if err != nil || claims.Type != "access" { httpx.Fail(c, http.StatusUnauthorized, "invalid or expired token") return } var u store.User if err := s.db.First(&u, claims.UserID).Error; err != nil || u.Status != "active" { httpx.Fail(c, http.StatusUnauthorized, "user not found or disabled") return } c.Set(ctxUserKey, &u) c.Set(ctxClaimsKey, claims) c.Next() } } // RequireAdmin guards admin-only routes. func RequireAdmin() gin.HandlerFunc { return func(c *gin.Context) { u := Current(c) if u == nil || u.Role != "admin" { httpx.Fail(c, http.StatusForbidden, "admin only") return } c.Next() } }