ForcePilot/backend/package/yuxi/channel/extensions/imessage/security.py
Kris 4d52f634fe feat(imessage): 新增iMessage渠道插件完整实现
该提交新增了基于BlueBubbles的iMessage渠道插件,支持单聊和群组消息,包含文本、图片、语音、文件和视频消息收发,支持消息编辑、撤回、回复、 reactions和输入状态提示,同时实现了账号配置、安全校验、配对授权、消息格式化与分片等完整功能。
2026-05-21 10:50:15 +08:00

112 lines
3.7 KiB
Python

from __future__ import annotations
import logging
logger = logging.getLogger(__name__)
class IMessageSecurityAdapter:
DM_POLICY_OPTIONS = ["pairing", "allowlist", "open", "disabled"]
GROUP_POLICY_OPTIONS = ["open", "allowlist", "disabled"]
def __init__(self, config_adapter=None):
self._config_adapter = config_adapter
def _get_channel_config(self, config: dict) -> dict:
if self._config_adapter:
return self._config_adapter._get_channel_config(config)
return config.get("channels", {}).get("imessage", {})
def resolve_dm_policy(self, config: dict | None = None) -> dict:
if config:
channel_config = self._get_channel_config(config)
return {
"mode": channel_config.get("dm_policy", "pairing"),
"allow_from": channel_config.get("allow_from", []),
}
return {"mode": "pairing", "allow_from": []}
async def check_allowlist(self, peer_id: str, channel_type: str, config: dict | None = None) -> bool:
if not config:
return False
channel_config = self._get_channel_config(config)
dm_policy = channel_config.get("dm_policy", "pairing")
if dm_policy == "open":
return True
if dm_policy == "disabled":
return False
allow_from = channel_config.get("allow_from", [])
if "*" in allow_from:
return True
if peer_id in allow_from:
return True
if dm_policy == "pairing":
return False
return False
def resolve_group_policy(self, config: dict | None = None) -> dict:
if config:
channel_config = self._get_channel_config(config)
return {
"mode": channel_config.get("group_policy", "allowlist"),
"group_allow_from": channel_config.get("group_allow_from", []),
}
return {"mode": "allowlist", "group_allow_from": []}
async def check_group_access(self, config: dict, chat_guid: str, sender_handle: str) -> bool:
channel_config = self._get_channel_config(config)
group_policy = channel_config.get("group_policy", "allowlist")
if group_policy == "open":
return True
if group_policy == "disabled":
return False
group_allow_from = channel_config.get("group_allow_from", [])
if sender_handle in group_allow_from:
return True
groups = channel_config.get("groups", {})
if chat_guid in groups:
return True
return False
def is_allowed_dm(self, peer_id: str, allow_from: list[str], policy: str) -> bool:
if policy == "open":
return True
if policy == "disabled":
return False
if policy == "allowlist":
return peer_id in allow_from or "*" in allow_from
if policy == "pairing":
return peer_id in allow_from
return False
def is_allowed_group(self, group_id: str, group_allow_from: list[str], policy: str) -> bool:
if policy == "open":
return True
if policy == "disabled":
return False
if policy == "allowlist":
return group_id in group_allow_from
return False
def is_valid_allow_entry(self, entry: str) -> bool:
if not entry or entry == "*":
return True
if "@" in entry:
return True
if entry.startswith("+"):
return True
if entry.startswith("chat_guid:"):
return len(entry) > len("chat_guid:")
if entry.startswith("chat_identifier:"):
return len(entry) > len("chat_identifier:")
return False