From a9588b11be6df0d36ca44658a810c34a6d6618d7 Mon Sep 17 00:00:00 2001 From: CMDR furrycat Date: Thu, 10 Jan 2019 14:01:39 +0000 Subject: [PATCH] Allow server administrators to manage roles on their own server. --- plugin/role/role.py | 100 ++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/plugin/role/role.py b/plugin/role/role.py index acaa011..ab4bfb1 100644 --- a/plugin/role/role.py +++ b/plugin/role/role.py @@ -114,12 +114,13 @@ class Role(DBConnection): else: await cat.yelp(message.channel) - async def can_manage_roles(self, author, channel, command): + async def can_manage_roles(self, author, channel, command, server = None, hiss = True): if command in ['manage', 'unmanage']: - if bot.is_admin(author): + if bot.is_admin(author, server): return True else: - await cat.hiss(channel) + if hiss: + await cat.hiss(channel) return False log.debug('Anyone can attempt to assign or unassign roles.') return True @@ -141,75 +142,69 @@ class Role(DBConnection): yield ManagedRole(dict(row)) self.close_db() - def get_managed_role(self, role): + def get_managed_role(self, role, as_managed = False): managed_roles = list(self.get_managed_roles(role)) if managed_roles is None or not len(managed_roles): log.info('Role {} on {} is not managed'.format(role.name, role.server.name)) return None return managed_roles[0] - async def find_role(self, message, role_name, as_managed = False): + async def find_role(self, message, role_name, command = False): role = await bot.parse_role(role_name, author = message.author) if not isinstance(role, discord.role.Role): - log.info('Failed to find server for role {} a role'.format(role_name)) + log.info('Failed to find server for role {}'.format(role_name)) await bot.say(message.channel, '?') - return None + return (None, None, None) if role.is_everyone: log.info("Can't make &everyone assignable!") await bot.say(message.channel, 'everyone?') - return None + return (None, None, None) if not bot.shared_with(message.author, role): - await cat.hiss(message.channel) - return None + return (None, None, cat.hiss) managed_role = self.get_managed_role(role) if managed_role is None: - await cat.yelp(message.channel) - return None - - if as_managed: - return managed_role + return (None, None, cat.yelp) member = role.server.get_member(message.author.id) + can_manage = True + if command is not None: + can_manage = await self.can_manage_roles(message.author, message.channel, command, role.server) if managed_role.above_role_id: above_role = self.get_role_on_server(managed_role.above_role_id, role.server) if not above_role: log.warning("Can't find above role {} on server {}".format(managed_role.above_role_id, role.server.name)) - await cat.yelp(message.channel) - return None - if member.top_role <= above_role: + 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.server.name)) - await cat.hiss(message.channel) - return None + 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.server) if not below_role: log.warning("Can't find below role {} on server {}".format(managed_role.below_role_id, role.server.name)) - await cat.yelp(message.channel) - return None - if member.top_role >= below_role: + 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.server.name)) - await cat.hiss(message.channel) - return None + return (role, managed_role, cat.hiss) log.debug('Managing role {} for {}'.format(role.name, member.name)) - return role + return (role, managed_role, cat.hiss if not can_manage else None) async def list_roles(self, message, args): - result = await self.can_manage_roles(message.author, message.channel, 'manage') - if not result: - return - roles = [] hiss = False for managed_role in self.get_managed_roles(): server = client.get_server(managed_role.server_id) + result = await self.can_manage_roles(message.author, message.channel, 'manage', server, False) + if not result: + hiss = True + continue if not bot.shared_with(message.author, server): log.debug('Not showing managed role {} on server {} to user {} not on that server'.format(managed_role.role_id, server.name, message.author.name)) hiss = True @@ -232,10 +227,6 @@ class Role(DBConnection): await cat.shrug(message.channel) async def manage_role(self, message, args): - result = await self.can_manage_roles(message.author, message.channel, 'manage') - if not result: - return - if not len(args): await bot.say(message.channel, 'role?') return @@ -246,6 +237,9 @@ class Role(DBConnection): log.error("Can't find role {} to manage!".format(args[0])) await cat.yelp(message.channel) return + result = await self.can_manage_roles(message.author, message.channel, 'manage', role.server) + if not result: + return if role.is_everyone: await bot.say(message.channel, "Can't manage everyone!") return @@ -344,16 +338,18 @@ class Role(DBConnection): await cat.yelp(message.channel) async def unmanage_role(self, message, args): - result = await self.can_manage_roles(message.author, message.channel, 'unmanage') - if not result: - return - if not len(args): await bot.say(message.channel, 'role?') return - managed_role = await self.find_role(message, args[0], True) - if not managed_role: + role, managed_role, method = await self.find_role(message, args[0], 'unmanage') + if method is not None: + await method(message.channel) + if not role: + return + + result = await self.can_manage_roles(message.author, message.channel, 'unmanage', role.server) + if not result: return if not self.delete_from_table(client, 'roles', managed_role.id): @@ -361,18 +357,20 @@ class Role(DBConnection): await cat.yelp(message.channel) async def assign_role(self, message, args): - result = await self.can_manage_roles(message.author, message.channel, 'assign') - if not result: - return - if not len(args): await bot.say(message.channel, 'role?') return - role = await self.find_role(message, ' '.join(args)) + role, managed_role, method = await self.find_role(message, ' '.join(args)) + if method is not None: + await method(message.channel) if not role: return + result = await self.can_manage_roles(message.author, message.channel, 'assign', role.server) + if not result: + return + member = role.server.get_member(message.author.id) if role in member.roles: log.info('Member {} already has role {} on {}'.format(member.name, role.name, role.server.name)) @@ -387,18 +385,20 @@ class Role(DBConnection): await cat.yelp(message.channel) async def unassign_role(self, message, args): - result = await self.can_manage_roles(message.author, message.channel, 'unassign') - if not result: - return - if not len(args): await bot.say(message.channel, 'role?') return - role = await self.find_role(message, ' '.join(args)) + role, managed_role, method = await self.find_role(message, ' '.join(args)) + if method is not None: + await method(message.channel) if not role: return + result = await self.can_manage_roles(message.author, message.channel, 'unassign', role.server) + if not result: + return + member = role.server.get_member(message.author.id) if role not in member.roles: log.info("Member {} doesn't have role {} on {}".format(member.name, role.name, role.server.name)) -- 2.7.4