mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-22 02:37:57 -05:00
Permissions redesign (#2149)
API changes: - Cogs must now inherit from `commands.Cog` (see #2151 for discussion and more details) - All functions which are not decorators in the `redbot.core.checks` module are now deprecated in favour of their counterparts in `redbot.core.utils.mod`. This is to make this module more consistent and end the confusing naming convention. - `redbot.core.checks.check_overrides` function is now gone, overrideable checks can now be created with the `@commands.permissions_check` decorator - Command, Group, Cog and Context have some new attributes and methods, but they are for internal use so shouldn't concern cog creators (unless they're making a permissions cog!). - `__permissions_check_before` and `__permissions_check_after` have been replaced: A cog method named `__permissions_hook` will be evaluated as permissions hooks in the same way `__permissions_check_before` previously was. Permissions hooks can also be added/removed/verified through the new `*_permissions_hook()` methods on the bot object, and they will be verified even when permissions is unloaded. - New utility method `redbot.core.utils.chat_formatting.humanize_list` - New dependency [`schema`](https://github.com/keleshev/schema) User-facing changes: - When a `@bot_has_permissions` check fails, the bot will respond saying what permissions were actually missing. - All YAML-related `[p]permissions` subcommands now reside under the `[p]permissions acl` sub-group (tbh I still think the whole cog has too many top-level commands) - The YAML schema for these commands has been changed - A rule cannot be set as allow and deny at the same time (previously this would just default to allow) Documentation: - New documentation for `redbot.core.commands.requires` and `redbot.core.checks` modules - Renewed documentation for the permissions cog - `sphinx.ext.doctest` is now enabled Note: standard discord.py checks will still behave exactly the same way, in fact they are checked before `Requires` is looked at, so they are not overrideable. Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
import asyncio
|
||||
from datetime import timedelta
|
||||
from typing import List, Iterable, Union
|
||||
from typing import List, Iterable, Union, TYPE_CHECKING, Dict
|
||||
|
||||
import discord
|
||||
|
||||
from redbot.core import Config
|
||||
from redbot.core.bot import Red
|
||||
if TYPE_CHECKING:
|
||||
from .. import Config
|
||||
from ..bot import Red
|
||||
from ..commands import Context
|
||||
|
||||
|
||||
async def mass_purge(messages: List[discord.Message], channel: discord.TextChannel):
|
||||
@@ -87,7 +89,7 @@ def get_audit_reason(author: discord.Member, reason: str = None):
|
||||
|
||||
|
||||
async def is_allowed_by_hierarchy(
|
||||
bot: Red, settings: Config, guild: discord.Guild, mod: discord.Member, user: discord.Member
|
||||
bot: "Red", settings: "Config", guild: discord.Guild, mod: discord.Member, user: discord.Member
|
||||
):
|
||||
if not await settings.guild(guild).respect_hierarchy():
|
||||
return True
|
||||
@@ -95,7 +97,9 @@ async def is_allowed_by_hierarchy(
|
||||
return mod.top_role.position > user.top_role.position or is_special
|
||||
|
||||
|
||||
async def is_mod_or_superior(bot: Red, obj: Union[discord.Message, discord.Member, discord.Role]):
|
||||
async def is_mod_or_superior(
|
||||
bot: "Red", obj: Union[discord.Message, discord.Member, discord.Role]
|
||||
):
|
||||
"""Check if an object has mod or superior permissions.
|
||||
|
||||
If a message is passed, its author's permissions are checked. If a role is
|
||||
@@ -179,7 +183,7 @@ def strfdelta(delta: timedelta):
|
||||
|
||||
|
||||
async def is_admin_or_superior(
|
||||
bot: Red, obj: Union[discord.Message, discord.Member, discord.Role]
|
||||
bot: "Red", obj: Union[discord.Message, discord.Member, discord.Role]
|
||||
):
|
||||
"""Same as `is_mod_or_superior` except for admin permissions.
|
||||
|
||||
@@ -225,3 +229,36 @@ async def is_admin_or_superior(
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
async def check_permissions(ctx: "Context", perms: Dict[str, bool]) -> bool:
|
||||
"""Check if the author has required permissions.
|
||||
|
||||
This will always return ``True`` if the author is a bot owner, or
|
||||
has the ``administrator`` permission. If ``perms`` is empty, this
|
||||
will only check if the user is a bot owner.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ctx : Context
|
||||
The command invokation context to check.
|
||||
perms : Dict[str, bool]
|
||||
A dictionary mapping permissions to their required states.
|
||||
Valid permission names are those listed as properties of
|
||||
the `discord.Permissions` class.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
``True`` if the author has the required permissions.
|
||||
|
||||
"""
|
||||
if await ctx.bot.is_owner(ctx.author):
|
||||
return True
|
||||
elif not perms:
|
||||
return False
|
||||
resolved = ctx.channel.permissions_for(ctx.author)
|
||||
|
||||
return resolved.administrator or all(
|
||||
getattr(resolved, name, None) == value for name, value in perms.items()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user