From ccdd1ca89208de21eabb8fc5a903fd9457b52939 Mon Sep 17 00:00:00 2001 From: Flame442 <34169552+Flame442@users.noreply.github.com> Date: Fri, 14 Apr 2023 17:58:02 -0400 Subject: [PATCH] Add global checks to app commands (#6015) --- redbot/core/bot.py | 27 +++++++++++++++++++-------- redbot/core/tree.py | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/redbot/core/bot.py b/redbot/core/bot.py index 02ebd1ec4..49a339fdd 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -851,7 +851,7 @@ class Red( return True async def ignored_channel_or_guild( - self, ctx: Union[commands.Context, discord.Message] + self, ctx: Union[commands.Context, discord.Message, discord.Interaction] ) -> bool: """ This checks if the bot is meant to be ignoring commands in a channel or guild, @@ -861,7 +861,8 @@ class Red( ---------- ctx : Context object of the command which needs to be checked prior to invoking - or a Message object which might be intended for use as a command. + or a Message object which might be intended for use as a command + or an Interaction object which might be intended for use with a command. Returns ------- @@ -871,20 +872,30 @@ class Red( Raises ------ TypeError - ``ctx.channel`` is of `discord.PartialMessageable` type. + ``ctx.channel`` is a `discord.PartialMessageable` with a ``type`` other + than ``discord.ChannelType.private`` """ + if isinstance(ctx, discord.Interaction): + author = ctx.user + else: + author = ctx.author + + is_private = isinstance(ctx.channel, discord.abc.PrivateChannel) if isinstance(ctx.channel, discord.PartialMessageable): - raise TypeError("Can't check permissions for PartialMessageable.") - perms = ctx.channel.permissions_for(ctx.author) + if ctx.channel.type is not discord.ChannelType.private: + raise TypeError("Can't check permissions for non-private PartialMessageable.") + is_private = True + perms = ctx.channel.permissions_for(author) surpass_ignore = ( - isinstance(ctx.channel, discord.abc.PrivateChannel) + is_private or perms.manage_guild - or await self.is_owner(ctx.author) - or await self.is_admin(ctx.author) + or await self.is_owner(author) + or await self.is_admin(author) ) # guild-wide checks if surpass_ignore: return True + guild_ignored = await self._ignored_cache.get_ignored_guild(ctx.guild) if guild_ignored: return False diff --git a/redbot/core/tree.py b/redbot/core/tree.py index 94bb76676..2d97b3e3d 100644 --- a/redbot/core/tree.py +++ b/redbot/core/tree.py @@ -309,6 +309,27 @@ class RedTree(CommandTree): else: log.exception(type(error).__name__, exc_info=error) + async def interaction_check(self, interaction: discord.Interaction): + """Global checks for app commands.""" + if interaction.user.bot: + return False + + if interaction.guild: + if not (await self.client.ignored_channel_or_guild(interaction)): + await interaction.response.send_message( + "This channel or server is ignored.", ephemeral=True + ) + return False + + if not (await self.client.allowed_by_whitelist_blacklist(interaction.user)): + await interaction.response.send_message( + "You are not permitted to use commands because of an allowlist or blocklist.", + ephemeral=True, + ) + return False + + return True + # DEP-WARN def _remove_with_module(self, name: str, *args, **kwargs) -> None: """Handles cases where a module raises an exception in the loading process, but added commands to the tree.