ForcePilot/backend/package/yuxi/channels/adapters/googlechat/approval_auth.py
Kris ca07c593a8 feat(googlechat): 实现 Google Chat 适配器完整功能集
新增 Google Chat 对接的全套工具模块,包括:
- 会话线程管理、消息解析与格式化
- Pub/Sub 消息解码、提及和命令识别
- 权限审批、目录管理和审计日志
- 消息缓存、媒体上传下载和 SSFR 防护
- 策略配置、卡片构建和流式回复支持
2026-05-12 00:44:18 +08:00

72 lines
1.9 KiB
Python

from __future__ import annotations
from typing import Any
from yuxi.utils.logging_config import logger
def normalize_approver_id(raw: str) -> str:
if not raw:
return ""
if raw.startswith("users/") or raw.startswith("user:"):
return raw
if "@" in raw:
return f"users/{raw}"
return f"users/{raw}"
def resolve_approver_ids(
dm_allow_from: list[str],
default_to: str = "",
) -> list[str]:
approvers: list[str] = []
for entry in dm_allow_from:
if entry == "*":
continue
normalized = normalize_approver_id(entry)
if normalized:
approvers.append(normalized)
if not approvers and default_to:
approvers.append(normalize_approver_id(default_to))
return approvers
def build_exec_approval_context(
action_id: str,
approvers: list[str],
metadata: dict[str, Any] | None = None,
) -> dict[str, Any]:
return {
"action_id": action_id,
"approvers": approvers,
"approved_by": [],
"rejected_by": [],
"metadata": metadata or {},
}
def record_approval_decision(
context: dict[str, Any],
user_id: str,
approved: bool,
) -> bool:
normalized = normalize_approver_id(user_id)
if normalized not in context.get("approvers", []):
logger.warning(f"User {normalized} is not an authorized approver")
return False
if approved:
if normalized in context.get("approved_by", []):
return True
context.setdefault("approved_by", []).append(normalized)
else:
if normalized in context.get("rejected_by", []):
return True
context.setdefault("rejected_by", []).append(normalized)
return True
def is_fully_approved(context: dict[str, Any]) -> bool:
approvers = context.get("approvers", [])
approved = context.get("approved_by", [])
return bool(approvers) and set(approvers) == set(approved)