Files
skybridge/internal/services/auth_service.go
2025-08-22 15:01:40 -04:00

148 lines
4.5 KiB
Go

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
}