auth.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package middleware
  2. import (
  3. "context"
  4. "net/http"
  5. "time"
  6. "git.linuxforward.com/byop/byop-engine/auth"
  7. "github.com/gin-gonic/gin"
  8. "github.com/golang-jwt/jwt/v5"
  9. )
  10. // JWT secret key - in production, this should be loaded from environment variables
  11. var jwtSecret = []byte("your-secret-key-here")
  12. // Claims represents the JWT claims
  13. type Claims struct {
  14. UserID string `json:"user_id"`
  15. Role string `json:"role"`
  16. jwt.RegisteredClaims
  17. }
  18. // Auth middleware that accepts the auth service as dependency
  19. func Auth(authService auth.Service) gin.HandlerFunc {
  20. return func(c *gin.Context) {
  21. // Get token from request
  22. token := extractTokenFromHeader(c)
  23. if token == "" {
  24. c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"})
  25. c.Abort()
  26. return
  27. }
  28. // Validate token using the auth service
  29. clientID, err := authService.ValidateToken(c.Request.Context(), token)
  30. if err != nil {
  31. c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
  32. c.Abort()
  33. return
  34. }
  35. // Set client ID in context for later use
  36. c.Set("clientID", clientID)
  37. c.Next()
  38. }
  39. }
  40. // GenerateToken creates a new JWT token for a user
  41. func GenerateToken(userID, role string) (string, error) {
  42. // Set claims with expiration time
  43. claims := &Claims{
  44. UserID: userID,
  45. Role: role,
  46. RegisteredClaims: jwt.RegisteredClaims{
  47. ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // Token expires in 24 hours
  48. IssuedAt: jwt.NewNumericDate(time.Now()),
  49. Subject: userID,
  50. },
  51. }
  52. // Create token with claims
  53. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  54. // Sign the token with the secret key
  55. tokenString, err := token.SignedString(jwtSecret)
  56. if err != nil {
  57. return "", err
  58. }
  59. return tokenString, nil
  60. }
  61. // GetUserIDFromContext retrieves the user ID from the request context
  62. func GetUserIDFromContext(ctx context.Context) string {
  63. userID, ok := ctx.Value("user_id").(string)
  64. if !ok {
  65. return ""
  66. }
  67. return userID
  68. }
  69. // GetRoleFromContext retrieves the user role from the request context
  70. func GetRoleFromContext(ctx context.Context) string {
  71. role, ok := ctx.Value("role").(string)
  72. if !ok {
  73. return ""
  74. }
  75. return role
  76. }
  77. // IsAdmin checks if the user in the context has admin role
  78. func IsAdmin(ctx context.Context) bool {
  79. role := GetRoleFromContext(ctx)
  80. return role == "admin"
  81. }
  82. // extractTokenFromHeader gets the JWT token from the Authorization header
  83. func extractTokenFromHeader(c *gin.Context) string {
  84. authHeader := c.GetHeader("Authorization")
  85. if authHeader == "" {
  86. return ""
  87. }
  88. // Check if the header has the format "Bearer <token>"
  89. if len(authHeader) > 7 && authHeader[:7] == "Bearer " {
  90. return authHeader[7:]
  91. }
  92. return ""
  93. }