diff --git a/idunn/utils/ban_check.py b/idunn/utils/ban_check.py index 799971b0a..7c506fb8c 100644 --- a/idunn/utils/ban_check.py +++ b/idunn/utils/ban_check.py @@ -6,13 +6,17 @@ logger = logging.getLogger(__name__) -if settings["BANCHECK_ENABLED"]: - ban_check_http = AsyncClient( - base_url=settings["QWANT_API_BASE_URL"], - timeout=float(settings["BANCHECK_TIMEOUT"]), - ) -else: - ban_check_http = None + +def get_ban_check_http(): + if settings["BANCHECK_ENABLED"]: + return AsyncClient( + base_url=settings["QWANT_API_BASE_URL"], + timeout=float(settings["BANCHECK_TIMEOUT"]), + ) + return None + + +ban_check_http = get_ban_check_http() async def check_banned_client(x_client_hash: Optional[str] = Header(None)): @@ -20,6 +24,7 @@ async def check_banned_client(x_client_hash: Optional[str] = Header(None)): return if not x_client_hash: return + try: response = await ban_check_http.get( "/v3/captcha/isban", params={"client_hash": x_client_hash} @@ -28,10 +33,11 @@ async def check_banned_client(x_client_hash: Optional[str] = Header(None)): response_data = response.json() response_status = response_data.get("status") if response_status != "success": - raise Exception(f"Got invalid status {repr(response_status)} from ban check") - is_client_banned = bool(response_data.get("data")) - if is_client_banned: - raise HTTPException(status_code=429) + raise ValueError(f"Got invalid status {repr(response_status)} from ban check") except Exception as err: logger.error("Failed to check client is not banned", exc_info=True) raise HTTPException(status_code=503) from err + + is_client_banned = bool(response_data.get("data")) + if is_client_banned: + raise HTTPException(status_code=429) diff --git a/tests/test_instant_answer/test_ia_bancheck.py b/tests/test_instant_answer/test_ia_bancheck.py new file mode 100644 index 000000000..2b1589d70 --- /dev/null +++ b/tests/test_instant_answer/test_ia_bancheck.py @@ -0,0 +1,31 @@ +import pytest +from unittest.mock import patch +from fastapi.testclient import TestClient + +from app import app +from idunn.utils.ban_check import get_ban_check_http +from tests.utils import override_settings + + +@pytest.fixture +def enable_bancheck(httpx_mock): + with override_settings( + { + "BANCHECK_ENABLED": True, + "QWANT_API_BASE_URL": "http://qwant-api.test", + } + ), patch("idunn.utils.ban_check.ban_check_http", new_callable=get_ban_check_http): + httpx_mock.get(url__regex=r"http://qwant-api.test/v3/captcha/isban.*").respond( + json={"status": "success", "data": True} + ) + yield + + +def test_ia_client_banned(enable_bancheck): + client = TestClient(app) + response = client.get( + "/v1/instant_answer", + params={"q": "paris", "lang": "fr"}, + headers={"x-client-hash": "banned"}, + ) + assert response.status_code == 429