Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
92cd689
Implement slash command permissions.
benwoo1110 Apr 21, 2021
0d6a255
Support get permission id type based on class type.
benwoo1110 Apr 21, 2021
4e982cb
Implement permission support for non-cog commands.
benwoo1110 Apr 21, 2021
00a11ba
Add support for default permissions.
benwoo1110 Apr 21, 2021
446cac6
Apply permissions based on applicable guilds specified.
benwoo1110 Apr 21, 2021
2054983
Rethink permission applicable guilds logic.
benwoo1110 Apr 21, 2021
9a23efd
Add option to delete perms from old guilds.
benwoo1110 Apr 21, 2021
e9f5570
Using logging instead of print.
benwoo1110 Apr 21, 2021
09003c0
Check if perms not registered before attempting to register.
benwoo1110 Apr 21, 2021
4249972
Add some debug print for testing.
benwoo1110 Apr 21, 2021
8799e97
Properly check if permissions has already been registered.
benwoo1110 Apr 21, 2021
5301fde
Forgot to pass permission dict as kwargs.
benwoo1110 Apr 21, 2021
439db8d
Fix logic issue with permission data matching checks.
benwoo1110 Apr 21, 2021
36f73e5
Fix wrong perm variable used in for loop.
benwoo1110 Apr 21, 2021
513c4d9
Use logger instead of print for debug messages.
benwoo1110 Apr 21, 2021
e8cdb4d
Fix some formatting issues.
benwoo1110 Apr 21, 2021
2de3385
Add docs to method and some cleanup.
benwoo1110 Apr 21, 2021
b46f348
Rename to applicable_guilds.
benwoo1110 Apr 21, 2021
70cc7f3
Apply some suggested code changes.
benwoo1110 Apr 21, 2021
9ee4b4d
Empty list instead of None for api_permissions.
benwoo1110 Apr 21, 2021
d927a26
Make permissions use a dict structure as suggested.
benwoo1110 Apr 21, 2021
ed7f8e8
Update method names to align with previous change.
benwoo1110 Apr 21, 2021
bee61a9
Implement generate_permissions function for easy permission creation.
benwoo1110 Apr 21, 2021
899534c
Flatten command_dict to minimize breaking changes.
benwoo1110 Apr 22, 2021
930bc01
Add coroutine for permissions requests.
benwoo1110 Apr 22, 2021
9a9902d
Fix issues with command syncing.
benwoo1110 Apr 22, 2021
315d307
Add sub command support.
benwoo1110 Apr 25, 2021
55bccd0
Add permission decorator.
benwoo1110 Apr 25, 2021
86ea0d3
Update discord_slash/utils/manage_commands.py
benwoo1110 Apr 26, 2021
ee61eff
Update discord_slash/utils/manage_commands.py
benwoo1110 Apr 26, 2021
6a62a14
Add link to discord api docs.
benwoo1110 Apr 26, 2021
acd2eb8
Merge branch 'permissions' of https://github.com/benwoo1110/discord-p…
benwoo1110 Apr 26, 2021
93b8865
Sub commands should not have permissions things.
benwoo1110 Apr 26, 2021
7815254
Add PermissionData class to store each ApplicationCommandPermissions.
benwoo1110 Apr 26, 2021
da60405
Merge permissions for subcommands.
benwoo1110 Apr 26, 2021
7e16da9
Rework CommandObject class inheritance.
benwoo1110 Apr 26, 2021
5bb9245
Add missing documentation on some functions.
benwoo1110 Apr 28, 2021
dca61e9
Add wiki guide for permissions.
benwoo1110 Apr 28, 2021
9cf6fa7
Updated docs as per suggestion.
benwoo1110 Apr 28, 2021
22e9e86
Add support for Cog subcomand.
benwoo1110 May 2, 2021
8001dec
Fix BasecommandObject attributes.
benwoo1110 May 3, 2021
cc63233
Merge branch 'permissions' of https://github.com/benwoo1110/discord-p…
benwoo1110 May 3, 2021
602fd6b
Fix a small typo.
benwoo1110 May 3, 2021
09a5d0d
Fix more typos.
benwoo1110 May 3, 2021
333b803
Update docs/gettingstarted.rst
benwoo1110 May 3, 2021
c725978
Update documentation.
benwoo1110 May 3, 2021
0b1449e
Rename to BaseCommandObject
benwoo1110 May 4, 2021
7c9550c
Apply suggestions from code review
benwoo1110 May 8, 2021
3526d6f
Add note on @everyone permission.
benwoo1110 May 8, 2021
8c39cec
Remove duplicate ids when on create_multi_ids_permission.
benwoo1110 May 8, 2021
89d38c0
Add guild_id parameter to GuildPermissionsData.
benwoo1110 May 8, 2021
4fd02ff
Update discord_slash/utils/manage_commands.py
benwoo1110 May 11, 2021
d1b2709
Update discord_slash/client.py
benwoo1110 May 11, 2021
24138fa
Update docs/gettingstarted.rst
benwoo1110 May 11, 2021
77e6a71
Fix minor issues when creating permissions with SlashCommandPermissio…
benwoo1110 May 11, 2021
fec21a6
Dont need to cast, should already be int.
benwoo1110 May 11, 2021
d0ab6c2
Add abit more logging on permission map.
benwoo1110 May 11, 2021
3a15ee4
fix logging issues.
benwoo1110 May 12, 2021
a650d65
Improving logging for sync_commands.
benwoo1110 May 12, 2021
323db71
Add docs on @slash.permission decorator.
benwoo1110 May 12, 2021
95f11b0
Do not need to copy guild_ids list there.
benwoo1110 May 12, 2021
63bef90
Fix issue with guild_ids is cog subcommand.
benwoo1110 May 12, 2021
54e79e7
Add support for merge permissions by cog subcommand.
benwoo1110 May 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 171 additions & 31 deletions discord_slash/client.py

Large diffs are not rendered by default.

32 changes: 29 additions & 3 deletions discord_slash/cog_ext.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import typing
import inspect
from .model import CogCommandObject, CogSubcommandObject
from .model import CogBaseCommandObject, CogSubcommandObject
from .utils import manage_commands


Expand All @@ -9,6 +9,8 @@ def cog_slash(*,
description: str = None,
guild_ids: typing.List[int] = None,
options: typing.List[dict] = None,
default_permission: bool = True,
permissions: dict = None,
connector: dict = None):
"""
Decorator for Cog to add slash command.\n
Expand All @@ -34,6 +36,10 @@ async def ping(self, ctx: SlashContext):
:type guild_ids: List[int]
:param options: Options of the slash command. This will affect ``auto_convert`` and command data at Discord API. Default ``None``.
:type options: List[dict]
:param default_permission: Sets if users have permission to run slash command by default, when no permissions are set. Default ``True``.
:type default_permission: bool
:param permissions: Permission requirements of the slash command. Default ``None``.
:type permissions: dict
:param connector: Kwargs connector for the command. Default ``None``.
:type connector: dict
"""
Expand All @@ -49,10 +55,12 @@ def wrapper(cmd):
"description": desc,
"guild_ids": guild_ids,
"api_options": opts,
"default_permission": default_permission,
"api_permissions": permissions,
"connector": connector,
"has_subcommands": False
}
return CogCommandObject(name or cmd.__name__, _cmd)
return CogBaseCommandObject(name or cmd.__name__, _cmd)
return wrapper


