""" Auth Middleware für LLM Gateway. Unterstützt: - API Key Auth (X-API-Key Header oder Authorization Bearer) - JWT Token Auth (vom Consent Service) """ import logging from typing import Optional from fastapi import HTTPException, Header, Depends from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials import jwt from ..config import get_config logger = logging.getLogger(__name__) security = HTTPBearer(auto_error=False) async def verify_api_key( x_api_key: Optional[str] = Header(None, alias="X-API-Key"), authorization: Optional[HTTPAuthorizationCredentials] = Depends(security), ) -> str: """ Verifiziert den API Key oder JWT Token. Akzeptiert: - X-API-Key Header - Authorization: Bearer Returns: str: User ID oder "api_key" bei API Key Auth """ config = get_config() # 1. Prüfe X-API-Key Header if x_api_key: if x_api_key in config.api_keys: return "api_key" logger.warning(f"Invalid API key attempted") raise HTTPException( status_code=401, detail={"error": "unauthorized", "message": "Invalid API key"}, ) # 2. Prüfe Authorization Header if authorization: token = authorization.credentials # Prüfe ob es ein API Key ist if token in config.api_keys: return "api_key" # Versuche JWT zu dekodieren if config.jwt_secret: try: payload = jwt.decode( token, config.jwt_secret, algorithms=["HS256"], ) user_id = payload.get("user_id") or payload.get("sub") if user_id: return str(user_id) except jwt.ExpiredSignatureError: raise HTTPException( status_code=401, detail={"error": "token_expired", "message": "Token has expired"}, ) except jwt.InvalidTokenError as e: logger.warning(f"Invalid JWT token: {e}") raise HTTPException( status_code=401, detail={"error": "invalid_token", "message": "Invalid token"}, ) # 3. In Development Mode ohne Auth erlauben if config.debug: logger.warning("Auth bypassed in debug mode") return "debug_user" # 4. Keine gültige Auth gefunden raise HTTPException( status_code=401, detail={ "error": "unauthorized", "message": "API key or valid token required", }, ) def get_current_user_id(user_id: str = Depends(verify_api_key)) -> str: """Dependency um die aktuelle User ID zu bekommen.""" return user_id