feat: add per-channel plugin filtering
Channels with a [channels."#name"] section and `plugins` list only run those plugins. Unconfigured channels run everything. Core is always active. PMs are unrestricted. Denied commands are silently ignored.
This commit is contained in:
@@ -281,8 +281,11 @@ class Bot:
|
||||
return
|
||||
|
||||
# Dispatch to event handlers (fire-and-forget)
|
||||
channel = msg.target if msg.is_channel else None
|
||||
event_type = msg.command
|
||||
for handler in self.registry.events.get(event_type, []):
|
||||
if not self._plugin_allowed(handler.plugin, channel):
|
||||
continue
|
||||
self._spawn(handler.callback(self, msg), name=f"event:{handler.name}")
|
||||
|
||||
# Dispatch to command handlers (PRIVMSG only)
|
||||
@@ -312,6 +315,20 @@ class Bot:
|
||||
await self.conn.send(format_msg("NOTICE", msg.nick, reply))
|
||||
log.debug("CTCP %s reply to %s", ctcp_cmd, msg.nick)
|
||||
|
||||
def _plugin_allowed(self, plugin_name: str, channel: str | None) -> bool:
|
||||
"""Check if a plugin is allowed in a channel."""
|
||||
if plugin_name == "core":
|
||||
return True
|
||||
if not channel or not channel.startswith(("#", "&")):
|
||||
return True # PMs are unrestricted
|
||||
chan_cfg = self.config.get("channels", {}).get(channel)
|
||||
if not chan_cfg:
|
||||
return True # unconfigured channels run everything
|
||||
allowed = chan_cfg.get("plugins")
|
||||
if allowed is None:
|
||||
return True
|
||||
return plugin_name in allowed
|
||||
|
||||
def _is_admin(self, msg: Message) -> bool:
|
||||
"""Check if the message sender is a bot admin.
|
||||
|
||||
@@ -345,6 +362,10 @@ class Bot:
|
||||
name=f"cmd:{cmd_name}:ambiguous")
|
||||
return
|
||||
|
||||
channel = msg.target if msg.is_channel else None
|
||||
if not self._plugin_allowed(handler.plugin, channel):
|
||||
return
|
||||
|
||||
if handler.admin and not self._is_admin(msg):
|
||||
deny = f"Permission denied: {self.prefix}{cmd_name} requires admin"
|
||||
self._spawn(self.reply(msg, deny), name=f"cmd:{cmd_name}:denied")
|
||||
|
||||
@@ -29,8 +29,10 @@ DEFAULTS: dict = {
|
||||
"rate_burst": 5,
|
||||
"admins": [],
|
||||
},
|
||||
"channels": {},
|
||||
"logging": {
|
||||
"level": "info",
|
||||
"format": "text",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user