Reject bad perm kwargs in check decorators (#2289)

Also fixed a misspelled kwarg in reports.

Also now raising TypeError for an empty `@checks.has_permissions()` decorator.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
Toby Harradine 2018-11-05 15:07:56 +11:00 committed by GitHub
parent 92dbd14006
commit 99bbde7be9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 1 deletions

View File

@ -316,7 +316,7 @@ class Reports(commands.Cog):
self.tunnel_store[k]["msgs"] = msgs
@commands.guild_only()
@checks.mod_or_permissions(manage_members=True)
@checks.mod_or_permissions(manage_roles=True)
@report.command(name="interact")
async def response(self, ctx, ticket_number: int):
"""Open a message tunnel.

View File

@ -281,12 +281,14 @@ class Requires:
if isinstance(user_perms, dict):
self.user_perms: Optional[discord.Permissions] = discord.Permissions.none()
_validate_perms_dict(user_perms)
self.user_perms.update(**user_perms)
else:
self.user_perms = user_perms
if isinstance(bot_perms, dict):
self.bot_perms: discord.Permissions = discord.Permissions.none()
_validate_perms_dict(bot_perms)
self.bot_perms.update(**bot_perms)
else:
self.bot_perms = bot_perms
@ -311,6 +313,7 @@ class Requires:
if user_perms is None:
func.requires.user_perms = None
else:
_validate_perms_dict(user_perms)
func.requires.user_perms.update(**user_perms)
return func
@ -584,6 +587,7 @@ def bot_has_permissions(**perms: bool):
if asyncio.iscoroutinefunction(func):
func.__requires_bot_perms__ = perms
else:
_validate_perms_dict(perms)
func.requires.bot_perms.update(**perms)
return func
@ -595,6 +599,8 @@ def has_permissions(**perms: bool):
This check can be overridden by rules.
"""
if perms is None:
raise TypeError("Must provide at least one keyword argument to has_permissions")
return Requires.get_decorator(None, perms)
@ -666,3 +672,20 @@ class _IntKeyDict(Dict[int, _T]):
if not isinstance(key, int):
raise TypeError("Keys must be of type `int`")
return super().__setitem__(key, value)
def _validate_perms_dict(perms: Dict[str, bool]) -> None:
for perm, value in perms.items():
try:
attr = getattr(discord.Permissions, perm)
except AttributeError:
attr = None
if attr is None or not isinstance(attr, property):
# We reject invalid permissions
raise TypeError(f"Unknown permission name '{perm}'")
if value is not True:
# We reject any permission not specified as 'True', since this is the only value which
# makes practical sense.
raise TypeError(f"Permission {perm} may only be specified as 'True', not {value}")