mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-17 13:05:58 +00:00
0966131b31
* fix(channels): require bound identity for user-owned IM messages * make format * docs: document bound identity channel config * refactor: reuse channel connection config * refactor _requires_bound_identity() * refactor from_app_config() * make format * fix: reject unbound channel chats before semaphore * security enhancement * make format * fix: enforce bound-identity admission at command entry point The bound-identity gate only ran for non-command messages in _handle_message() and as a fallback inside _handle_chat(). Commands had no equivalent boundary, so an unbound platform user could send /new and reach _create_thread() directly, creating an unowned Gateway thread and empty checkpoint. Info commands (/status, /models, /memory) likewise leaked Gateway state to unbound users. Add the same _requires_bound_identity() check at the top of _handle_command(), rejecting via _reject_unbound_channel_message() before any thread creation or Gateway query. The gate is a no-op in legacy open-bot mode (require_bound_identity=False) and auth-disabled mode. Provider-level binding flows (/connect, /start) are consumed by the provider adapter before reaching the manager, so they are unaffected. Tests: - unbound auth-enabled /new is rejected before threads.create - bound auth-enabled /new still creates the thread Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(channels): carry workspace fallback decision on inbound messages * fix(channels): recheck bound identity by normalized workspace * fix(channels): avoid duplicate bound identity checks * fix(channels): preserve verified routing for bound identity rejects * fix(channels): clarify bound identity upgrade failures --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
65 lines
2.9 KiB
Python
65 lines
2.9 KiB
Python
"""Tests for user-facing IM channel connection configuration."""
|
|
|
|
from deerflow.config.channel_connections_config import ChannelConnectionsConfig
|
|
|
|
|
|
def test_channel_connections_disabled_by_default():
|
|
config = ChannelConnectionsConfig()
|
|
|
|
assert config.enabled is False
|
|
assert config.require_bound_identity is True
|
|
assert config.slack.enabled is False
|
|
assert config.telegram.enabled is False
|
|
assert config.discord.enabled is False
|
|
assert config.feishu.enabled is False
|
|
assert config.dingtalk.enabled is False
|
|
assert config.wechat.enabled is False
|
|
assert config.wecom.enabled is False
|
|
|
|
|
|
def test_enabled_channel_connections_do_not_require_public_url_or_encryption_key():
|
|
config = ChannelConnectionsConfig.model_validate(
|
|
{
|
|
"enabled": True,
|
|
"telegram": {
|
|
"enabled": True,
|
|
"bot_username": "deerflow_bot",
|
|
},
|
|
"slack": {"enabled": True},
|
|
"discord": {"enabled": True},
|
|
"feishu": {"enabled": True},
|
|
"dingtalk": {"enabled": True},
|
|
"wechat": {"enabled": True},
|
|
"wecom": {"enabled": True},
|
|
}
|
|
)
|
|
|
|
assert config.enabled is True
|
|
assert config.provider_status("telegram") == {"enabled": True, "configured": True}
|
|
assert config.provider_status("slack") == {"enabled": True, "configured": True}
|
|
assert config.provider_status("discord") == {"enabled": True, "configured": True}
|
|
assert config.provider_status("feishu") == {"enabled": True, "configured": True}
|
|
assert config.provider_status("dingtalk") == {"enabled": True, "configured": True}
|
|
assert config.provider_status("wechat") == {"enabled": True, "configured": True}
|
|
assert config.provider_status("wecom") == {"enabled": True, "configured": True}
|
|
|
|
|
|
def test_require_bound_identity_can_be_disabled_for_legacy_open_bot_mode():
|
|
config = ChannelConnectionsConfig.model_validate({"enabled": True, "require_bound_identity": False})
|
|
|
|
assert config.enabled is True
|
|
assert config.require_bound_identity is False
|
|
|
|
|
|
def test_provider_status_reports_disabled_and_unknown_providers():
|
|
config = ChannelConnectionsConfig.model_validate({"enabled": True})
|
|
|
|
assert config.provider_status("slack") == {"enabled": False, "configured": False}
|
|
assert config.provider_status("telegram") == {"enabled": False, "configured": False}
|
|
assert config.provider_status("discord") == {"enabled": False, "configured": False}
|
|
assert config.provider_status("feishu") == {"enabled": False, "configured": False}
|
|
assert config.provider_status("dingtalk") == {"enabled": False, "configured": False}
|
|
assert config.provider_status("wechat") == {"enabled": False, "configured": False}
|
|
assert config.provider_status("wecom") == {"enabled": False, "configured": False}
|
|
assert config.provider_status("unknown") == {"enabled": False, "configured": False}
|