Require karl prefixed bearer secrets

This commit is contained in:
StasonJatham committed 2026-05-21 18:36:06 +02:00
1 parent 8f07bbde84
commit d2cad52ae9
6 files changed
+33 -29

No files matched your search

+5 -5
View File
@@ -30,10 +30,10 @@ def test_custom_api_docs_include_only_current_api_surfaces(tmp_path: Path) -> No
assert redoc.status_code == 404
assert "Small API surface." in docs.text
assert "POST /api/v1/hostnames" in docs.text
assert "GET or POST /api/v1/router/register/<secret>" in docs.text
assert "GET or POST /api/v1/router/update/<secret>" in docs.text
assert "GET /api/v1/hostnames/<secret>" in docs.text
assert "POST /api/v1/hostnames/<secret>/rotate-update-url" in docs.text
assert "GET or POST /api/v1/router/register/<karl_secret>" in docs.text
assert "GET or POST /api/v1/router/update/<karl_secret>" in docs.text
assert "GET /api/v1/hostnames/<karl_secret>" in docs.text
assert "POST /api/v1/hostnames/<karl_secret>/rotate-update-url" in docs.text
assert "Rotate update URL" in docs.text
assert "Operator API" not in docs.text
assert "/api/v1/admin" not in docs.text
@@ -242,7 +242,7 @@ def test_hostname_api_history_is_scoped_to_dashboard_secret(tmp_path: Path) -> N
assert "source_ip" not in payload["history"][0]
assert "other.ddns.example.net" not in response.text
assert client.get(f"/api/v1/hostnames/{other['management_slug']}", params={"history_limit": 101}).status_code == 422
assert client.get(f"/api/v1/hostnames/{'a' * 32}").status_code == 404
assert client.get(f"/api/v1/hostnames/karl_{'a' * 32}").status_code == 404
def test_registration_publishes_initial_dns_when_provider_is_configured(tmp_path: Path, monkeypatch) -> None:
+7 -7
View File
@@ -104,9 +104,9 @@ printf 'updater placeholder\\n'
EOS
;;
*'/api/v1/hostnames'*)
printf '%s\\n' '{{"hostname":"abc.karldns.test","status":"pending","update_url":"https://karldns.test/api/v1/router/update/update-secret?myip=<ipaddr>&myipv6=<ip6addr>","dashboard_url":"https://karldns.test/m/manage-secret","registration_url":"https://karldns.test/api/v1/router/register/manage-secret"}}'
printf '%s\\n' '{{"hostname":"abc.karldns.test","status":"pending","update_url":"https://karldns.test/api/v1/router/update/karl_update_secret_12345678901234567890?myip=<ipaddr>&myipv6=<ip6addr>","dashboard_url":"https://karldns.test/m/karl_manage_secret_12345678901234567890","registration_url":"https://karldns.test/api/v1/router/register/karl_manage_secret_12345678901234567890"}}'
;;
*'/api/v1/router/register/manage-secret'*)
*'/api/v1/router/register/karl_manage_secret_12345678901234567890'*)
printf '%s\\n' 'good registered'
;;
*)
@@ -136,11 +136,11 @@ esac
log = log_file.read_text(encoding="utf-8")
assert "/api/v1/hostnames" in log
assert "/api/v1/router/register/manage-secret" in log
assert "/api/v1/router/register/karl_manage_secret_12345678901234567890" in log
assert "KarlDNS: registering hostname" in result.stdout
config = home_dir / ".config" / "karldns" / "updater.env"
config_text = config.read_text(encoding="utf-8")
assert "KARLDNS_UPDATE_URL='https://karldns.test/api/v1/router/update/update-secret'" in config_text
assert "KARLDNS_UPDATE_URL='https://karldns.test/api/v1/router/update/karl_update_secret_12345678901234567890'" in config_text
assert "KARLDNS_HOSTNAME='abc.karldns.test'" in config_text
@@ -172,9 +172,9 @@ printf 'updater placeholder\\n'
EOS
;;
*'/api/v1/hostnames'*)
printf '%s\\n' '{{"hostname":"abc.karldns.test","status":"pending","update_url":"https://karldns.test/api/v1/router/update/update-secret?myip=<ipaddr>&myipv6=<ip6addr>","dashboard_url":"https://karldns.test/m/manage-secret","registration_url":"https://karldns.test/api/v1/router/register/manage-secret"}}'
printf '%s\\n' '{{"hostname":"abc.karldns.test","status":"pending","update_url":"https://karldns.test/api/v1/router/update/karl_update_secret_12345678901234567890?myip=<ipaddr>&myipv6=<ip6addr>","dashboard_url":"https://karldns.test/m/karl_manage_secret_12345678901234567890","registration_url":"https://karldns.test/api/v1/router/register/karl_manage_secret_12345678901234567890"}}'
;;
*'/api/v1/router/register/manage-secret'*)
*'/api/v1/router/register/karl_manage_secret_12345678901234567890'*)
printf '%s\\n' 'good registered'
;;
*)
@@ -220,7 +220,7 @@ cp "$1" {crontab_file}
assert "KARLDNS_CONFIG=" in cron_text
assert "karldns-update" in cron_text
assert log.count("/api/v1/hostnames") == 1
assert log.count("/api/v1/router/register/manage-secret") == 1
assert log.count("/api/v1/router/register/karl_manage_secret_12345678901234567890") == 1
assert (home_dir / ".local" / "bin" / "karldns-update").exists()
run_script("sh", str(ROOT / "scripts" / "uninstall-linux.sh"), "--mode", "user", env=env)
+7 -3
View File
@@ -21,7 +21,7 @@ def test_generated_hostname_is_not_an_update_secret(tmp_path: Path) -> None:
client = TestClient(app)
response = client.get(
f"/api/v1/router/update/{'a' * 43}",
f"/api/v1/router/update/karl_{'a' * 43}",
params={"hostname": "public-target.ddns.example.net", "myip": "203.0.113.9"},
)
@@ -56,8 +56,8 @@ def test_bearer_link_routes_share_rate_limit_bucket(tmp_path: Path) -> None:
)
client = TestClient(app)
first = client.get(f"/m/{'a' * 43}")
second = client.get(f"/m/{'b' * 43}")
first = client.get(f"/m/karl_{'a' * 43}")
second = client.get(f"/m/karl_{'b' * 43}")
assert first.status_code == 404
assert second.status_code == 429
@@ -92,6 +92,10 @@ def test_redacted_access_log_masks_bearer_paths_and_query_strings(tmp_path: Path
"/api/v1/router/register/short",
"/api/v1/hostnames/short",
"/m/short",
"/api/v1/router/update/not_karl_but_long_enough_1234567890",
"/api/v1/router/register/not_karl_but_long_enough_1234567890",
"/api/v1/hostnames/not_karl_but_long_enough_1234567890",
"/m/not_karl_but_long_enough_1234567890",
],
)
def test_secret_path_tokens_are_constrained(tmp_path: Path, path: str) -> None: