from __future__ import annotations from dataclasses import dataclass @dataclass class SecretDescriptor: name: str description: str required: bool = True env_var: str = "" config_key: str = "" MATTERMOST_SECRETS = [ SecretDescriptor( name="bot_token", description="Mattermost Bot Personal Access Token", required=True, env_var="MATTERMOST_BOT_TOKEN", config_key="bot_token", ), SecretDescriptor( name="signing_secret", description="Mattermost Interactive Messages Signing Secret", required=False, env_var="MATTERMOST_SIGNING_SECRET", config_key="signing_secret", ), SecretDescriptor( name="approval_secret", description="Mattermost Exec Approval HMAC Secret", required=False, env_var="MATTERMOST_APPROVAL_SECRET", config_key="approval_secret", ), ] def get_secret_contract() -> list[SecretDescriptor]: """返回 Mattermost 渠道的密钥契约列表。""" return MATTERMOST_SECRETS def resolve_secret(name: str, config: dict) -> str | None: """从 config 或环境变量解析密钥。""" for secret in MATTERMOST_SECRETS: if secret.name == name: val = config.get(secret.config_key, "") if val: return val import os return os.getenv(secret.env_var, "") or None return None def list_configured_secrets(config: dict) -> dict[str, str]: """列出所有已配置的密钥(仅显示来源,不泄露值)。""" result = {} for secret in MATTERMOST_SECRETS: import os if config.get(secret.config_key): result[secret.name] = "config" elif secret.env_var and os.getenv(secret.env_var): result[secret.name] = "env" else: result[secret.name] = "missing" return result def build_secret_target_registry_entries() -> list[dict]: return [ { "channel_id": "mattermost", "secret_name": s.name, "label": s.description, "env_var": s.env_var, "required": s.required, } for s in MATTERMOST_SECRETS ] def collect_runtime_config_assignments(config: dict) -> list[dict]: assignments = [] for secret in MATTERMOST_SECRETS: value = resolve_secret(secret.name, config) if value: assignments.append( { "channel_id": "mattermost", "secret_name": secret.name, "config_key": secret.config_key, "source": "env" if not config.get(secret.config_key) else "config", } ) return assignments