Simplify DDNS flow and polish UI

This commit is contained in:
StasonJatham committed 2026-05-21 14:18:39 +02:00
1 parent 5beee0e5c6
commit 5a90bd9d87
42 files changed
+587 -1418

No files matched your search

+36 -47
View File
@@ -10,23 +10,20 @@ from router_dyndns.ddns import DdnsSettings, DdnsStore, DnsProviderError, DnsRec
def test_update_accepts_fritzbox_placeholders(tmp_path: Path) -> None:
app = make_app(
DdnsSettings(
database_path=tmp_path / "ddns.sqlite3",
shared_secret="secret",
admin_password="admin",
allowed_hosts={"home.example.net"},
)
)
database_path = tmp_path / "ddns.sqlite3"
store = DdnsStore(database_path)
account = store.create_account("home.ddns.example.net", "router")
app = make_app(DdnsSettings(database_path=database_path, admin_password="admin", hostname_suffix="ddns.example.net"))
client = TestClient(app)
response = client.get(
"/nic/update",
params={
"hostname": "home.example.net",
"hostname": "home.ddns.example.net",
"myip": "203.0.113.8",
"myipv6": "2001:db8::8",
"password": "secret",
"username": account["username"],
"password": account["password"],
},
)
@@ -34,36 +31,36 @@ def test_update_accepts_fritzbox_placeholders(tmp_path: Path) -> None:
assert response.text == "good 203.0.113.8"
records = client.get("/records", auth=("admin", "admin")).json()
assert records["total"] == 1
assert records["items"][0]["hostname"] == "home.example.net"
assert records["items"][0]["hostname"] == "home.ddns.example.net"
assert records["items"][0]["ipv4"] == "203.0.113.8"
assert records["items"][0]["ipv6"] == "2001:db8::8"
def test_update_rejects_wrong_secret(tmp_path: Path) -> None:
app = make_app(DdnsSettings(database_path=tmp_path / "ddns.sqlite3", shared_secret="secret"))
def test_update_rejects_wrong_password(tmp_path: Path) -> None:
database_path = tmp_path / "ddns.sqlite3"
store = DdnsStore(database_path)
account = store.create_account("home.ddns.example.net", "router")
app = make_app(DdnsSettings(database_path=database_path, admin_password="admin", hostname_suffix="ddns.example.net"))
client = TestClient(app)
response = client.get(
"/nic/update",
params={"hostname": "home.example.net", "myip": "203.0.113.8", "password": "wrong"},
params={"hostname": account["hostname"], "myip": "203.0.113.8", "username": account["username"], "password": "wrong"},
)
assert response.status_code == 401
def test_update_rejects_unlisted_host(tmp_path: Path) -> None:
app = make_app(
DdnsSettings(
database_path=tmp_path / "ddns.sqlite3",
shared_secret="secret",
allowed_hosts={"home.example.net"},
)
)
def test_update_rejects_hostname_outside_provider_suffix(tmp_path: Path) -> None:
database_path = tmp_path / "ddns.sqlite3"
store = DdnsStore(database_path)
account = store.create_account("home.example.net", "router")
app = make_app(DdnsSettings(database_path=database_path, admin_password="admin", hostname_suffix="ddns.example.net"))
client = TestClient(app)
response = client.get(
"/nic/update",
params={"hostname": "other.example.net", "myip": "203.0.113.8", "password": "secret"},
params={"hostname": account["hostname"], "myip": "203.0.113.8", "username": account["username"], "password": account["password"]},
)
assert response.status_code == 403
@@ -229,24 +226,17 @@ def test_unchanged_slug_update_is_read_only_for_history_and_record(tmp_path: Pat
assert published == []
def test_shared_secret_still_updates_explicitly_allowed_hostname(tmp_path: Path) -> None:
app = make_app(
DdnsSettings(
database_path=tmp_path / "ddns.sqlite3",
shared_secret="secret",
admin_password="admin",
allowed_hosts={"home.example.net"},
)
)
def test_slug_update_rejects_hostname_outside_provider_suffix(tmp_path: Path) -> None:
database_path = tmp_path / "ddns.sqlite3"
store = DdnsStore(database_path)
account = store.create_account("home.example.net", "router")
app = make_app(DdnsSettings(database_path=database_path, admin_password="admin", hostname_suffix="ddns.example.net"))
client = TestClient(app)
response = client.get(
"/nic/update",
params={"hostname": "home.example.net", "myip": "203.0.113.9", "password": "secret"},
)
response = client.get(f"/u/{account['update_slug']}", params={"myip": "203.0.113.9"})
assert response.status_code == 200
assert response.text == "good 203.0.113.9"
assert response.status_code == 404
assert store.list_records() == []
def test_omitted_ip_family_is_preserved(tmp_path: Path, monkeypatch) -> None:
@@ -326,19 +316,18 @@ def test_wrong_family_legacy_ip_is_badip_and_preserves_records(tmp_path: Path) -
def test_nic_update_invalid_ip_returns_badip(tmp_path: Path) -> None:
database_path = tmp_path / "ddns.sqlite3"
store = DdnsStore(database_path)
app = make_app(
DdnsSettings(
database_path=database_path,
shared_secret="secret",
admin_password="admin",
allowed_hosts={"home.example.net"},
)
)
account = store.create_account("home.ddns.example.net", "router")
app = make_app(DdnsSettings(database_path=database_path, admin_password="admin", hostname_suffix="ddns.example.net"))
client = TestClient(app)
response = client.get(
"/nic/update",
params={"hostname": "home.example.net", "myipv6": "203.0.113.9", "password": "secret"},
params={
"hostname": account["hostname"],
"myipv6": "203.0.113.9",
"username": account["username"],
"password": account["password"],
},
)
assert response.status_code == 400