实现了 Teams 机器人所需的全功能组件,包括: - 基础命令解析与帮助卡片生成 - 租户验证与访问控制 - 自定义 UA 与媒体工具 - 消息分块、批注处理与会话管理 - 防抖、缓存与配置路由能力 - 投票、配对、审计与运行时状态管理 - TTS 语音合成与卡片构建工具 - 群组管理与权限控制逻辑
103 lines
3.1 KiB
Python
103 lines
3.1 KiB
Python
"""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
|