Harden production launch defaults

This commit is contained in:
StasonJatham committed 2026-05-20 18:33:48 +02:00
1 parent 8b80e0e3d2
commit 2203852170
8 files changed
+176 -30

No files matched your search

+69
View File
@@ -212,6 +212,23 @@ def test_admin_routes_are_rate_limited(tmp_path: Path) -> None:
assert second.status_code == 429
def test_bearer_link_routes_share_rate_limit_bucket(tmp_path: Path) -> None:
app = make_app(
DdnsSettings(
database_path=tmp_path / "ddns.sqlite3",
admin_password="admin",
rate_limit_per_minute=1,
)
)
client = TestClient(app)
first = client.get("/m/not-a-real-token")
second = client.get("/m/another-token")
assert first.status_code == 404
assert second.status_code == 429
def test_admin_can_rotate_links_and_password(tmp_path: Path) -> None:
settings = DdnsSettings(
database_path=tmp_path / "ddns.sqlite3",
@@ -385,10 +402,13 @@ def test_api_docs_include_versioned_ddns_api(tmp_path: Path) -> None:
app = make_app(DdnsSettings(database_path=tmp_path / "ddns.sqlite3", admin_password="admin"))
client = TestClient(app)
docs = client.get("/docs")
redoc = client.get("/redoc")
schema = client.get("/openapi.json").json()
assert docs.status_code == 200
assert redoc.status_code == 200
assert "unsafe-inline" in docs.headers["content-security-policy"]
assert "/api/v1/hostnames/magic" in schema["paths"]
assert "/api/v1/updates/{update_slug}" in schema["paths"]
assert "/admin" not in schema["paths"]
@@ -398,6 +418,35 @@ def test_api_docs_include_versioned_ddns_api(tmp_path: Path) -> None:
assert all(tag["name"] != "admin" for tag in schema["tags"])
def test_application_pages_use_stricter_script_csp(tmp_path: Path) -> None:
app = make_app(DdnsSettings(database_path=tmp_path / "ddns.sqlite3", admin_password="admin"))
client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
assert '<script src="/app.js" defer></script>' in response.text
assert "script-src 'self'" in response.headers["content-security-policy"]
assert "script-src 'self' 'unsafe-inline'" not in response.headers["content-security-policy"]
assert client.get("/app.js").status_code == 200
def test_trusted_host_middleware_rejects_unlisted_host(tmp_path: Path) -> None:
app = make_app(
DdnsSettings(
database_path=tmp_path / "ddns.sqlite3",
admin_password="admin",
public_base_url="http://ddns.example.net",
trusted_hosts={"ddns.example.net"},
)
)
client = TestClient(app)
response = client.get("/", headers={"host": "evil.example.net"})
assert response.status_code == 400
def test_api_magic_hostname_lifecycle(tmp_path: Path) -> None:
app = make_app(
DdnsSettings(
@@ -639,6 +688,26 @@ def test_require_dns_provider_fails_startup_without_backend(tmp_path: Path) -> N
raise AssertionError("expected startup failure")
def test_launch_mode_requires_strong_admin_password(tmp_path: Path) -> None:
try:
make_app(
DdnsSettings(
database_path=tmp_path / "ddns.sqlite3",
admin_password="admin",
public_base_url="http://ddns.example.net",
hostname_suffix="ddns.example.net",
dns_provider="cloudflare",
cloudflare_api_token="token",
cloudflare_zone_id="zone",
require_dns_provider=True,
)
)
except RuntimeError as exc:
assert "DDNS_ADMIN_PASSWORD" in str(exc)
else:
raise AssertionError("expected startup failure")
def test_background_cleanup_removes_abandoned_setup_flows(tmp_path: Path) -> None:
database_path = tmp_path / "ddns.sqlite3"
app = make_app(