mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-07 03:38:53 -05:00
[Mod] Added optional role hierarchy check
Toggleable with [p]modset hierarchy This enables a role hierarchy check before all moderation actions. If the mod doesn't have a role superior to the user's top role the action will be denied. Server owner and bot owner are exempt from the check.
This commit is contained in:
parent
3d9a157516
commit
7c192b3668
88
cogs/mod.py
88
cogs/mod.py
@ -31,9 +31,10 @@ ACTIONS_CASES = {
|
||||
}
|
||||
|
||||
default_settings = {
|
||||
"ban_mention_spam" : False,
|
||||
"delete_repeats" : False,
|
||||
"mod-log" : None
|
||||
"ban_mention_spam" : False,
|
||||
"delete_repeats" : False,
|
||||
"mod-log" : None,
|
||||
"respect_hierarchy" : False
|
||||
}
|
||||
|
||||
|
||||
@ -111,14 +112,18 @@ class Mod:
|
||||
await send_cmd_help(ctx)
|
||||
roles = settings.get_server(server).copy()
|
||||
_settings = {**self.settings[server.id], **roles}
|
||||
if "respect_hierarchy" not in _settings:
|
||||
_settings["respect_hierarchy"] = default_settings["respect_hierarchy"]
|
||||
if "delete_delay" not in _settings:
|
||||
_settings["delete_delay"] = -1
|
||||
_settings["delete_delay"] = "Disabled"
|
||||
|
||||
msg = ("Admin role: {ADMIN_ROLE}\n"
|
||||
"Mod role: {MOD_ROLE}\n"
|
||||
"Mod-log: {mod-log}\n"
|
||||
"Delete repeats: {delete_repeats}\n"
|
||||
"Ban mention spam: {ban_mention_spam}\n"
|
||||
"Delete delay: {delete_delay}\n"
|
||||
"Respects hierarchy: {respect_hierarchy}"
|
||||
"".format(**_settings))
|
||||
await self.bot.say(box(msg))
|
||||
|
||||
@ -234,7 +239,7 @@ class Mod:
|
||||
@modset.command(pass_context=True, no_pm=True, name='cases')
|
||||
async def set_cases(self, ctx, action: str = None, enabled: bool = None):
|
||||
"""Enables or disables case creation for each type of mod action
|
||||
|
||||
|
||||
Enabled can be 'on' or 'off'"""
|
||||
server = ctx.message.server
|
||||
|
||||
@ -278,6 +283,23 @@ class Mod:
|
||||
)
|
||||
await self.bot.say(msg)
|
||||
|
||||
@modset.command(pass_context=True, no_pm=True)
|
||||
@checks.serverowner_or_permissions()
|
||||
async def hierarchy(self, ctx):
|
||||
"""Toggles role hierarchy check for mods / admins"""
|
||||
server = ctx.message.server
|
||||
toggled = self.settings[server.id].get("respect_hierarchy",
|
||||
default_settings["respect_hierarchy"])
|
||||
if not toggled:
|
||||
self.settings[server.id]["respect_hierarchy"] = True
|
||||
await self.bot.say("Role hierarchy will be checked when "
|
||||
"moderation commands are issued.")
|
||||
else:
|
||||
self.settings[server.id]["respect_hierarchy"] = False
|
||||
await self.bot.say("Role hierarchy will be ignored when "
|
||||
"moderation commands are issued.")
|
||||
dataIO.save_json("data/mod/settings.json", self.settings)
|
||||
|
||||
@commands.command(no_pm=True, pass_context=True)
|
||||
@checks.admin_or_permissions(kick_members=True)
|
||||
async def kick(self, ctx, user: discord.Member, *, reason: str = None):
|
||||
@ -289,6 +311,11 @@ class Mod:
|
||||
await self.bot.say("I cannot let you do that. Self-harm is "
|
||||
"bad \N{PENSIVE FACE}")
|
||||
return
|
||||
elif not self.is_allowed_by_hierarchy(server, author, user):
|
||||
await self.bot.say("I cannot let you do that. You are "
|
||||
"not higher than the user in the role "
|
||||
"hierarchy.")
|
||||
return
|
||||
|
||||
try:
|
||||
await self.bot.kick(user)
|
||||
@ -319,6 +346,11 @@ class Mod:
|
||||
await self.bot.say("I cannot let you do that. Self-harm is "
|
||||
"bad \N{PENSIVE FACE}")
|
||||
return
|
||||
elif not self.is_allowed_by_hierarchy(server, author, user):
|
||||
await self.bot.say("I cannot let you do that. You are "
|
||||
"not higher than the user in the role "
|
||||
"hierarchy.")
|
||||
return
|
||||
|
||||
if days:
|
||||
if days.isdigit():
|
||||
@ -365,6 +397,11 @@ class Mod:
|
||||
await self.bot.say("I cannot let you do that. Self-harm is "
|
||||
"bad \N{PENSIVE FACE}")
|
||||
return
|
||||
elif not self.is_allowed_by_hierarchy(server, author, user):
|
||||
await self.bot.say("I cannot let you do that. You are "
|
||||
"not higher than the user in the role "
|
||||
"hierarchy.")
|
||||
return
|
||||
|
||||
try:
|
||||
invite = await self.bot.create_invite(server, max_age=3600*24)
|
||||
@ -433,10 +470,17 @@ class Mod:
|
||||
channel = ctx.message.channel
|
||||
server = ctx.message.server
|
||||
overwrites = channel.overwrites_for(user)
|
||||
|
||||
if overwrites.send_messages is False:
|
||||
await self.bot.say("That user can't send messages in this "
|
||||
"channel.")
|
||||
return
|
||||
elif not self.is_allowed_by_hierarchy(server, author, user):
|
||||
await self.bot.say("I cannot let you do that. You are "
|
||||
"not higher than the user in the role "
|
||||
"hierarchy.")
|
||||
return
|
||||
|
||||
self._perms_cache[user.id][channel.id] = overwrites.send_messages
|
||||
overwrites.send_messages = False
|
||||
try:
|
||||
@ -461,6 +505,13 @@ class Mod:
|
||||
"""Mutes user in the server"""
|
||||
author = ctx.message.author
|
||||
server = ctx.message.server
|
||||
|
||||
if not self.is_allowed_by_hierarchy(server, author, user):
|
||||
await self.bot.say("I cannot let you do that. You are "
|
||||
"not higher than the user in the role "
|
||||
"hierarchy.")
|
||||
return
|
||||
|
||||
register = {}
|
||||
for channel in server.channels:
|
||||
if channel.type != discord.ChannelType.text:
|
||||
@ -506,11 +557,20 @@ class Mod:
|
||||
async def channel_unmute(self, ctx, user : discord.Member):
|
||||
"""Unmutes user in the current channel"""
|
||||
channel = ctx.message.channel
|
||||
author = ctx.message.author
|
||||
server = ctx.message.server
|
||||
overwrites = channel.overwrites_for(user)
|
||||
|
||||
if overwrites.send_messages:
|
||||
await self.bot.say("That user doesn't seem to be muted "
|
||||
"in this channel.")
|
||||
return
|
||||
elif not self.is_allowed_by_hierarchy(server, author, user):
|
||||
await self.bot.say("I cannot let you do that. You are "
|
||||
"not higher than the user in the role "
|
||||
"hierarchy.")
|
||||
return
|
||||
|
||||
if user.id in self._perms_cache:
|
||||
old_value = self._perms_cache[user.id].get(channel.id)
|
||||
else:
|
||||
@ -542,11 +602,19 @@ class Mod:
|
||||
async def server_unmute(self, ctx, user : discord.Member):
|
||||
"""Unmutes user in the server"""
|
||||
server = ctx.message.server
|
||||
author = ctx.message.author
|
||||
|
||||
if user.id not in self._perms_cache:
|
||||
await self.bot.say("That user doesn't seem to have been muted with {0}mute commands. "
|
||||
"Unmute them in the channels you want with `{0}unmute <user>`"
|
||||
"".format(ctx.prefix))
|
||||
return
|
||||
elif not self.is_allowed_by_hierarchy(server, author, user):
|
||||
await self.bot.say("I cannot let you do that. You are "
|
||||
"not higher than the user in the role "
|
||||
"hierarchy.")
|
||||
return
|
||||
|
||||
for channel in server.channels:
|
||||
if channel.type != discord.ChannelType.text:
|
||||
continue
|
||||
@ -1306,6 +1374,16 @@ class Mod:
|
||||
else:
|
||||
return False
|
||||
|
||||
def is_allowed_by_hierarchy(self, server, mod, user):
|
||||
toggled = self.settings[server.id].get("respect_hierarchy",
|
||||
default_settings["respect_hierarchy"])
|
||||
is_special = mod == server.owner or mod.id == self.bot.settings.owner
|
||||
|
||||
if not toggled:
|
||||
return True
|
||||
else:
|
||||
return mod.top_role.position > user.top_role.position or is_special
|
||||
|
||||
async def new_case(self, server, *, action, mod=None, user, reason=None, until=None, channel=None):
|
||||
action_type = action.lower() + "_cases"
|
||||
if not self.settings[server.id].get(action_type, default_settings[action_type]):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user