From: CMDR furrycat Date: Tue, 11 May 2021 07:30:19 +0000 (+0200) Subject: Tweak role permissions X-Git-Url: http://git.furryclan.net/?a=commitdiff_plain;h=f9a959cf4d50c02e0a18bbf2b9fb6ed2f2ea71d9;p=furrycat%2Fcatbot.git Tweak role permissions Only list roles to users who have permission to assign them. Show above and below roles in list output. --- diff --git a/plugins/role/__init__.py b/plugins/role/__init__.py index cd44f45..ddfcc8d 100644 --- a/plugins/role/__init__.py +++ b/plugins/role/__init__.py @@ -188,7 +188,30 @@ class Role(DBConnection): return None return managed_roles[0] - async def find_role(self, role_name, message = None, member = None, server = None, command = False): + def complain_if_cannot_assign_role(self, member, managed_role, role, verb = None): + if managed_role.above_role_id: + above_role = self.get_role_on_server(managed_role.above_role_id, role.guild) + if not above_role: + log.warning("Can't find above role {} on server {}".format(managed_role.above_role_id, role.guild.name)) + return (None, None, cat.yelp) + if member.top_role <= above_role: + if member.top_role < above_role or not managed_role.above_inclusive: + log.info('Member {} needs at least role {} to {} {} on {}'.format(member.name, above_role.name, verb, role.name, role.guild.name)) + return (role, managed_role, cat.hiss) + + if managed_role.below_role_id: + below_role = self.get_role_on_server(managed_role.below_role_id, role.guild) + if not below_role: + log.warning("Can't find below role {} on server {}".format(managed_role.below_role_id, role.guild.name)) + return (None, None, cat.yelp) + if member.top_role >= below_role: + if member.top_role > below_role or not managed_role.below_inclusive: + log.info('Member {} needs at least role {} to {} {} on {}'.format(member.name, below_role.name, verb, role.name, role.guild.name)) + return (role, managed_role, cat.hiss) + + return (role, managed_role, None) + + async def find_role(self, role_name, message = None, member = None, server = None, command = None): author = message.author if message is not None else member role = await bot.parse_role(role_name, author = author) if not isinstance(role, discord.role.Role): @@ -216,32 +239,17 @@ class Role(DBConnection): if command is not None: can_manage = await self.can_manage_roles(author, message.channel if message is not None else None, command, role.guild) - if managed_role.above_role_id: - above_role = self.get_role_on_server(managed_role.above_role_id, role.guild) - if not above_role: - log.warning("Can't find above role {} on server {}".format(managed_role.above_role_id, role.guild.name)) - return (None, None, cat.yelp) - if command is None and member.top_role <= above_role: - if member.top_role < above_role or not above_inclusive: - log.info('Member {} needs at least role {} to assign {} on {}'.format(member.name, above_role.name, role.name, role.guild.name)) - return (role, managed_role, cat.hiss) - - if managed_role.below_role_id: - below_role = self.get_role_on_server(managed_role.below_role_id, role.guild) - if not below_role: - log.warning("Can't find below role {} on server {}".format(managed_role.below_role_id, role.guild.name)) - return (None, None, cat.yelp) - if command is None and member.top_role >= below_role: - if member.top_role > below_role or not below_inclusive: - log.info('Member {} needs at least role {} to assign {} on {}'.format(member.name, below_role.name, role.name, role.guild.name)) - return (role, managed_role, cat.hiss) + complaint = self.complain_if_cannot_assign_role(member, managed_role, role, command or 'assign') + if complaint[2]: + return complaint log.debug('Managing role {} for {}'.format(role.name, member.name)) return (role, managed_role, cat.hiss if not can_manage else None) async def list_roles(self, message, args): - roles = [] hiss = False + server_admin = {} + output = [] for managed_role in self.get_managed_roles(): server = bot.get_server(managed_role.server_id) result = await self.can_manage_roles(message.author, message.channel, 'list', server, False) @@ -260,10 +268,32 @@ class Role(DBConnection): if not role: log.warning("Can't find role {} on server {}".format(managed_role.role_id, server.name)) continue - roles.append(role) + is_admin = server_admin.get(managed_role.server_id) + if is_admin is None: + is_admin = await self.can_manage_roles(message.author, message.channel, 'manage', server, False) + server_admin[managed_role.server_id] = is_admin + parts = ['"{}" on {}'.format(role.name, role.guild.name) if bot.is_private(message.channel) else role.name] + if is_admin: + above_role = None + below_role = None + if managed_role.above_role_id: + above_role = self.get_role_on_server(managed_role.above_role_id, role.guild) + if managed_role.below_role_id: + below_role = self.get_role_on_server(managed_role.below_role_id, role.guild) + if above_role and below_role and above_role.id == below_role.id: + parts.append('_only_ {}'.format(above_role.name)) + elif above_role: + parts.append('_above_ {}'.format(above_role.name)) + elif below_role: + parts.append('_below_ {}'.format(below_role.name)) + else: + complaint = self.complain_if_cannot_assign_role(server.get_member(message.author.id), managed_role, role, 'list') + if complaint[2]: + continue + output.append(' '.join(parts)) - if len(roles): - await bot.say_many(message.channel, ['"{}" on {}'.format(role.name, role.guild.name) if bot.is_private(message.channel) else role.name for role in roles]) + if len(output): + await bot.say_many(message.channel, output) elif hiss: await cat.hiss(message.channel) else: @@ -388,7 +418,8 @@ class Role(DBConnection): role, managed_role, method = await self.find_role(' '.join(args), message = message, command = 'unmanage') if method is not None: await method(message.channel) - if not role: + return + elif not role: return result = await self.can_manage_roles(message.author, message.channel, 'unmanage', role.guild) @@ -407,7 +438,8 @@ class Role(DBConnection): role, managed_role, method = await self.find_role(' '.join(args), message = message) if method is not None: await method(message.channel) - if not role: + return + elif not role: return result = await self.can_manage_roles(message.author, message.channel, 'assign', role.guild) @@ -435,6 +467,7 @@ class Role(DBConnection): role, managed_role, method = await self.find_role(' '.join(args), message = message) if method is not None: await method(message.channel) + return if not role: return