From 0e887837d14ff742d876bada2584251d78a213fe Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Fri, 15 May 2026 21:03:03 -0700 Subject: [PATCH] fix(blocklist): validate _v6_auth session JSON, add auth-failure test --- app/services/pihole.py | 7 ++++++- tests/test_service_pihole.py | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/services/pihole.py b/app/services/pihole.py index 0648072..f952d46 100644 --- a/app/services/pihole.py +++ b/app/services/pihole.py @@ -64,7 +64,12 @@ class PiholeClient: with httpx.Client(timeout=10) as c: r = c.post(f"{self.url}/api/auth", json={"password": self.api_key}) r.raise_for_status() - return r.json()["session"]["sid"] + data = r.json() + sid = data.get("session", {}).get("sid") + if not sid: + msg = data.get("session", {}).get("message", "no sid returned") + raise ValueError(f"Pi-hole v6 auth failed: {msg}") + return sid def _v6_post_domain(self, sid: str, domain: str, comment: str) -> None: body = [{"domain": domain, "comment": comment, "enabled": True}] diff --git a/tests/test_service_pihole.py b/tests/test_service_pihole.py index ba4dd47..66d8071 100644 --- a/tests/test_service_pihole.py +++ b/tests/test_service_pihole.py @@ -78,3 +78,13 @@ class TestV6Client: client.block("samsungads.com") _, _, comment = mock_post.call_args.args assert comment == "Turnstone block" + + def test_auth_raises_on_invalid_session(self): + client = self._client() + invalid_resp = {"session": {"valid": False, "message": "wrong password"}} + with patch("httpx.Client") as mock_cls: + mock_c = mock_cls.return_value.__enter__.return_value + mock_c.post.return_value.raise_for_status.return_value = None + mock_c.post.return_value.json.return_value = invalid_resp + with pytest.raises(ValueError, match="Pi-hole v6 auth failed"): + client._v6_auth()