- Disable OpenAPI docs/redoc/openapi.json when APP_ENV=production - Strip uvicorn Server header with --no-server-header in Dockerfile and docker-compose.yml - Add OriginValidatorMiddleware to reject state-changing requests from disallowed origins - Add global exception handler to prevent stack trace leakage on unhandled errors - Add tests for all new security features (OpenAPI, origin validation, exception handler, server header)
42 lines
1.5 KiB
Python
42 lines
1.5 KiB
Python
"""Unit tests for OpenAPI docs disabled in production."""
|
|
from unittest import mock
|
|
|
|
from starlette.testclient import TestClient
|
|
|
|
|
|
class TestOpenAPIDisabledInProduction:
|
|
"""Verify docs/redoc/openapi are disabled when APP_ENV=production."""
|
|
|
|
def test_docs_disabled_in_production(self) -> None:
|
|
prod_env = {
|
|
"APP_ENV": "production",
|
|
"OIDC_CLIENT_ID": "test-client-id",
|
|
"JWT_SECRET": "test-secret-not-default",
|
|
}
|
|
with mock.patch.dict("os.environ", prod_env):
|
|
# Re-import to pick up the new env
|
|
import importlib
|
|
import api.config
|
|
importlib.reload(api.config)
|
|
import api.app
|
|
importlib.reload(api.app)
|
|
app = api.app.app
|
|
|
|
client = TestClient(app, raise_server_exceptions=False)
|
|
assert client.get("/docs").status_code == 404
|
|
assert client.get("/redoc").status_code == 404
|
|
assert client.get("/openapi.json").status_code == 404
|
|
|
|
def test_docs_enabled_in_dev(self) -> None:
|
|
with mock.patch.dict("os.environ", {"APP_ENV": "dev"}):
|
|
import importlib
|
|
import api.config
|
|
importlib.reload(api.config)
|
|
import api.app
|
|
importlib.reload(api.app)
|
|
app = api.app.app
|
|
|
|
client = TestClient(app, raise_server_exceptions=False)
|
|
# /docs should return 200 (Swagger UI) in non-production
|
|
assert client.get("/docs").status_code == 200
|
|
assert client.get("/openapi.json").status_code == 200
|