新增IRC协议相关的全套工具模块,包括: - 核心协议解析与CTCP处理 - 消息发送缓存与文本 sanitize - 账号配置管理与运行时状态 - 命令处理与权限控制 - 服务发现与诊断工具 - 多账号网关与配置加载
98 lines
2.8 KiB
Python
98 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from dataclasses import dataclass, field
|
|
from typing import Any
|
|
|
|
|
|
@dataclass
|
|
class SecretTarget:
|
|
key: str
|
|
label: str
|
|
description: str
|
|
env_var: str | None = None
|
|
config_path: str | None = None
|
|
required: bool = False
|
|
metadata: dict[str, Any] = field(default_factory=dict)
|
|
|
|
|
|
IRC_SECRET_TARGETS: list[SecretTarget] = [
|
|
SecretTarget(
|
|
key="nickserv_password",
|
|
label="NickServ Password",
|
|
description="Password used with NickServ IDENTIFY to reserve and protect the bot's nickname",
|
|
env_var="IRC_NICKSERV_PASSWORD",
|
|
config_path="nickserv_password",
|
|
),
|
|
SecretTarget(
|
|
key="server_password",
|
|
label="Server Password",
|
|
description="IRC server connection password (PASS command)",
|
|
env_var="IRC_SERVER_PASSWORD",
|
|
config_path="password",
|
|
),
|
|
SecretTarget(
|
|
key="sasl_password",
|
|
label="SASL Password",
|
|
description="SASL authentication password for PLAIN or SCRAM mechanisms",
|
|
env_var="IRC_SASL_PASSWORD",
|
|
config_path="sasl_password",
|
|
),
|
|
SecretTarget(
|
|
key="nickserv_password_file",
|
|
label="NickServ Password File",
|
|
description="File path containing NickServ password (alternative to inline password)",
|
|
env_var="IRC_NICKSERV_PASSWORD_FILE",
|
|
config_path="nickserv_password_file",
|
|
),
|
|
]
|
|
|
|
|
|
def list_secret_targets() -> list[dict[str, Any]]:
|
|
return [
|
|
{
|
|
"key": t.key,
|
|
"label": t.label,
|
|
"description": t.description,
|
|
"env_var": t.env_var,
|
|
"config_path": t.config_path,
|
|
"required": t.required,
|
|
}
|
|
for t in IRC_SECRET_TARGETS
|
|
]
|
|
|
|
|
|
def get_secret_target(key: str) -> dict[str, Any] | None:
|
|
for t in IRC_SECRET_TARGETS:
|
|
if t.key == key:
|
|
return {
|
|
"key": t.key,
|
|
"label": t.label,
|
|
"description": t.description,
|
|
"env_var": t.env_var,
|
|
"config_path": t.config_path,
|
|
"required": t.required,
|
|
}
|
|
return None
|
|
|
|
|
|
def audit_secrets(config: dict[str, Any]) -> list[dict[str, Any]]:
|
|
findings: list[dict[str, Any]] = []
|
|
for t in IRC_SECRET_TARGETS:
|
|
found_paths: list[str] = []
|
|
if t.config_path and config.get(t.config_path):
|
|
found_paths.append(f"config.{t.config_path}")
|
|
|
|
if t.env_var and os.environ.get(t.env_var):
|
|
found_paths.append(f"env.{t.env_var}")
|
|
findings.append(
|
|
{
|
|
"key": t.key,
|
|
"label": t.label,
|
|
"configured": bool(found_paths),
|
|
"sources": found_paths,
|
|
"required": t.required,
|
|
}
|
|
)
|
|
return findings
|