ForcePilot/backend/package/yuxi/channel/extensions/gitlab/security.py
Kris 4a4e256955 feat(gitlab): 新增完整 GitLab 渠道插件支持
实现了 GitLab 全功能集成,包含 Webhook 处理、API 客户端、消息收发、会话管理、安全校验、限流器等完整模块,支持 Issues、Merge Requests、流水线等事件监听与交互。
2026-05-21 10:49:01 +08:00

58 lines
2.1 KiB
Python

from __future__ import annotations
import logging
logger = logging.getLogger(__name__)
POLICY_OPEN = "open"
POLICY_PAIRING = "pairing"
POLICY_ALLOWLIST = "allowlist"
POLICY_DISABLED = "disabled"
VALID_POLICIES = {POLICY_OPEN, POLICY_PAIRING, POLICY_ALLOWLIST, POLICY_DISABLED}
class GitLabSecurity:
@staticmethod
def resolve_dm_policy(account: dict) -> str:
policy = account.get("dm_policy", POLICY_OPEN)
if policy not in VALID_POLICIES:
logger.warning("gitlab invalid dm_policy '%s', defaulting to open", policy)
return POLICY_OPEN
return policy
@staticmethod
def is_allowed(account: dict, username: str) -> tuple[bool, str | None]:
policy = account.get("dm_policy", POLICY_OPEN)
if policy == POLICY_DISABLED:
return False, "gitlab-disabled"
if policy == POLICY_OPEN:
return True, None
if policy == POLICY_ALLOWLIST:
allow_from: list = account.get("allow_from", [])
if username in allow_from or "*" in allow_from:
return True, None
return False, f"gitlab-not-in-allowlist:{username}"
if policy == POLICY_PAIRING:
allow_from: list = account.get("allow_from", [])
if username in allow_from:
return True, "gitlab-paired"
return True, "gitlab-pairing-required"
return False, "gitlab-unknown-policy"
@staticmethod
def collect_warnings(config: dict, account_id: str | None = None, account: dict | None = None) -> list[str]:
warnings = []
if not account:
return warnings
if account.get("dm_policy") == "open" and not account.get("allow_from"):
warnings.append("gitlab dmPolicy is 'open' without allowFrom — anyone can interact with the bot")
if not account.get("ssl_verify"):
warnings.append("gitlab ssl verification disabled — only use in trusted internal networks")
return warnings
@staticmethod
def is_bot_own_message(payload: dict, bot_username: str) -> bool:
user = payload.get("user", {})
return user.get("username", "") == bot_username