diff --git a/main.py b/main.py index 627c74a..17b30cf 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ import logging import os +from urllib.parse import urlsplit from fastapi import FastAPI, HTTPException, Query import requests import humanize @@ -54,7 +55,12 @@ def get_greader_token(): logging.warning("FreshRSS login request failed: %s", exc) raise HTTPException(status_code=502, detail="FreshRSS login request failed") from exc if res.status_code != 200: - logging.warning("FreshRSS login failed (status %d): %s", res.status_code, res.text) + upstream_host = urlsplit(FRESHRSS_HOST).hostname or "unknown" + logging.warning( + "FreshRSS login failed (status=%d, upstream_host=%s)", + res.status_code, + upstream_host, + ) raise HTTPException(status_code=502, detail=f"FreshRSS login failed with status {res.status_code}") # Find and extract 'Auth=' line for line in res.text.splitlines(): diff --git a/tests/test_main.py b/tests/test_main.py index 8e624e9..21a46db 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -84,15 +84,30 @@ def fake_post(url, data, timeout): ] -def test_get_greader_token_rejects_failed_login(monkeypatch): - main = import_app(monkeypatch) - monkeypatch.setattr(main.requests, "post", lambda *args, **kwargs: FakeResponse(status_code=403, text="nope")) - - with pytest.raises(HTTPException) as excinfo: - main.get_greader_token() +def test_get_greader_token_rejects_failed_login_without_logging_secrets(monkeypatch, caplog): + credentials = { + "FRESHRSS_HOST": "https://freshrss.example.test", + "FRESHRSS_USER": "sentinel-username", + "FRESHRSS_PASS": "sentinel-password", + } + main = import_app(monkeypatch, credentials) + response_body = "sentinel-response-body\nAuth=sentinel-token" + monkeypatch.setattr( + main.requests, + "post", + lambda *args, **kwargs: FakeResponse(status_code=403, text=response_body), + ) + + with caplog.at_level("WARNING"): + with pytest.raises(HTTPException) as excinfo: + main.get_greader_token() assert excinfo.value.status_code == 502 assert "FreshRSS login failed with status 403" == excinfo.value.detail + assert "status=403" in caplog.text + assert "upstream_host=freshrss.example.test" in caplog.text + for secret in (*credentials.values(), response_body, "sentinel-token"): + assert secret not in caplog.text def test_get_greader_token_rejects_missing_auth_line(monkeypatch):