60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
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)
|