ForcePilot/backend/package/yuxi/channels/adapters/nextcloudtalk/approval_auth.py
Kris b018ad25da feat(backend): add Nextcloud Talk channel adapter implementation
实现了完整的Nextcloud Talk聊天适配器,包含以下核心功能:
1. 基础客户端通信与认证
2. 会话路由与聊天类型解析
3. 消息分块与格式转换
4. 用户配对与权限校验
5. 轮询式消息监听
6. 配置验证与诊断工具
7. 安全策略与去重缓存
8. 指标统计与状态快照

新增配套的配对用户缓存文件与模块导出入口。
2026-05-12 00:47:06 +08:00

55 lines
1.8 KiB
Python

from __future__ import annotations
import logging
from typing import Any
from .normalize import normalize_user_target, strip_nc_prefix
logger = logging.getLogger(__name__)
def resolve_approver_id(user_id: str) -> str:
approver_id = strip_nc_prefix(user_id)
return f"nc:{approver_id}"
def resolve_allow_from_approvers(config: dict[str, Any]) -> list[str]:
allow_from = config.get("allow_from", config.get("allowFrom", []))
return [normalize_user_target(strip_nc_prefix(entry)) for entry in allow_from]
def check_approval_required(
user_id: str,
config: dict[str, Any],
paired_users: set[str] | None = None,
) -> dict[str, Any]:
dm_policy = config.get("dm_policy", "pairing")
if dm_policy == "open":
return {"approval_required": False, "reason": "dm_policy is open"}
if dm_policy == "disabled":
return {"approval_required": True, "reason": "dm_policy is disabled", "action": "block"}
if dm_policy == "allowlist":
allow_from = config.get("allow_from", config.get("allowFrom", []))
approved = any(
normalize_user_target(strip_nc_prefix(e)) == normalize_user_target(strip_nc_prefix(user_id))
for e in allow_from
)
if approved:
return {"approval_required": False, "reason": "User is in allowlist"}
return {"approval_required": True, "reason": "User not in allowlist", "action": "block"}
if dm_policy == "pairing":
if paired_users and user_id in paired_users:
return {"approval_required": False, "reason": "User is already paired"}
return {
"approval_required": True,
"reason": "User not paired",
"action": "pair",
"approver_id": resolve_approver_id(user_id),
}
return {"approval_required": True, "reason": f"Unknown dm_policy: {dm_policy}"}