From 55d3c6b14a633b16d6f4d4e2e142683e1687d904 Mon Sep 17 00:00:00 2001 From: Som Date: Wed, 6 May 2026 01:37:59 +0530 Subject: [PATCH] fix: use distinct scheme_name on APIKeyHeader so Swagger shows correct curl headers - Add scheme_name="AdminApiKey" to API_KEY_HEADER (X-Admin-API-Key) - Add scheme_name="UserApiKey" to USER_API_KEY_HEADER (X-API-Key) - FastAPI collapses both into one scheme when scheme_name is missing, causing Swagger to show X-API-Key for all routes including admin ones - Add regression test (test_openapi_schema.py) that validates both schemes exist in /openapi.json with correct header names Closes #80 --- services/admin-api/app/main.py | 4 +-- .../admin-api/tests/test_openapi_schema.py | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 services/admin-api/tests/test_openapi_schema.py diff --git a/services/admin-api/app/main.py b/services/admin-api/app/main.py index 844b63b7..952b9aa3 100644 --- a/services/admin-api/app/main.py +++ b/services/admin-api/app/main.py @@ -63,8 +63,8 @@ class PaginatedMeetingUserStatResponse(BaseModel): items: List[MeetingUserStat] # Security - Reuse logic from meeting-api/auth.py for admin token verification -API_KEY_HEADER = APIKeyHeader(name="X-Admin-API-Key", auto_error=False) # Use a distinct header -USER_API_KEY_HEADER = APIKeyHeader(name="X-API-Key", auto_error=False) # For user-facing endpoints +API_KEY_HEADER = APIKeyHeader(name="X-Admin-API-Key", scheme_name="AdminApiKey", auto_error=False) +USER_API_KEY_HEADER = APIKeyHeader(name="X-API-Key", scheme_name="UserApiKey", auto_error=False) ADMIN_API_TOKEN = os.getenv("ADMIN_API_TOKEN") # Read from environment ANALYTICS_API_TOKEN = os.getenv("ANALYTICS_API_TOKEN") # Read-only analytics token diff --git a/services/admin-api/tests/test_openapi_schema.py b/services/admin-api/tests/test_openapi_schema.py new file mode 100644 index 00000000..aae5f5ce --- /dev/null +++ b/services/admin-api/tests/test_openapi_schema.py @@ -0,0 +1,33 @@ +"""Regression test for issue #80 — OpenAPI security scheme names must be distinct. + +FastAPI collapses APIKeyHeader instances that share the same scheme_name into one +OpenAPI security scheme. Without explicit scheme_name values, Swagger UI shows the +wrong header (X-API-Key) in curl examples for admin endpoints. +""" + +import os + +os.environ.setdefault("ADMIN_API_TOKEN", "test-admin-token") +os.environ.setdefault("DB_HOST", "localhost") +os.environ.setdefault("DB_PORT", "5432") +os.environ.setdefault("DB_NAME", "test") +os.environ.setdefault("DB_USER", "test") +os.environ.setdefault("DB_PASSWORD", "test") + +import pytest +from httpx import AsyncClient, ASGITransport +from app.main import app + + +@pytest.mark.asyncio +async def test_openapi_security_schemes_are_distinct(): + """AdminApiKey and UserApiKey must be separate schemes so Swagger shows the right header.""" + transport = ASGITransport(app=app) + async with AsyncClient(transport=transport, base_url="http://test") as client: + resp = await client.get("/openapi.json") + assert resp.status_code == 200 + schemes = resp.json()["components"]["securitySchemes"] + assert "AdminApiKey" in schemes, "AdminApiKey scheme missing — admin curl examples will show wrong header" + assert "UserApiKey" in schemes, "UserApiKey scheme missing — user curl examples will show wrong header" + assert schemes["AdminApiKey"]["name"] == "X-Admin-API-Key" + assert schemes["UserApiKey"]["name"] == "X-API-Key"