From c0d01f32a6c4b079609f7063aa8c4ffac5704c33 Mon Sep 17 00:00:00 2001 From: Toby Harradine Date: Thu, 12 Jul 2018 02:33:39 +0200 Subject: [PATCH] [V3] Use our own checks instead of discord.py's (#1861) * [V3] Use our own checks instead of discord.py's * Remove bot.has_permissions checks too --- redbot/cogs/admin/admin.py | 4 +- redbot/cogs/cleanup/cleanup.py | 25 +++++++--- redbot/cogs/mod/mod.py | 9 ++-- redbot/cogs/permissions/permissions.py | 67 ++++++++++++++------------ 4 files changed, 63 insertions(+), 42 deletions(-) diff --git a/redbot/cogs/admin/admin.py b/redbot/cogs/admin/admin.py index 062d1f61c..f1bd83013 100644 --- a/redbot/cogs/admin/admin.py +++ b/redbot/cogs/admin/admin.py @@ -313,7 +313,7 @@ class Admin: await self._removerole(ctx, ctx.author, selfrole) @selfrole.command(name="add") - @commands.has_permissions(manage_roles=True) + @checks.admin_or_permissions(manage_roles=True) async def selfrole_add(self, ctx: commands.Context, *, role: discord.Role): """ Add a role to the list of available selfroles. @@ -327,7 +327,7 @@ class Admin: await ctx.send("The selfroles list has been successfully modified.") @selfrole.command(name="delete") - @commands.has_permissions(manage_roles=True) + @checks.admin_or_permissions(manage_roles=True) async def selfrole_delete(self, ctx: commands.Context, *, role: SelfRole): """ Removes a role from the list of available selfroles. diff --git a/redbot/cogs/cleanup/cleanup.py b/redbot/cogs/cleanup/cleanup.py index a31260519..68dd42d3d 100644 --- a/redbot/cogs/cleanup/cleanup.py +++ b/redbot/cogs/cleanup/cleanup.py @@ -100,7 +100,6 @@ class Cleanup: @cleanup.command() @commands.guild_only() - @commands.bot_has_permissions(manage_messages=True) async def text( self, ctx: commands.Context, text: str, number: int, delete_pinned: bool = False ): @@ -112,6 +111,10 @@ class Cleanup: Remember to use double quotes.""" channel = ctx.channel + if not channel.permissions_for(ctx.guild.me).manage_messages: + await ctx.send("I need the Manage Messages permission to do this.") + return + author = ctx.author is_bot = self.bot.user.bot @@ -150,7 +153,6 @@ class Cleanup: @cleanup.command() @commands.guild_only() - @commands.bot_has_permissions(manage_messages=True) async def user( self, ctx: commands.Context, user: str, number: int, delete_pinned: bool = False ): @@ -159,6 +161,10 @@ class Cleanup: Examples: cleanup user @\u200bTwentysix 2 cleanup user Red 6""" + channel = ctx.channel + if not channel.permissions_for(ctx.guild.me).manage_messages: + await ctx.send("I need the Manage Messages permission to do this.") + return member = None try: @@ -171,7 +177,6 @@ class Cleanup: else: _id = member.id - channel = ctx.channel author = ctx.author is_bot = self.bot.user.bot @@ -212,7 +217,6 @@ class Cleanup: @cleanup.command() @commands.guild_only() - @commands.bot_has_permissions(manage_messages=True) async def after(self, ctx: commands.Context, message_id: int, delete_pinned: bool = False): """Deletes all messages after specified message. @@ -224,6 +228,9 @@ class Cleanup: """ channel = ctx.channel + if not channel.permissions_for(ctx.guild.me).manage_messages: + await ctx.send("I need the Manage Messages permission to do this.") + return author = ctx.author is_bot = self.bot.user.bot @@ -250,7 +257,6 @@ class Cleanup: @cleanup.command() @commands.guild_only() - @commands.bot_has_permissions(manage_messages=True) async def messages(self, ctx: commands.Context, number: int, delete_pinned: bool = False): """Deletes last X messages. @@ -258,6 +264,9 @@ class Cleanup: cleanup messages 26""" channel = ctx.channel + if not channel.permissions_for(ctx.guild.me).manage_messages: + await ctx.send("I need the Manage Messages permission to do this.") + return author = ctx.author is_bot = self.bot.user.bot @@ -284,11 +293,13 @@ class Cleanup: @cleanup.command(name="bot") @commands.guild_only() - @commands.bot_has_permissions(manage_messages=True) async def cleanup_bot(self, ctx: commands.Context, number: int, delete_pinned: bool = False): """Cleans up command messages and messages from the bot.""" - channel = ctx.message.channel + channel = ctx.channel + if not channel.permissions_for(ctx.guild.me).manage_messages: + await ctx.send("I need the Manage Messages permission to do this.") + return author = ctx.message.author is_bot = self.bot.user.bot diff --git a/redbot/cogs/mod/mod.py b/redbot/cogs/mod/mod.py index ad2addf09..c1e72f5e1 100644 --- a/redbot/cogs/mod/mod.py +++ b/redbot/cogs/mod/mod.py @@ -628,7 +628,6 @@ class Mod: @commands.command() @commands.guild_only() @checks.admin_or_permissions(ban_members=True) - @commands.bot_has_permissions(ban_members=True) async def unban(self, ctx: commands.Context, user_id: int, *, reason: str = None): """Unbans the target user. @@ -636,6 +635,10 @@ class Mod: 1. Copy it from the mod log case (if one was created), or 2. enable developer mode, go to Bans in this server's settings, right- click the user and select 'Copy ID'.""" + channel = ctx.channel + if not channel.permissions_for(ctx.guild.me).ban_members: + await ctx.send("I need the Ban Members permission to do this.") + return guild = ctx.guild author = ctx.author user = await self.bot.get_user_info(user_id) @@ -1186,7 +1189,7 @@ class Mod: await ctx.send(_("Channel already in ignore list.")) @ignore.command(name="server", aliases=["guild"]) - @commands.has_permissions(manage_guild=True) + @checks.admin_or_permissions(manage_guild=True) async def ignore_guild(self, ctx: commands.Context): """Ignores current server""" guild = ctx.guild @@ -1219,7 +1222,7 @@ class Mod: await ctx.send(_("That channel is not in the ignore list.")) @unignore.command(name="server", aliases=["guild"]) - @commands.has_permissions(manage_guild=True) + @checks.admin_or_permissions(manage_guild=True) async def unignore_guild(self, ctx: commands.Context): """Removes current guild from ignore list""" guild = ctx.message.guild diff --git a/redbot/cogs/permissions/permissions.py b/redbot/cogs/permissions/permissions.py index 340acbea5..ed9815005 100644 --- a/redbot/cogs/permissions/permissions.py +++ b/redbot/cogs/permissions/permissions.py @@ -17,6 +17,7 @@ _models = ["owner", "guildowner", "admin", "mod", "all"] _ = Translator("Permissions", __file__) REACTS = {"\N{WHITE HEAVY CHECK MARK}": True, "\N{NEGATIVE SQUARED CROSS MARK}": False} +Y_OR_N = {"y": True, "yes": True, "n": False, "no": False} @cog_i18n(_) @@ -532,31 +533,14 @@ class Permissions: models.update(data) await ctx.send(_("Default set.")) - @commands.bot_has_permissions(add_reactions=True) @checks.is_owner() @permissions.command(name="clearglobalsettings") async def clear_globals(self, ctx: commands.Context): """ Clears all global rules. """ + await self._confirm_then_clear_rules(ctx, is_guild=False) - m = await ctx.send("Are you sure?") - for r in REACTS.keys(): - await m.add_reaction(r) - try: - reaction, user = await self.bot.wait_for( - "reaction_add", check=lambda r, u: u == ctx.author and str(r) in REACTS, timeout=30 - ) - except asyncio.TimeoutError: - return await ctx.send(_("Ok, try responding with an emoji next time.")) - - if REACTS.get(str(reaction)): - await self.config.owner_models.clear() - await ctx.send(_("Global settings cleared.")) - else: - await ctx.send(_("Okay.")) - - @commands.bot_has_permissions(add_reactions=True) @commands.guild_only() @checks.guildowner_or_permissions(administrator=True) @permissions.command(name="clearguildsettings") @@ -564,20 +548,43 @@ class Permissions: """ Clears all guild rules. """ + await self._confirm_then_clear_rules(ctx, is_guild=True) - m = await ctx.send("Are you sure?") - for r in REACTS.keys(): - await m.add_reaction(r) - try: - reaction, user = await self.bot.wait_for( - "reaction_add", check=lambda r, u: u == ctx.author and str(r) in REACTS, timeout=30 - ) - except asyncio.TimeoutError: - return await ctx.send(_("Ok, try responding with an emoji next time.")) + async def _confirm_then_clear_rules(self, ctx: commands.Context, is_guild: bool): + if ctx.guild.me.permissions_in(ctx.channel).add_reactions: + m = await ctx.send(_("Are you sure?")) + for r in REACTS.keys(): + await m.add_reaction(r) + try: + reaction, user = await self.bot.wait_for( + "reaction_add", + check=lambda r, u: u == ctx.author and str(r) in REACTS, + timeout=30, + ) + except asyncio.TimeoutError: + return await ctx.send(_("Ok, try responding with an emoji next time.")) - if REACTS.get(str(reaction)): - await self.config.guild(ctx.guild).owner_models.clear() - await ctx.send(_("Guild settings cleared.")) + agreed = REACTS.get(str(reaction)) + else: + await ctx.send(_("Are you sure? (y/n)")) + try: + message = await self.bot.wait_for( + "message", + check=lambda m: m.author == ctx.author and m.content in Y_OR_N, + timeout=30, + ) + except asyncio.TimeoutError: + return await ctx.send(_("Ok, try responding with yes or no next time.")) + + agreed = Y_OR_N.get(message.content.lower()) + + if agreed: + if is_guild: + await self.config.guild(ctx.guild).owner_models.clear() + await ctx.send(_("Guild settings cleared.")) + else: + await self.config.owner_models.clear() + await ctx.send(_("Global settings cleared.")) else: await ctx.send(_("Okay."))