mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-17 21:15: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>
63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
"""Configuration for user-owned IM channel connections."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class SlackChannelConnectionConfig(BaseModel):
|
|
enabled: bool = False
|
|
|
|
@property
|
|
def configured(self) -> bool:
|
|
return True
|
|
|
|
|
|
class TelegramChannelConnectionConfig(BaseModel):
|
|
enabled: bool = False
|
|
bot_username: str = ""
|
|
|
|
@property
|
|
def configured(self) -> bool:
|
|
return bool(self.bot_username)
|
|
|
|
|
|
class DiscordChannelConnectionConfig(BaseModel):
|
|
enabled: bool = False
|
|
|
|
@property
|
|
def configured(self) -> bool:
|
|
return True
|
|
|
|
|
|
class BindingCodeChannelConnectionConfig(BaseModel):
|
|
enabled: bool = False
|
|
|
|
@property
|
|
def configured(self) -> bool:
|
|
return True
|
|
|
|
|
|
class ChannelConnectionsConfig(BaseModel):
|
|
"""Top-level config for browser-connectable IM channels."""
|
|
|
|
enabled: bool = False
|
|
require_bound_identity: bool = True
|
|
slack: SlackChannelConnectionConfig = Field(default_factory=SlackChannelConnectionConfig)
|
|
telegram: TelegramChannelConnectionConfig = Field(default_factory=TelegramChannelConnectionConfig)
|
|
discord: DiscordChannelConnectionConfig = Field(default_factory=DiscordChannelConnectionConfig)
|
|
feishu: BindingCodeChannelConnectionConfig = Field(default_factory=BindingCodeChannelConnectionConfig)
|
|
dingtalk: BindingCodeChannelConnectionConfig = Field(default_factory=BindingCodeChannelConnectionConfig)
|
|
wechat: BindingCodeChannelConnectionConfig = Field(default_factory=BindingCodeChannelConnectionConfig)
|
|
wecom: BindingCodeChannelConnectionConfig = Field(default_factory=BindingCodeChannelConnectionConfig)
|
|
|
|
def provider_status(self, provider: str) -> dict[str, bool]:
|
|
config = getattr(self, provider, None)
|
|
if config is None:
|
|
return {"enabled": False, "configured": False}
|
|
enabled = bool(config.enabled)
|
|
return {
|
|
"enabled": enabled,
|
|
"configured": enabled and bool(config.configured),
|
|
}
|