ForcePilot/backend/package/yuxi/channels/adapters/irc/doctor.py
Kris 2dd1a075f2 feat(irc): 实现完整的IRC适配器基础功能模块
新增IRC协议相关的全套工具模块,包括:
- 核心协议解析与CTCP处理
- 消息发送缓存与文本 sanitize
- 账号配置管理与运行时状态
- 命令处理与权限控制
- 服务发现与诊断工具
- 多账号网关与配置加载
2026-05-12 00:45:10 +08:00

88 lines
2.7 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
from .security import (
IRCSecurityConfig,
_find_mutable_allowlist_entries,
)
@dataclass
class DoctorDiagnosis:
status: str = "ok"
warnings: list[str] = field(default_factory=list)
errors: list[str] = field(default_factory=list)
checks: list[dict[str, Any]] = field(default_factory=list)
def diagnose(
config: dict[str, Any],
security_config: IRCSecurityConfig | None = None,
use_tls: bool = True,
nickserv_enabled: bool = False,
nickserv_register: bool = False,
) -> DoctorDiagnosis:
result = DoctorDiagnosis()
_check_tls(result, use_tls)
_check_nickserv(result, nickserv_enabled, nickserv_register)
if security_config:
_check_policies(result, security_config)
_check_mutable_allowlist(result, security_config)
return result
def _check_tls(result: DoctorDiagnosis, use_tls: bool) -> None:
check = {"name": "tls", "status": "ok"}
if not use_tls:
check["status"] = "warning"
check["message"] = "TLS is disabled — connection is not encrypted"
result.warnings.append(check["message"])
result.checks.append(check)
def _check_nickserv(
result: DoctorDiagnosis,
nickserv_enabled: bool,
nickserv_register: bool,
) -> None:
check = {"name": "nickserv", "status": "ok"}
if not nickserv_enabled:
check["status"] = "warning"
check["message"] = "NickServ is not enabled — nick may not be reserved"
result.warnings.append(check["message"])
elif nickserv_register:
check["status"] = "warning"
check["message"] = (
"nickserv.register is enabled — after first successful registration "
"consider removing this config to avoid repeated REGISTER commands"
)
result.warnings.append(check["message"])
result.checks.append(check)
def _check_policies(
result: DoctorDiagnosis,
security_config: IRCSecurityConfig,
) -> None:
check = {"name": "group_policy", "status": "ok"}
if security_config.group_policy == "open":
check["status"] = "warning"
check["message"] = "Group policy is 'open' — anyone can trigger bot in channels"
result.warnings.append(check["message"])
result.checks.append(check)
def _check_mutable_allowlist(
result: DoctorDiagnosis,
security_config: IRCSecurityConfig,
) -> None:
mutable_entries = _find_mutable_allowlist_entries(security_config)
for entry in mutable_entries:
msg = f"Mutable allowlist entry detected: '{entry}' — consider using nick!user@host format"
result.warnings.append(msg)
result.checks.append({"name": "mutable_allowlist", "status": "warning", "message": msg})