From 7b9af884ce8e3fb90a9d57c4048b90abeb3ca517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadeusz=20So=C5=9Bnierz?= Date: Wed, 6 Oct 2021 14:56:25 +0200 Subject: [PATCH 1/3] Make it possible to disable commands dynamically This allows for hiding them completely depending on e.g. a config setting, or arbitrary sender rules (up to the implementing bridge). --- mautrix/bridge/commands/handler.py | 9 ++++++++- mautrix/bridge/commands/meta.py | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mautrix/bridge/commands/handler.py b/mautrix/bridge/commands/handler.py index 86787c2b..9894cece 100644 --- a/mautrix/bridge/commands/handler.py +++ b/mautrix/bridge/commands/handler.py @@ -193,6 +193,7 @@ def _render_message(message: str, allow_html: bool, render_markdown: bool) -> Op CommandHandlerFunc = Callable[[CommandEvent], Awaitable[Any]] +IsEnabledForFunc = Callable[[CommandEvent], bool] class CommandHandler: @@ -213,6 +214,7 @@ class CommandHandler: management_only: bool needs_admin: bool needs_auth: bool + is_enabled_for: IsEnabledForFunc _help_text: str _help_args: str @@ -220,7 +222,9 @@ class CommandHandler: def __init__(self, handler: CommandHandlerFunc, management_only: bool, name: str, help_text: str, help_args: str, help_section: HelpSection, - needs_auth: bool, needs_admin: bool, **kwargs) -> None: + needs_auth: bool, needs_admin: bool, + is_enabled_for: IsEnabledForFunc = lambda _: True, + **kwargs) -> None: """ Args: handler: The function handling the execution of this command. @@ -243,6 +247,7 @@ def __init__(self, handler: CommandHandlerFunc, management_only: bool, name: str self._help_text = help_text self._help_args = help_args self.help_section = help_section + self.is_enabled_for = is_enabled_for async def get_permission_error(self, evt: CommandEvent) -> Optional[str]: """Returns the reason why the command could not be issued. @@ -392,6 +397,8 @@ async def handle(self, room_id: RoomID, event_id: EventID, sender: BaseUser, command = command.lower() try: handler = command_handlers[command] + if not handler.is_enabled_for(evt): + raise KeyError() except KeyError: try: handler = command_aliases[command] diff --git a/mautrix/bridge/commands/meta.py b/mautrix/bridge/commands/meta.py index 8b4354ed..b21508b7 100644 --- a/mautrix/bridge/commands/meta.py +++ b/mautrix/bridge/commands/meta.py @@ -45,7 +45,7 @@ async def _get_help_text(evt: CommandEvent) -> str: if cache_key not in help_cache: help_sections: Dict[HelpSection, List[str]] = {} for handler in command_handlers.values(): - if handler.has_help and handler.has_permission(cache_key): + if handler.has_help and handler.has_permission(cache_key) and handler.is_enabled_for(evt): help_sections.setdefault(handler.help_section, []) help_sections[handler.help_section].append(handler.help + " ") help_sorted = sorted(help_sections.items(), key=lambda item: item[0].order) From 697e4e93049aa5df0c0e821f3294ec0fc68284a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadeusz=20So=C5=9Bnierz?= Date: Wed, 6 Oct 2021 15:45:04 +0200 Subject: [PATCH 2/3] Make sure command aliases respect is_enabled_for as well --- mautrix/bridge/commands/handler.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/mautrix/bridge/commands/handler.py b/mautrix/bridge/commands/handler.py index 9894cece..e10d9d84 100644 --- a/mautrix/bridge/commands/handler.py +++ b/mautrix/bridge/commands/handler.py @@ -395,20 +395,16 @@ async def handle(self, room_id: RoomID, event_id: EventID, sender: BaseUser, is_management=is_management, has_bridge_bot=has_bridge_bot) orig_command = command command = command.lower() - try: - handler = command_handlers[command] - if not handler.is_enabled_for(evt): - raise KeyError() - except KeyError: - try: - handler = command_aliases[command] - except KeyError: - if sender.command_status and "next" in sender.command_status: - args.insert(0, orig_command) - evt.command = "" - handler = sender.command_status["next"] - else: - handler = command_handlers["unknown-command"] + + handler = command_handlers.get(command) or command_aliases.get(command) + if handler is None or not handler.is_enabled_for(evt): + if sender.command_status and "next" in sender.command_status: + args.insert(0, orig_command) + evt.command = "" + handler = sender.command_status["next"] + else: + handler = command_handlers["unknown-command"] + try: await self._run_handler(handler, evt) except Exception: From 16ebcb92f8d64fea4f5afadf0341d1ab9c573535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadeusz=20So=C5=9Bnierz?= Date: Wed, 6 Oct 2021 18:12:10 +0200 Subject: [PATCH 3/3] Make command handler resolution a little nicer Co-authored-by: Sumner Evans --- mautrix/bridge/commands/handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mautrix/bridge/commands/handler.py b/mautrix/bridge/commands/handler.py index e10d9d84..e6ca8eb1 100644 --- a/mautrix/bridge/commands/handler.py +++ b/mautrix/bridge/commands/handler.py @@ -396,7 +396,7 @@ async def handle(self, room_id: RoomID, event_id: EventID, sender: BaseUser, orig_command = command command = command.lower() - handler = command_handlers.get(command) or command_aliases.get(command) + handler = command_handlers.get(command, command_aliases.get(command)) if handler is None or not handler.is_enabled_for(evt): if sender.command_status and "next" in sender.command_status: args.insert(0, orig_command)