Expand All @@ -63,6 +71,8 @@ def cog_subcommand(*,
description: str = None,
base_description: str = None,
base_desc: str = None,
base_default_permission: bool = True,
base_permissions: dict = None,
subcommand_group_description: str = None,
sub_group_desc: str = None,
guild_ids: typing.List[int] = None,
Expand Down Expand Up @@ -95,6 +105,10 @@ async def group_say(self, ctx: SlashContext, text: str):
:param base_description: Description of the base command. Default ``None``.
:type base_description: str
:param base_desc: Alias of ``base_description``.
:param base_default_permission: Sets if users have permission to run slash command by default, when no permissions are set. Default ``True``.
:type base_default_permission: bool
:param base_permissions: Permission requirements of the slash command. Default ``None``.
:type base_permissions: dict
:param subcommand_group_description: Description of the subcommand_group. Default ``None``.
:type subcommand_group_description: str
:param sub_group_desc: Alias of ``subcommand_group_description``.
Expand All @@ -107,6 +121,7 @@ async def group_say(self, ctx: SlashContext, text: str):
"""
base_description = base_description or base_desc
subcommand_group_description = subcommand_group_description or sub_group_desc
guild_ids = guild_ids if guild_ids else []

def wrapper(cmd):
desc = description or inspect.getdoc(cmd)
Expand All @@ -115,6 +130,17 @@ def wrapper(cmd):
else:
opts = options

_cmd = {
"func": None,
"description": base_description,
"guild_ids": guild_ids.copy(),
"api_options": [],
"default_permission": base_default_permission,
"api_permissions": base_permissions,
"connector": {},
"has_subcommands": True
}

_sub = {
"func": cmd,
"name": name or cmd.__name__,
Expand All @@ -125,5 +151,5 @@ def wrapper(cmd):
"api_options": opts,
"connector": connector
}
return CogSubcommandObject(_sub, base, name or cmd.__name__, subcommand_group)
return CogSubcommandObject(base, _cmd, subcommand_group, name or cmd.__name__, _sub)
return wrapper
19 changes: 18 additions & 1 deletion discord_slash/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ def get_all_commands(self, guild_id=None):
"""
return self.command_request(method="GET", guild_id=guild_id)

def get_all_guild_commands_permissions(self, guild_id):
"""
Sends a slash command get request to Discord API for all permissions of a guild.

:param guild_id: ID of the target guild to get registered command permissions of.
:return: JSON Response of the request.
"""
return self.command_request(method="GET", guild_id=guild_id, url_ending="/permissions")

def update_guild_commands_permissions(self, guild_id, perms_dict):
"""
Sends a slash command put request to the Discord API for setting all command permissions of a guild.

:param guild_id: ID of the target guild to register command permissions.
:return: JSON Response of the request.
"""
return self.command_request(method="PUT", guild_id=guild_id, json=perms_dict, url_ending="/permissions")

def add_slash_command(
self, guild_id, cmd_name: str, description: str, options: list = None
):
Expand Down Expand Up @@ -167,4 +185,3 @@ def delete(self, token, message_id="@original"):
"""
req_url = f"/messages/{message_id}"
return self.command_response(token, True, "DELETE", url_ending = req_url)

95 changes: 90 additions & 5 deletions discord_slash/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ def __init__(self, name, cmd): # Let's reuse old command formatting.
self.allowed_guild_ids = cmd["guild_ids"] or []
self.options = cmd["api_options"] or []
self.connector = cmd["connector"] or {}
self.has_subcommands = cmd["has_subcommands"]
# Ref https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/core.py#L1447
# Since this isn't inherited from `discord.ext.commands.Command`, discord.py's check decorator will
# add checks at this var.
Expand Down Expand Up @@ -176,6 +175,28 @@ async def can_run(self, ctx) -> bool:
return False not in res


class BaseCommandObject(CommandObject):
"""
BaseCommand object of this extension.

.. note::
This model inherits :class:`.model.CommandObject`, so this has every variables from that.

.. warning::
Do not manually init this model.

:ivar has_subcommands: Indicates whether this base command has subcommands.
:ivar default_permission: Indicates whether users should have permissions to run this command by default.
:ivar permissions: Permissions to restrict use of this command.
"""

def __init__(self, name, cmd): # Let's reuse old command formatting.
super().__init__(name, cmd)
self.has_subcommands = cmd["has_subcommands"]
self.default_permission = cmd["default_permission"]
self.permissions = cmd["api_permissions"] or []


class SubcommandObject(CommandObject):
"""
Subcommand object of this extension.
Expand All @@ -193,15 +214,14 @@ class SubcommandObject(CommandObject):
"""

def __init__(self, sub, base, name, sub_group=None):
sub["has_subcommands"] = True # For the inherited class.
super().__init__(name, sub)
self.base = base.lower()
self.subcommand_group = sub_group.lower() if sub_group else sub_group
self.base_description = sub["base_desc"]
self.subcommand_group_description = sub["sub_group_desc"]


class CogCommandObject(CommandObject):
class CogBaseCommandObject(BaseCommandObject):
"""
Slash command object but for Cog.

Expand Down Expand Up @@ -235,8 +255,9 @@ class CogSubcommandObject(SubcommandObject):
Do not manually init this model.
"""

def __init__(self, *args):
super().__init__(*args)
def __init__(self, base, cmd, sub_group, name, sub):
super().__init__(sub, base, name, sub_group)
self.base_command_data = cmd
self.cog = None # Manually set this later.

async def invoke(self, *args, **kwargs):
Expand Down Expand Up @@ -358,3 +379,67 @@ async def wrap():
await self._http.delete(self.__interaction_token, self.id)

self._state.loop.create_task(wrap())


class PermissionData:
"""
Single slash permission data.

:ivar id: User or role id, based on following type specfic.
:ivar type: The ``SlashCommandPermissionsType`` type of this permission.
:ivar permission: State of permission. ``True`` to allow, ``False`` to disallow.
"""
def __init__(self, id, type, permission, **kwargs):
self.id = id
self.type = type
self.permission = permission

def __eq__(self, other):
if isinstance(other, PermissionData):
return (
self.id == other.id
and self.type == other.id
and self.permission == other.permission
)
else:
return False


class GuildPermissionsData:
"""
Slash permissions data for a command in a guild.

:ivar id: Command id, provided by discord.
:ivar guild_id: Guild id that the permissions are in.
:ivar permissions: List of permissions dict.
"""
def __init__(self, id, guild_id, permissions, **kwargs):
self.id = id
self.guild_id = guild_id
self.permissions = []
if permissions:
for permission in permissions:
self.permissions.append(PermissionData(**permission))

def __eq__(self, other):
if isinstance(other, GuildPermissionsData):
return (
self.id == other.id
and self.guild_id == other.guild_id
and self.permissions == other.permissions
)
else:
return False


class SlashCommandPermissionType(IntEnum):
"""
Equivalent of `ApplicationCommandPermissionType <https://discord.com/developers/docs/interactions/slash-commands#applicationcommandpermissiontype>`_ in the Discord API.
"""
ROLE = 1
USER = 2

@classmethod
def from_type(cls, t: type):
if issubclass(t, discord.abc.Role): return cls.ROLE
if issubclass(t, discord.abc.User): return cls.USER
Loading