import logging logger = logging.getLogger(__name__) class FreshdeskSecurity: def __init__(self, gateway): self._gateway = gateway def resolve_dm_policy(self) -> dict: if self._gateway is None or not self._gateway.accounts: return {"mode": "open", "allow_from": []} entry = next(iter(self._gateway.accounts.values()), None) if entry is None: return {"mode": "open", "allow_from": []} account = entry["account"] return { "mode": account.dm_policy, "allow_from": account.allow_from, } async def check_allowlist(self, peer_id: str, channel_type: str) -> bool: policy = self.resolve_dm_policy() if policy["mode"] == "disabled": return False if policy["mode"] == "open": allow_from = policy["allow_from"] if "*" in allow_from or not allow_from: return True return peer_id in allow_from if policy["mode"] == "allowlist": allow_from = policy["allow_from"] if not allow_from: return False return peer_id in allow_from if policy["mode"] == "pairing": return True return False def authorize_dm(self, account, contact_id: str) -> tuple[bool, str]: policy = account.dm_policy if hasattr(account, 'dm_policy') else account.get("dm_policy", "open") allow_from = account.allow_from if hasattr(account, 'allow_from') else account.get("allow_from", []) if policy == "disabled": return False, "DM is disabled" if policy == "open": if "*" in allow_from or not allow_from: return True, "" return contact_id in allow_from, "not-allowlisted" if policy == "allowlist": if not allow_from: return False, "allowlist-empty" return contact_id in allow_from, "not-allowlisted" if policy == "pairing": return True, "pairing-required" return False, "unknown-policy" def apply_config_fixes(self, config: dict) -> dict: config.setdefault("channels", {}) config["channels"].setdefault("freshdesk", {}) return config def collect_warnings(self, config: dict, account_id: str | None = None, account=None) -> list[str]: warnings: list[str] = [] if account: account_dict = account if isinstance(account, dict) else { "dm_policy": getattr(account, "dm_policy", "open"), "allow_from": getattr(account, "allow_from", []), } if not account_dict.get("webhook_secret"): warnings.append("webhookSecret is not configured. Webhook signature verification will be skipped.") if account_dict.get("dm_policy") == "open" and not account_dict.get("allow_from"): warnings.append('dmPolicy is "open" without allowFrom. Consider adding allowFrom=["*"] explicitly.') if account_dict.get("dm_policy") == "allowlist" and not account_dict.get("allow_from"): warnings.append('dmPolicy is "allowlist" but allowFrom is empty. No contacts will be allowed.') return warnings def collect_audit_findings( self, config, account_id=None, account=None, source_config=None, ordered_account_ids=None, has_explicit_account_path=False, ) -> list[dict]: return []