from __future__ import annotations from typing import Any from yuxi.utils.logging_config import logger class ChannelAuthorization: def __init__(self, config: dict[str, Any] | None = None): config = config or {} auth_config = config.get("authorization", {}) self._channel_rules: dict[str, dict[str, Any]] = auth_config.get("channel_rules", {}) self._default_authorized_ships: list[str] = auth_config.get("default_authorized_ships", []) self._group_allow_from: list[str] = config.get("group_allow_from", []) def is_channel_allowed(self, channel_id: str, sender_ship: str) -> bool: sender_id = f"urbit:{sender_ship}" if sender_id in self._default_authorized_ships: return True if sender_id in self._group_allow_from: return True rule = self._channel_rules.get(channel_id) if rule is None: return True policy = rule.get("policy", "open") match policy: case "open": return True case "disabled": return False case "allowlist": allow_from = rule.get("allow_from", []) return sender_id in allow_from case _: return False def get_channel_policy(self, channel_id: str) -> str: rule = self._channel_rules.get(channel_id) if rule: return rule.get("policy", "open") return "open" def add_channel_rule( self, channel_id: str, policy: str = "allowlist", allow_from: list[str] | None = None, ) -> None: self._channel_rules[channel_id] = { "policy": policy, "allow_from": allow_from or [], } logger.info(f"[Urbit] Channel rule added: {channel_id} → {policy}") def remove_channel_rule(self, channel_id: str) -> None: self._channel_rules.pop(channel_id, None)