mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
130 lines
3.4 KiB
Go
130 lines
3.4 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bugulma/backend/internal/service"
|
|
"context"
|
|
"log"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// Context keys for storing user/org info
|
|
type contextKey string
|
|
|
|
const (
|
|
UserIDKey contextKey = "user_id"
|
|
OrgIDKey contextKey = "org_id"
|
|
)
|
|
|
|
// ContextMiddleware extracts user and organization information from headers/tokens
|
|
func ContextMiddleware(authService *service.AuthService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Try to extract user ID from JWT token
|
|
userID, orgID := extractFromJWT(c, authService)
|
|
if userID != "" {
|
|
ctx := context.WithValue(c.Request.Context(), UserIDKey, userID)
|
|
c.Request = c.Request.WithContext(ctx)
|
|
// Also set in Gin context for handlers that use c.Get()
|
|
c.Set("user_id", userID)
|
|
}
|
|
|
|
if orgID != "" {
|
|
ctx := context.WithValue(c.Request.Context(), OrgIDKey, orgID)
|
|
c.Request = c.Request.WithContext(ctx)
|
|
// Also set in Gin context for handlers that use c.Get()
|
|
c.Set("org_id", orgID)
|
|
}
|
|
|
|
// Fallback to headers/query params for development
|
|
if userID == "" {
|
|
userID = extractUserID(c)
|
|
if userID != "" {
|
|
ctx := context.WithValue(c.Request.Context(), UserIDKey, userID)
|
|
c.Request = c.Request.WithContext(ctx)
|
|
// Also set in Gin context for handlers that use c.Get()
|
|
c.Set("user_id", userID)
|
|
}
|
|
}
|
|
|
|
if orgID == "" {
|
|
orgID = extractOrgID(c)
|
|
if orgID != "" {
|
|
ctx := context.WithValue(c.Request.Context(), OrgIDKey, orgID)
|
|
c.Request = c.Request.WithContext(ctx)
|
|
// Also set in Gin context for handlers that use c.Get()
|
|
c.Set("org_id", orgID)
|
|
}
|
|
}
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// extractFromJWT extracts user and organization info from JWT token
|
|
func extractFromJWT(c *gin.Context, authService *service.AuthService) (string, string) {
|
|
authHeader := c.GetHeader("Authorization")
|
|
if !strings.HasPrefix(authHeader, "Bearer ") {
|
|
return "", ""
|
|
}
|
|
|
|
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
|
if tokenString == "" {
|
|
return "", ""
|
|
}
|
|
|
|
// Validate token and extract claims
|
|
_, claims, err := authService.ValidateTokenWithClaims(c.Request.Context(), tokenString)
|
|
if err != nil {
|
|
log.Printf("JWT validation failed: %v", err)
|
|
return "", ""
|
|
}
|
|
|
|
return claims.UserID, claims.OrgID
|
|
}
|
|
|
|
// extractUserID extracts user ID from request (fallback for development)
|
|
func extractUserID(c *gin.Context) string {
|
|
// Check query parameter (for development/testing)
|
|
if userID := c.Query("user_id"); userID != "" {
|
|
return userID
|
|
}
|
|
|
|
// Default fallback
|
|
return "system"
|
|
}
|
|
|
|
// extractOrgID extracts organization ID from request
|
|
func extractOrgID(c *gin.Context) string {
|
|
// Check X-Organization-ID header
|
|
if orgID := c.GetHeader("X-Organization-ID"); orgID != "" {
|
|
return orgID
|
|
}
|
|
|
|
// Check query parameter (for development/testing)
|
|
if orgID := c.Query("org_id"); orgID != "" {
|
|
return orgID
|
|
}
|
|
|
|
// For resource flow operations, we might need to determine org from path params
|
|
// This would be handled in the service layer based on the entity being operated on
|
|
|
|
return ""
|
|
}
|
|
|
|
// GetUserIDFromContext extracts user ID from context
|
|
func GetUserIDFromContext(ctx context.Context) string {
|
|
if userID, ok := ctx.Value(UserIDKey).(string); ok {
|
|
return userID
|
|
}
|
|
return "system"
|
|
}
|
|
|
|
// GetOrgIDFromContext extracts organization ID from context
|
|
func GetOrgIDFromContext(ctx context.Context) string {
|
|
if orgID, ok := ctx.Value(OrgIDKey).(string); ok {
|
|
return orgID
|
|
}
|
|
return ""
|
|
}
|