"""敏感信息脱敏工具。""" import re from collections.abc import Mapping from typing import Any SENSITIVE_KEYS = { "api_key", "apikey", "authorization", "password", "secret", "token", "access_token", "refresh_token", "private_key", } _REDACTED = "[REDACTED]" _BEARER_RE = re.compile(r"Bearer\s+[A-Za-z0-9._~+/-]+=*", re.IGNORECASE) def redact_text(value: str) -> str: return _BEARER_RE.sub("Bearer [REDACTED]", value) def redact_mapping(data: Mapping[str, Any]) -> dict[str, Any]: redacted: dict[str, Any] = {} for key, value in data.items(): normalized = key.lower().replace("-", "_") if normalized in SENSITIVE_KEYS or any(part in normalized for part in SENSITIVE_KEYS): redacted[key] = _REDACTED else: redacted[key] = redact_value(value) return redacted def redact_value(value: Any) -> Any: if isinstance(value, str): return redact_text(value) if isinstance(value, Mapping): return redact_mapping(value) if isinstance(value, list): return [redact_value(item) for item in value] return value