feat(admin): Implement admin role.
This commit is contained in:
@@ -140,12 +140,13 @@ class ModerationCog(LionCog):
|
||||
)
|
||||
)
|
||||
@appcmds.rename(
|
||||
adminrole=ModerationSettings.AdminRole._display_name,
|
||||
modrole=ModerationSettings.ModRole._display_name,
|
||||
ticket_log=ModerationSettings.TicketLog._display_name,
|
||||
alert_channel=ModerationSettings.AlertChannel._display_name,
|
||||
)
|
||||
@appcmds.describe(
|
||||
modrole=ModerationSettings.ModRole._desc,
|
||||
adminrole=ModerationSettings.AdminRole._desc,
|
||||
ticket_log=ModerationSettings.TicketLog._desc,
|
||||
alert_channel=ModerationSettings.AlertChannel._desc,
|
||||
)
|
||||
@@ -154,6 +155,7 @@ class ModerationCog(LionCog):
|
||||
modrole: Optional[discord.Role] = None,
|
||||
ticket_log: Optional[discord.TextChannel] = None,
|
||||
alert_channel: Optional[discord.TextChannel] = None,
|
||||
adminrole: Optional[discord.Role] = None,
|
||||
):
|
||||
if not ctx.guild:
|
||||
return
|
||||
@@ -169,6 +171,12 @@ class ModerationCog(LionCog):
|
||||
instance = setting(ctx.guild.id, modrole.id)
|
||||
modified.append(instance)
|
||||
|
||||
if adminrole is not None:
|
||||
setting = self.settings.AdminRole
|
||||
await setting._check_value(ctx.guild.id, adminrole)
|
||||
instance = setting(ctx.guild.id, adminrole.id)
|
||||
modified.append(instance)
|
||||
|
||||
if ticket_log is not None:
|
||||
setting = self.settings.TicketLog
|
||||
await setting._check_value(ctx.guild.id, ticket_log)
|
||||
|
||||
@@ -148,7 +148,7 @@ class ModerationSettings(SettingGroup):
|
||||
if value:
|
||||
resp = t(_p(
|
||||
'guildset:mod_role|set_response:set',
|
||||
"Members with the {role} will be considered moderators."
|
||||
"Members with {role} will be considered moderators."
|
||||
)).format(role=value.mention)
|
||||
else:
|
||||
resp = t(_p(
|
||||
@@ -167,3 +167,46 @@ class ModerationSettings(SettingGroup):
|
||||
'guildset:mod_role|formatted:unset',
|
||||
"Not Set."
|
||||
))
|
||||
|
||||
class AdminRole(ModelData, RoleSetting):
|
||||
setting_id = "admin_role"
|
||||
_event = 'guildset_admin_role'
|
||||
|
||||
_display_name = _p('guildset:admin_role', "admin_role")
|
||||
_desc = _p(
|
||||
'guildset:admin_role|desc',
|
||||
"Server role allowing access to all administrator level functionality in Leo."
|
||||
)
|
||||
_long_desc = _p(
|
||||
'guildset:admin_role|long_desc',
|
||||
"Members with this role are considered to be server administrators, "
|
||||
"allowing them to use all of my interfaces and commands, "
|
||||
"except for managing roles that are above them in the role hierachy. "
|
||||
"This setting allows giving members administrator-level permissions "
|
||||
"over my systems, without actually giving the members admin server permissions. "
|
||||
"Note that the role will also need to be given permission to see the commands "
|
||||
"through the Discord server integrations interface."
|
||||
)
|
||||
_accepts = _p(
|
||||
'guildset:admin_role|accepts',
|
||||
"Admin role name or id."
|
||||
)
|
||||
|
||||
_model = CoreData.Guild
|
||||
_column = CoreData.Guild.admin_role.name
|
||||
|
||||
@property
|
||||
def update_message(self) -> str:
|
||||
t = ctx_translator.get().t
|
||||
value = self.value
|
||||
if value:
|
||||
resp = t(_p(
|
||||
'guildset:admin_role|set_response:set',
|
||||
"Members with {role} will now be considered admins, and have access to my full interface."
|
||||
)).format(role=value.mention)
|
||||
else:
|
||||
resp = t(_p(
|
||||
'guildset:admin_role|set_response:unset',
|
||||
"The admin role has been unset. Only members with administrator permissions will be considered admins."
|
||||
))
|
||||
return resp
|
||||
|
||||
@@ -18,9 +18,10 @@ _p = babel._p
|
||||
|
||||
class ModerationSettingUI(ConfigUI):
|
||||
setting_classes = (
|
||||
ModerationSettings.ModRole,
|
||||
ModerationSettings.AdminRole,
|
||||
ModerationSettings.TicketLog,
|
||||
ModerationSettings.AlertChannel,
|
||||
ModerationSettings.ModRole,
|
||||
)
|
||||
|
||||
def __init__(self, bot: LionBot, guildid: int, channelid, **kwargs):
|
||||
@@ -103,6 +104,31 @@ class ModerationSettingUI(ConfigUI):
|
||||
"Select Moderator Role"
|
||||
))
|
||||
|
||||
# Admin Role Selector
|
||||
@select(
|
||||
cls=RoleSelect,
|
||||
placeholder="ADMINROLE_MENU_PLACEHOLDER",
|
||||
min_values=0, max_values=1
|
||||
)
|
||||
async def adminrole_menu(self, selection: discord.Interaction, selected: RoleSelect):
|
||||
"""
|
||||
Single role selector for the `admin_role` setting.
|
||||
"""
|
||||
await selection.response.defer(thinking=True, ephemeral=True)
|
||||
|
||||
setting = self.get_instance(ModerationSettings.AdminRole)
|
||||
setting.value = selected.values[0] if selected.values else None
|
||||
await setting.write()
|
||||
await selection.delete_original_response()
|
||||
|
||||
async def adminrole_menu_refresh(self):
|
||||
menu = self.adminrole_menu
|
||||
t = self.bot.translator.t
|
||||
menu.placeholder = t(_p(
|
||||
'ui:moderation_config|menu:adminrole|placeholder',
|
||||
"Select Admin Role"
|
||||
))
|
||||
|
||||
# ----- UI Flow -----
|
||||
async def make_message(self) -> MessageArgs:
|
||||
t = self.bot.translator.t
|
||||
@@ -133,13 +159,15 @@ class ModerationSettingUI(ConfigUI):
|
||||
self.ticket_log_menu_refresh(),
|
||||
self.alert_channel_menu_refresh(),
|
||||
self.modrole_menu_refresh(),
|
||||
self.adminrole_menu_refresh(),
|
||||
)
|
||||
await asyncio.gather(*component_refresh)
|
||||
|
||||
self.set_layout(
|
||||
(self.adminrole_menu,),
|
||||
(self.modrole_menu,),
|
||||
(self.ticket_log_menu,),
|
||||
(self.alert_channel_menu,),
|
||||
(self.modrole_menu,),
|
||||
(self.edit_button, self.reset_button, self.close_button,)
|
||||
)
|
||||
|
||||
|
||||
24
src/wards.py
24
src/wards.py
@@ -26,15 +26,31 @@ async def high_management(bot: LionBot, member: discord.Member, guild: discord.G
|
||||
return True
|
||||
if await sys_admin(bot, member.id):
|
||||
return True
|
||||
return member.guild_permissions.administrator
|
||||
if member.guild_permissions.administrator:
|
||||
return True
|
||||
|
||||
lguild = await bot.core.lions.fetch_guild(guild.id)
|
||||
adminrole = lguild.data.admin_role
|
||||
roleids = [role.id for role in member.roles]
|
||||
if (adminrole and adminrole in roleids):
|
||||
return True
|
||||
|
||||
async def low_management(bot: LionBot, member: discord.Member, guild: discord.Guild):
|
||||
"""
|
||||
Low management is currently identified with moderator permissions.
|
||||
"""
|
||||
if not guild:
|
||||
return True
|
||||
if await high_management(bot, member, guild):
|
||||
return True
|
||||
return member.guild_permissions.manage_guild
|
||||
if member.guild_permissions.manage_guild:
|
||||
return True
|
||||
|
||||
lguild = await bot.core.lions.fetch_guild(guild.id)
|
||||
modrole = lguild.data.mod_role
|
||||
roleids = [role.id for role in member.roles]
|
||||
if (modrole and modrole in roleids):
|
||||
return True
|
||||
|
||||
|
||||
# Interaction Wards, also return True/False
|
||||
@@ -96,7 +112,7 @@ async def high_management_ward(ctx: LionContext) -> bool:
|
||||
raise CheckFailure(
|
||||
ctx.bot.translator.t(_p(
|
||||
'ward:high_management|failed',
|
||||
"You must have the `ADMINISTRATOR` permission in this server to do this!"
|
||||
"You must have the `ADMINISTRATOR` permission or the configured `admin_role` to do this!"
|
||||
))
|
||||
)
|
||||
|
||||
@@ -112,7 +128,7 @@ async def low_management_ward(ctx: LionContext) -> bool:
|
||||
raise CheckFailure(
|
||||
ctx.bot.translator.t(_p(
|
||||
'ward:low_management|failed',
|
||||
"You must have the `MANAGE_GUILD` permission in this server to do this!"
|
||||
"You must have the `MANAGE_GUILD` permission or the configured `mod_role` to do this!"
|
||||
))
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user