diff options
| author | 2019-01-09 16:40:54 -0500 | |
|---|---|---|
| committer | 2019-01-09 16:40:54 -0500 | |
| commit | 646a892348af4cf99fe2b08d6a1688e0aff56d3b (patch) | |
| tree | b142e33b094e1b4d0146533a07517a683a1b048b | |
| parent | Add role hierarchy comparison check method (diff) | |
Add hierarchy check to desired infractions
Per #134, only implement for all variations of the ban & kick infractions
Update helper method inputs to facilitate a generic logging & context message
| -rw-r--r-- | bot/cogs/moderation.py | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/bot/cogs/moderation.py b/bot/cogs/moderation.py index a15a1b71c..057b51bbf 100644 --- a/bot/cogs/moderation.py +++ b/bot/cogs/moderation.py @@ -125,6 +125,11 @@ class Moderation(Scheduler): :param reason: The reason for the kick. """ + if not self.respect_role_hierarchy(ctx, user, 'kick'): + # Ensure ctx author has a higher top role than the target user + # Warning is sent to ctx by the helper method + return + notified = await self.notify_infraction( user=user, infr_type="Kick", @@ -171,6 +176,11 @@ class Moderation(Scheduler): :param reason: The reason for the ban. """ + if not self.respect_role_hierarchy(ctx, user, 'ban'): + # Ensure ctx author has a higher top role than the target user + # Warning is sent to ctx by the helper method + return + notified = await self.notify_infraction( user=user, infr_type="Ban", @@ -327,6 +337,11 @@ class Moderation(Scheduler): :param reason: The reason for the temporary ban. """ + if not self.respect_role_hierarchy(ctx, user, 'tempban'): + # Ensure ctx author has a higher top role than the target user + # Warning is sent to ctx by the helper method + return + notified = await self.notify_infraction( user=user, infr_type="Ban", @@ -420,6 +435,11 @@ class Moderation(Scheduler): :param reason: The reason for the kick. """ + if not self.respect_role_hierarchy(ctx, user, 'shadowkick'): + # Ensure ctx author has a higher top role than the target user + # Warning is sent to ctx by the helper method + return + response_object = await post_infraction(ctx, user, type="kick", reason=reason, hidden=True) if response_object is None: return @@ -456,6 +476,11 @@ class Moderation(Scheduler): :param reason: The reason for the ban. """ + if not self.respect_role_hierarchy(ctx, user, 'shadowban'): + # Ensure ctx author has a higher top role than the target user + # Warning is sent to ctx by the helper method + return + response_object = await post_infraction(ctx, user, type="ban", reason=reason, hidden=True) if response_object is None: return @@ -581,6 +606,11 @@ class Moderation(Scheduler): :param reason: The reason for the temporary ban. """ + if not self.respect_role_hierarchy(ctx, user, 'shadowtempban'): + # Ensure ctx author has a higher top role than the target user + # Warning is sent to ctx by the helper method + return + response_object = await post_infraction(ctx, user, type="ban", reason=reason, duration=duration, hidden=True) if response_object is None: return @@ -1207,18 +1237,29 @@ class Moderation(Scheduler): if User in error.converters: await ctx.send(str(error.errors[0])) - async def respect_role_hierarchy(self, guild: Guild, actor: Member, target: Member) -> bool: + async def respect_role_hierarchy(self, ctx: Context, target: Member, infraction_type: str) -> bool: """ Check if the highest role of the invoking member is less than or equal to the target member + If this check fails, a warning is sent to the invoking ctx + Implement as a method rather than a check in order to avoid having to reimplement parameter checks & conversions in a dedicated check decorater """ # Build role hierarchy - role_hierarchy = {role: rank for rank, role in enumerate(reversed(guild.roles))} + actor = ctx.author + role_hierarchy = {role: rank for rank, role in enumerate(reversed(ctx.guild.roles))} + hierarchy_check = role_hierarchy[actor.top_role] <= role_hierarchy[target.top_role] + + if not hierarchy_check: + log.info( + f"{actor.display_name} ({actor.id}) attempted to {infraction_type} " + f"{target.display_name} ({target.id}), who has a higher top role" + ) + ctx.send(f":x: {actor.mention}, you may not {infraction_type} someone with a higher top role") - return role_hierarchy[actor.top_role] <= role_hierarchy[target.top_role] + return hierarchy_check def setup(bot): |