diff --git a/api.py b/api.py index d1d477e..fe73373 100644 --- a/api.py +++ b/api.py @@ -343,15 +343,7 @@ def generate_filtered_openapi_schema( base_schema["components"]["securitySchemes"] = auth_schemes - security_requirements = [] - if "HTTPBearer" in auth_schemes and "ApiKeyAuth" in auth_schemes: - security_requirements = [{"HTTPBearer": []}, {"ApiKeyAuth": []}] - elif "HTTPBearer" in auth_schemes: - security_requirements = [{"HTTPBearer": []}] - elif "ApiKeyAuth" in auth_schemes: - security_requirements = [{"ApiKeyAuth": []}] - - base_schema["security"] = security_requirements + base_schema["security"] = [] if not allowed_tags: logger.info("⚙️ Schéma OpenAPI complet (admin)") @@ -377,7 +369,13 @@ def generate_filtered_openapi_schema( operation_tags = operation.get("tags", []) if any(tag in allowed_tags for tag in operation_tags): - operation["security"] = security_requirements + operation_security = [] + if "HTTPBearer" in auth_schemes: + operation_security.append({"HTTPBearer": []}) + if "ApiKeyAuth" in auth_schemes: + operation_security.append({"ApiKeyAuth": []}) + + operation["security"] = operation_security filtered_operations[method] = operation if filtered_operations: @@ -398,7 +396,6 @@ def generate_filtered_openapi_schema( referenced_schemas = set() def extract_schema_refs(obj): - """Extrait récursivement tous les $ref depuis un objet""" if isinstance(obj, dict): for key, value in obj.items(): if key == "$ref" and isinstance(value, str): @@ -430,12 +427,12 @@ def generate_filtered_openapi_schema( base_schema["components"]["schemas"] = filtered_schemas logger.info( - f" Schéma filtré: {len(filtered_paths)} paths, " + f"🔍 Schéma filtré: {len(filtered_paths)} paths, " f"{len(filtered_schemas)} schémas, tags: {allowed_tags}" ) else: logger.info( - f" Schéma filtré: {len(filtered_paths)} paths, tags: {allowed_tags}" + f"🔍 Schéma filtré: {len(filtered_paths)} paths, tags: {allowed_tags}" ) return base_schema diff --git a/middleware/security.py b/middleware/security.py index a9afb21..efd25fa 100644 --- a/middleware/security.py +++ b/middleware/security.py @@ -159,13 +159,12 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware): api_key_header = request.headers.get("X-API-Key") if api_key_header: - logger.debug(f" API Key détectée pour {method} {path}") - return await self._handle_api_key_auth( - request, api_key_header, path, method, call_next - ) + api_key_header = api_key_header.strip() + if not api_key_header or api_key_header == "": + api_key_header = None if auth_header and auth_header.startswith("Bearer "): - token = auth_header.split(" ")[1] + token = auth_header.split(" ")[1].strip() if token.startswith("sdk_live_"): logger.warning( @@ -179,7 +178,13 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware): request.state.authenticated_via = "jwt" return await call_next(request) - logger.debug(f"❓ Aucune auth pour {method} {path} → délégation à FastAPI") + if api_key_header: + logger.debug(f"🔑 API Key détectée pour {method} {path}") + return await self._handle_api_key_auth( + request, api_key_header, path, method, call_next + ) + + logger.debug(f"❌ Aucune auth pour {method} {path} → délégation à FastAPI") return await call_next(request) async def _handle_api_key_auth( @@ -200,7 +205,7 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware): api_key_obj = await service.verify_api_key(api_key) if not api_key_obj: - logger.warning(f" Clé API invalide: {method} {path}") + logger.warning(f"🔒 Clé API invalide: {method} {path}") return JSONResponse( status_code=status.HTTP_401_UNAUTHORIZED, content={ @@ -250,7 +255,7 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware): request.state.api_key = api_key_obj request.state.authenticated_via = "api_key" - logger.info(f" ACCÈS AUTORISÉ: {api_key_obj.name} → {method} {path}") + logger.info(f"✅ ACCÈS AUTORISÉ: {api_key_obj.name} → {method} {path}") return await call_next(request)