""" Auth Service Configuration Manages authentication configuration and route matching for the auth service. """ import logging from typing import List from services.base_service import BaseService, ServiceConfig from services.base_service.route_matcher import RouteConfig logger = logging.getLogger(__name__) class AuthServiceConfig(BaseService): """ Configuration for the auth service. Controls which routes require authentication, which are optional, and which are public (no auth needed). """ SERVICE_NAME = "auth_service" # Route configuration _route_config: RouteConfig = None # JWT configuration _jwt_secret: str = None _jwt_algorithm: str = "HS256" _jwt_expiry_hours: int = 24 # Google OAuth configuration _google_client_id: str = None # Admin configuration _admin_emails: List[str] = [] @classmethod def register( cls, required_urls: List[str] = None, optional_urls: List[str] = None, public_urls: List[str] = None, jwt_secret: str = None, jwt_algorithm: str = "HS256", jwt_expiry_hours: int = 24, google_client_id: str = None, admin_emails: List[str] = None, ) -> None: """ Register auth service configuration. Args: required_urls: URLs that REQUIRE authentication optional_urls: URLs where authentication is optional public_urls: URLs that don't need authentication jwt_secret: Secret key for JWT signing jwt_algorithm: JWT algorithm (default: HS256) jwt_expiry_hours: Token expiry in hours (default: 24) google_client_id: Google OAuth Client ID admin_emails: List of admin email addresses Raises: RuntimeError: If service is already registered ValueError: If jwt_secret is not provided """ if cls._registered: raise RuntimeError(f"{cls.SERVICE_NAME} is already registered") # Validate JWT secret if not jwt_secret: raise ValueError("jwt_secret is required for auth service") # Store route configuration cls._route_config = RouteConfig( required=required_urls or [], optional=optional_urls or [], public=public_urls or [], ) # Store JWT configuration cls._jwt_secret = jwt_secret cls._jwt_algorithm = jwt_algorithm cls._jwt_expiry_hours = jwt_expiry_hours # Store Google OAuth configuration cls._google_client_id = google_client_id # Store admin configuration cls._admin_emails = admin_emails or [] cls._registered = True logger.info(f"✅ {cls.SERVICE_NAME} registered successfully") logger.info(f" JWT algorithm: {cls._jwt_algorithm}") logger.info(f" JWT expiry: {cls._jwt_expiry_hours} hours") logger.info(f" Required URLs: {len(required_urls or [])}") logger.info(f" Optional URLs: {len(optional_urls or [])}") logger.info(f" Public URLs: {len(public_urls or [])}") logger.info(f" Admin emails: {len(cls._admin_emails)}") @classmethod def get_middleware(cls): """Return AuthMiddleware instance.""" from services.auth_service.middleware import AuthMiddleware return AuthMiddleware @classmethod def requires_auth(cls, path: str) -> bool: """Check if a URL path requires authentication.""" cls.assert_registered() return cls._route_config.is_required(path) @classmethod def allows_optional_auth(cls, path: str) -> bool: """Check if a URL path allows optional authentication.""" cls.assert_registered() return cls._route_config.is_optional(path) @classmethod def is_public(cls, path: str) -> bool: """Check if a URL path is public (no auth needed).""" cls.assert_registered() return cls._route_config.is_public(path) @classmethod def get_jwt_secret(cls) -> str: """Get JWT secret key.""" cls.assert_registered() return cls._jwt_secret @classmethod def get_jwt_algorithm(cls) -> str: """Get JWT algorithm.""" cls.assert_registered() return cls._jwt_algorithm @classmethod def get_jwt_expiry_hours(cls) -> int: """Get JWT expiry hours.""" cls.assert_registered() return cls._jwt_expiry_hours @classmethod def get_google_client_id(cls) -> str: """Get Google OAuth Client ID.""" cls.assert_registered() return cls._google_client_id @classmethod def is_admin(cls, email: str) -> bool: """Check if an email is an admin.""" cls.assert_registered() return email in cls._admin_emails @classmethod def get_admin_emails(cls) -> List[str]: """Get list of admin emails.""" cls.assert_registered() return cls._admin_emails.copy() __all__ = ['AuthServiceConfig']