[Permissions] Prevent guild owner lockouts (#3955)

* [Permissions] Prevent guild owner lockouts

  - Guild owners will always be able to access the guild configuration
  commands in permissions
  - This includes `permissions explain` and `permissions canrun` as
  informational tools useful for ensuing a correct configuration

  resolves #3107

* minor nitpicking over ordering consistency

* a single new line for style compliance

* Fix a typo + alphabet went wrong

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
This commit is contained in:
Michael H 2020-06-11 18:31:41 -04:00 committed by GitHub
parent 593079dbbb
commit 6c048fad01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -81,6 +81,11 @@ __version__ = "1.0.0"
class Permissions(commands.Cog): class Permissions(commands.Cog):
"""Customise permissions for commands and cogs.""" """Customise permissions for commands and cogs."""
# The command groups in this cog should never directly take any configuration actions
# These should be delegated to specific commands so that it remains trivial
# to prevent the guild owner from ever locking themselves out
# see ``Permissions.__permissions_hook`` for more details
def __init__(self, bot: Red): def __init__(self, bot: Red):
super().__init__() super().__init__()
self.bot = bot self.bot = bot
@ -108,6 +113,44 @@ class Permissions(commands.Cog):
self.config.init_custom(COMMAND, 1) self.config.init_custom(COMMAND, 1)
self.config.register_custom(COMMAND) self.config.register_custom(COMMAND)
async def __permissions_hook(self, ctx: commands.Context) -> Optional[bool]:
"""
Purpose of this hook is to prevent guild owner lockouts of permissions specifically
without modifying rule behavior in any other case.
Guild owner is not special cased outside of these configuration commands
to allow guild owner to restrict the use of potentially damaging commands
such as, but not limited to, cleanup to specific channels.
Leaving the configuration commands special cased allows guild owners to fix
any misconfigurations.
"""
if ctx.guild:
if ctx.author == ctx.guild.owner:
# the below should contain all commands from this cog
# which configure or are useful to the
# configuration of guild permissions and should never
# have a potential impact on global configuration
# as well as the parent groups
if ctx.command in (
self.permissions, # main top level group
self.permissions_acl, # acl group
self.permissions_acl_getguild,
self.permissions_acl_setguild,
self.permissions_acl_updateguild,
self.permissions_addguildrule,
self.permissions_clearguildrules,
self.permissions_removeguildrule,
self.permissions_setdefaultguildrule,
self.permissions_canrun,
self.permissions_explain,
):
return True # permission rules will be ignored at this case
# this delegates to permissions rules, do not change to False which would deny
return None
@commands.group() @commands.group()
async def permissions(self, ctx: commands.Context): async def permissions(self, ctx: commands.Context):
"""Command permission management tools.""" """Command permission management tools."""