From 1336872b15c25d45ebcb7c1cf72369c2bdd53187 Mon Sep 17 00:00:00 2001 From: Eilen Shin <136898293+Eilen6316@users.noreply.github.com> Date: Wed, 6 May 2026 15:27:34 +0800 Subject: [PATCH] fix(channels): authenticate gateway command requests (#2742) --- backend/app/channels/manager.py | 6 ++++- backend/tests/test_channels.py | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/backend/app/channels/manager.py b/backend/app/channels/manager.py index 9215eade5..e59dbcf2c 100644 --- a/backend/app/channels/manager.py +++ b/backend/app/channels/manager.py @@ -997,7 +997,11 @@ class ChannelManager: try: async with httpx.AsyncClient() as http: - resp = await http.get(f"{self._gateway_url}{path}", timeout=10) + resp = await http.get( + f"{self._gateway_url}{path}", + timeout=10, + headers=create_internal_auth_headers(), + ) resp.raise_for_status() data = resp.json() except Exception: diff --git a/backend/tests/test_channels.py b/backend/tests/test_channels.py index cef5bfad6..d68701c4e 100644 --- a/backend/tests/test_channels.py +++ b/backend/tests/test_channels.py @@ -466,6 +466,47 @@ class TestChannelManager: assert headers["Cookie"] == f"csrf_token={csrf_token}" assert headers["X-DeerFlow-Internal-Token"] + def test_fetch_gateway_includes_internal_auth_headers(self, monkeypatch): + from app.channels.manager import ChannelManager + + class MockResponse: + def raise_for_status(self): + return None + + def json(self): + return {"models": [{"name": "default"}]} + + class MockAsyncClient: + def __init__(self, *args, **kwargs): + return None + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + return None + + async def get(self, url, **kwargs): + calls.append({"url": url, **kwargs}) + return MockResponse() + + calls = [] + monkeypatch.setattr("app.channels.manager.httpx.AsyncClient", MockAsyncClient) + + async def go(): + bus = MessageBus() + store = ChannelStore(path=Path(tempfile.mkdtemp()) / "store.json") + manager = ChannelManager(bus=bus, store=store, gateway_url="http://gateway:8001") + + reply = await manager._fetch_gateway("/api/models", "models") + + assert reply == "Available models:\n• default" + assert calls[0]["url"] == "http://gateway:8001/api/models" + assert calls[0]["timeout"] == 10 + assert calls[0]["headers"]["X-DeerFlow-Internal-Token"] + + _run(go()) + def test_handle_chat_calls_channel_receive_file_for_inbound_files(self, monkeypatch): from app.channels.manager import ChannelManager