aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar sco1 <[email protected]>2019-01-09 16:40:54 -0500
committerGravatar sco1 <[email protected]>2019-01-09 16:40:54 -0500
commit646a892348af4cf99fe2b08d6a1688e0aff56d3b (patch)
treeb142e33b094e1b4d0146533a07517a683a1b048b
parentAdd 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.py47
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):