diff --git a/gateway/platforms/feishu.py b/gateway/platforms/feishu.py index 832698722d8..b90dfcf86c7 100644 --- a/gateway/platforms/feishu.py +++ b/gateway/platforms/feishu.py @@ -1514,8 +1514,10 @@ class FeishuAdapter(BasePlatformAdapter): connection_mode=str( extra.get("connection_mode") or os.getenv("FEISHU_CONNECTION_MODE", "websocket") ).strip().lower(), - encrypt_key=os.getenv("FEISHU_ENCRYPT_KEY", "").strip(), - verification_token=os.getenv("FEISHU_VERIFICATION_TOKEN", "").strip(), + encrypt_key=str(extra.get("encrypt_key") or os.getenv("FEISHU_ENCRYPT_KEY", "")).strip(), + verification_token=str( + extra.get("verification_token") or os.getenv("FEISHU_VERIFICATION_TOKEN", "") + ).strip(), group_policy=os.getenv("FEISHU_GROUP_POLICY", "allowlist").strip().lower(), allowed_group_users=frozenset( item.strip() @@ -1642,6 +1644,11 @@ class FeishuAdapter(BasePlatformAdapter): self._connection_mode, ) return False + if self._connection_mode == "webhook" and not (self._verification_token or self._encrypt_key): + logger.error( + "[Feishu] Webhook mode requires FEISHU_VERIFICATION_TOKEN or FEISHU_ENCRYPT_KEY." + ) + return False try: self._app_lock_identity = self._app_id diff --git a/tests/gateway/test_feishu.py b/tests/gateway/test_feishu.py index 63287d88cb4..ff6fcf56e3d 100644 --- a/tests/gateway/test_feishu.py +++ b/tests/gateway/test_feishu.py @@ -3191,6 +3191,39 @@ class TestWebhookSecurity(unittest.TestCase): response = asyncio.run(adapter._handle_webhook_request(request)) self.assertEqual(response.status, 401) + @patch.dict(os.environ, {}, clear=True) + def test_webhook_connect_requires_inbound_auth_secret(self): + from gateway.config import PlatformConfig + from gateway.platforms.feishu import FeishuAdapter + + adapter = FeishuAdapter( + PlatformConfig( + enabled=True, + extra={"app_id": "cli_app", "app_secret": "secret_app", "connection_mode": "webhook"}, + ) + ) + self.assertFalse(asyncio.run(adapter.connect())) + + @patch.dict(os.environ, {}, clear=True) + def test_webhook_loads_auth_secrets_from_platform_extra(self): + from gateway.config import PlatformConfig + from gateway.platforms.feishu import FeishuAdapter + + adapter = FeishuAdapter( + PlatformConfig( + enabled=True, + extra={ + "app_id": "cli_app", + "app_secret": "secret_app", + "connection_mode": "webhook", + "verification_token": "token_from_extra", + "encrypt_key": "encrypt_from_extra", + }, + ) + ) + self.assertEqual(adapter._verification_token, "token_from_extra") + self.assertEqual(adapter._encrypt_key, "encrypt_from_extra") + @patch.dict(os.environ, {}, clear=True) def test_webhook_url_verification_challenge_passes_without_signature(self): """Challenge requests must succeed even when no encrypt_key is set."""