ForcePilot/backend/package/yuxi/channels/adapters/msteams/doctor.py
Kris bd60c15df0 feat(msteams): 新增完整的 Microsoft Teams 适配器模块
实现了 Teams 机器人所需的全功能组件,包括:
- 基础命令解析与帮助卡片生成
- 租户验证与访问控制
- 自定义 UA 与媒体工具
- 消息分块、批注处理与会话管理
- 防抖、缓存与配置路由能力
- 投票、配对、审计与运行时状态管理
- TTS 语音合成与卡片构建工具
- 群组管理与权限控制逻辑
2026-05-12 00:46:44 +08:00

103 lines
3.1 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Microsoft Teams Doctor - 可变允许列表检测与警告。
检测 allowlist 中非稳定的条目(显示名、邮箱),
提示用户改为 AAD Object ID。
"""
from __future__ import annotations
import re
from typing import Any
from yuxi.utils.logging_config import logger
_EMAIL_PATTERN = re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
_UUID_PATTERN = re.compile(r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")
def is_mutable_allowlist_entry(entry: str) -> bool:
"""检查 allowlist 条目是否为可变值而非稳定 ID。
Returns True 如果条目是显示名或邮箱(可变),而不是 AAD Object ID稳定
"""
entry = entry.strip()
if not entry:
return False
if entry in ("*",):
return True
if _UUID_PATTERN.match(entry):
return False
if _EMAIL_PATTERN.match(entry):
return True
has_spaces = " " in entry
has_special = any(c in entry for c in "@. ")
looks_like_name = not has_spaces and not has_special and len(entry) < 36
if has_spaces or looks_like_name:
return True
return True
def collect_mutable_allowlist_warnings(
allow_from: list[str] | None = None,
group_allow_from: list[str] | None = None,
allow_name_matching: bool = False,
) -> list[dict[str, Any]]:
warnings: list[dict[str, Any]] = []
dm_entries = allow_from or []
for entry in dm_entries:
if is_mutable_allowlist_entry(entry):
warnings.append(
{
"type": "mutable_allowlist",
"source": "allow_from",
"entry": entry,
"severity": "warning",
"message": (
f"DM allowlist entry '{entry}' is a display name or email. "
f"Consider replacing with AAD Object ID for stability."
),
}
)
group_entries = group_allow_from or []
for entry in group_entries:
if is_mutable_allowlist_entry(entry):
warnings.append(
{
"type": "mutable_allowlist",
"source": "group_allow_from",
"entry": entry,
"severity": "warning",
"message": (
f"Group allowlist entry '{entry}' is a display name or email. "
f"Consider replacing with AAD Object ID for stability."
),
}
)
if allow_name_matching:
warnings.append(
{
"type": "name_matching_enabled",
"source": "allow_name_matching",
"entry": "",
"severity": "warning",
"message": (
"allow_name_matching is enabled. This matches by display name, "
"which can be changed by users. Consider using AAD Object IDs instead."
),
}
)
if warnings:
logger.warning(f"MSTeams Doctor: {len(warnings)} mutable allowlist items detected")
return warnings