package services import ( "context" "fmt" "time" "go.uber.org/zap" "github.com/kms/api-key-service/internal/auth" "github.com/kms/api-key-service/internal/config" "github.com/kms/api-key-service/internal/domain" "github.com/kms/api-key-service/internal/errors" ) // authenticationService implements the AuthenticationService interface type authenticationService struct { config config.ConfigProvider logger *zap.Logger jwtManager *auth.JWTManager } // NewAuthenticationService creates a new authentication service func NewAuthenticationService(config config.ConfigProvider, logger *zap.Logger) AuthenticationService { jwtManager := auth.NewJWTManager(config, logger) return &authenticationService{ config: config, logger: logger, jwtManager: jwtManager, } } // GetUserID extracts user ID from context func (s *authenticationService) GetUserID(ctx context.Context) (string, error) { // For now, this is a simple implementation // In a real implementation, this would extract from JWT tokens, session, etc. if userID, ok := ctx.Value("user_id").(string); ok { return userID, nil } return "", fmt.Errorf("user ID not found in context") } // ValidatePermissions checks if user has required permissions func (s *authenticationService) ValidatePermissions(ctx context.Context, userID string, appID string, requiredPermissions []string) error { s.logger.Debug("Validating permissions", zap.String("user_id", userID), zap.String("app_id", appID), zap.Strings("required_permissions", requiredPermissions)) // TODO: Implement actual permission validation // For now, we'll just allow all requests return nil } // GetUserClaims retrieves user claims func (s *authenticationService) GetUserClaims(ctx context.Context, userID string) (map[string]string, error) { s.logger.Debug("Getting user claims", zap.String("user_id", userID)) // TODO: Implement actual claims retrieval // For now, return basic claims claims := map[string]string{ "user_id": userID, "email": userID, // Assuming user_id is email for now "name": "Test User", } return claims, nil } // ValidateJWTToken validates a JWT token and returns claims func (s *authenticationService) ValidateJWTToken(ctx context.Context, tokenString string) (*domain.AuthContext, error) { s.logger.Debug("Validating JWT token") // Validate the token using JWT manager claims, err := s.jwtManager.ValidateToken(tokenString) if err != nil { s.logger.Warn("JWT token validation failed", zap.Error(err)) return nil, err } // Check if token is revoked revoked, err := s.jwtManager.IsTokenRevoked(tokenString) if err != nil { s.logger.Error("Failed to check token revocation status", zap.Error(err)) return nil, errors.NewInternalError("Failed to validate token").WithInternal(err) } if revoked { s.logger.Warn("JWT token is revoked", zap.String("user_id", claims.UserID)) return nil, errors.NewAuthenticationError("Token has been revoked") } // Convert JWT claims to AuthContext authContext := &domain.AuthContext{ UserID: claims.UserID, TokenType: claims.TokenType, Permissions: claims.Permissions, Claims: claims.Claims, AppID: claims.AppID, } s.logger.Debug("JWT token validated successfully", zap.String("user_id", claims.UserID), zap.String("app_id", claims.AppID)) return authContext, nil } // GenerateJWTToken generates a new JWT token for a user func (s *authenticationService) GenerateJWTToken(ctx context.Context, userToken *domain.UserToken) (string, error) { s.logger.Debug("Generating JWT token", zap.String("user_id", userToken.UserID), zap.String("app_id", userToken.AppID)) // Generate the token using JWT manager tokenString, err := s.jwtManager.GenerateToken(userToken) if err != nil { s.logger.Error("Failed to generate JWT token", zap.Error(err)) return "", err } s.logger.Debug("JWT token generated successfully", zap.String("user_id", userToken.UserID), zap.String("app_id", userToken.AppID)) return tokenString, nil } // RefreshJWTToken refreshes an existing JWT token func (s *authenticationService) RefreshJWTToken(ctx context.Context, tokenString string, newExpiration time.Time) (string, error) { s.logger.Debug("Refreshing JWT token") // Refresh the token using JWT manager newTokenString, err := s.jwtManager.RefreshToken(tokenString, newExpiration) if err != nil { s.logger.Error("Failed to refresh JWT token", zap.Error(err)) return "", err } s.logger.Debug("JWT token refreshed successfully") return newTokenString, nil }