ForcePilot/backend/package/yuxi/channels/adapters/nextcloudtalk/credentials.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

58 lines
1.4 KiB
Python

from __future__ import annotations
import logging
import os
logger = logging.getLogger(__name__)
def read_secret_file(filepath: str) -> str:
if not filepath:
raise ValueError("filepath cannot be empty")
real_path = os.path.realpath(filepath)
if real_path != os.path.abspath(filepath):
raise ValueError("Secret file path contains symlinks, which is not allowed")
try:
with open(filepath, encoding="utf-8") as f:
content = f.read()
except FileNotFoundError:
raise ValueError(f"Secret file not found: {filepath}")
except PermissionError:
raise ValueError(f"Permission denied reading secret file: {filepath}")
return content.strip()
def resolve_credential(
direct_value: str | None,
file_path: str | None,
env_var: str | None = None,
) -> str:
if direct_value:
return direct_value
if file_path:
return read_secret_file(file_path)
if env_var:
val = os.getenv(env_var, "")
if val:
return val
return ""
def resolve_credential_with_source(
direct_value: str | None,
file_path: str | None,
env_var: str | None = None,
) -> tuple[str, str]:
if direct_value:
return direct_value, "config"
if file_path:
return read_secret_file(file_path), "secretFile"
if env_var:
val = os.getenv(env_var, "")
if val:
return val, "env"
return "", "none"