feat(auth): add auth.expose_docs flag to view API docs without a token
The /docs, /redoc and /openapi.json routes are gated by AuthRequired, so a browser can't open them on plain navigation (no way to attach a Bearer token). Add an opt-in auth.expose_docs flag (default off) that relaxes ONLY those three routes to anonymous access (loopback + LAN) via a new verify_docs_access dependency. Every real endpoint stays protected, and a startup WARNING fires when the flag is on. - config: AuthConfig.expose_docs: bool = False - auth: verify_docs_access / DocsAccess dependency - main: docs routes use DocsAccess; startup warning - default_config.yaml: documented flag - tests: docs anonymous when exposed; real endpoints still 401
This commit is contained in:
@@ -87,6 +87,35 @@ class TestOpenAPIEndpoint:
|
||||
assert resp.status_code == 401
|
||||
|
||||
|
||||
class TestExposeDocsFlag:
|
||||
"""auth.expose_docs relaxes the docs routes to anonymous access."""
|
||||
|
||||
@pytest.fixture
|
||||
def expose_docs(self, monkeypatch):
|
||||
"""Turn auth.expose_docs ON for the duration of a test."""
|
||||
monkeypatch.setattr(get_config().auth, "expose_docs", True)
|
||||
|
||||
def test_openapi_anonymous_when_exposed(self, client, expose_docs):
|
||||
resp = client.get("/openapi.json")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["info"]["version"] == __version__
|
||||
|
||||
def test_swagger_anonymous_when_exposed(self, client, expose_docs):
|
||||
resp = client.get("/docs")
|
||||
assert resp.status_code == 200
|
||||
assert "text/html" in resp.headers["content-type"]
|
||||
|
||||
def test_redoc_anonymous_when_exposed(self, client, expose_docs):
|
||||
resp = client.get("/redoc")
|
||||
assert resp.status_code == 200
|
||||
assert "text/html" in resp.headers["content-type"]
|
||||
|
||||
def test_real_endpoints_still_protected_when_exposed(self, client, expose_docs):
|
||||
"""Exposing docs must NOT open up actual API endpoints."""
|
||||
resp = client.get("/api/v1/system/api-keys")
|
||||
assert resp.status_code == 401
|
||||
|
||||
|
||||
class TestRootEndpoint:
|
||||
def test_root_returns_html(self, client):
|
||||
resp = client.get("/")
|
||||
|
||||
Reference in New Issue
Block a user