示例#1
0
    async def _voice_perm_check(ctx: commands.Context,
                                user_voice_state: Optional[discord.VoiceState],
                                **perms: bool) -> bool:
        """Check if the bot and user have sufficient permissions for voicebans.

        This also verifies that the user's voice state and connected
        channel are not ``None``.

        Returns
        -------
        bool
            ``True`` if the permissions are sufficient and the user has
            a valid voice state.

        """
        if user_voice_state is None or user_voice_state.channel is None:
            await ctx.send(_("That user is not in a voice channel."))
            return False
        voice_channel: discord.VoiceChannel = user_voice_state.channel
        required_perms = discord.Permissions()
        required_perms.update(**perms)
        if not voice_channel.permissions_for(ctx.me) >= required_perms:
            await ctx.send(
                _("I require the {perms} permission(s) in that user's channel to do that."
                  ).format(perms=format_perms_list(required_perms)))
            return False
        if (ctx.permission_state is commands.PermState.NORMAL
                and not voice_channel.permissions_for(
                    ctx.author) >= required_perms):
            await ctx.send(
                _("You must have the {perms} permission(s) in that user's channel to use this "
                  "command.").format(perms=format_perms_list(required_perms)))
            return False
        return True
示例#2
0
 async def chanperms(self,
                     ctx,
                     member: discord.Member,
                     *,
                     channel: Union[discord.TextChannel,
                                    discord.VoiceChannel,
                                    discord.CategoryChannel, str] = None):
     """Check user's permission for current or provided channel"""
     if isinstance(channel, str):
         await ctx.send_help()
         return
     perms = channel.permissions_for(member)
     await ctx.send("{}\n{}".format(
         chat.inline(str(member.guild_permissions.value)),
         chat.box(chat.format_perms_list(perms), lang="py")))
示例#3
0
 async def chanperms(
     self,
     ctx,
     member: Optional[discord.Member],
     *,
     channel: Union[discord.TextChannel, discord.VoiceChannel,
                    discord.CategoryChannel] = None,
 ):
     """Check user's permission for current or provided channel"""
     if not member:
         member = ctx.author
     if not channel:
         channel = ctx.channel
     perms = channel.permissions_for(member)
     await ctx.send("{}\n{}".format(
         chat.inline(str(perms.value)),
         chat.box(
             chat.format_perms_list(perms)
             if perms.value else _("No permissions"),
             lang="py",
         ),
     ))
示例#4
0
    async def _check_requires_user_perms_and_privilege_level(
            self, cog_or_command: commands.CogCommandMixin) -> CheckResult:
        label = _("User's discord permissions and privilege level")
        requires = cog_or_command.requires
        if await requires._verify_user(self.ctx):
            print("HI!")
            return CheckResult(True, label)
        resolutions = []
        if requires.user_perms is not None:
            permissions = format_perms_list(requires.user_perms)
            resolutions.append(
                _("grant the required permissions to the user through role settings"
                  " or channel overrides"))
            details = (_(
                "The user is missing some of the channel permissions ({permissions})"
                " required by the {cog} cog."
            ).format(
                permissions=permissions,
                cog=inline(cog_or_command.qualified_name)
            ) if cog_or_command is self.ctx.cog else _(
                "The user is missing some of the channel permissions ({permissions})"
                " required by the {command} command.").format(
                    permissions=permissions,
                    command=self._format_command_name(cog_or_command)))
        if requires.privilege_level is not None:
            if requires.privilege_level is commands.PrivilegeLevel.GUILD_OWNER:
                privilege_level = _("the guild owner")
            else:
                if requires.privilege_level is commands.PrivilegeLevel.MOD:
                    privilege_level = _("the mod role")
                elif requires.privilege_level is commands.PrivilegeLevel.ADMIN:
                    privilege_level = _("the admin role")
                else:
                    raise RuntimeError("Ran into unexpected privilege level.")
                resolutions.append(_("assign appropriate role to the user"))
            details = (
                _("The user is missing the privilege level ({privilege_level})"
                  " required by the {cog} cog.").format(
                      privilege_level=privilege_level,
                      cog=inline(cog_or_command.qualified_name))
                if cog_or_command is self.ctx.cog else
                _("The user is missing the privilege level ({privilege_level})"
                  " required by the {command} command.").format(
                      privilege_level=privilege_level,
                      command=self._format_command_name(cog_or_command),
                  ))

        if not resolutions:
            # Neither `user_perms` nor `privilege_level` are responsible for the issue.
            return CheckResult(True, label)

        resolutions.append(_("add appropriate rule in the Permissions cog"))
        if requires.user_perms is not None and requires.privilege_level is not None:
            details = (_(
                "The user has neither the channel permissions ({permissions}) nor"
                " the privilege level ({privilege_level}) required by the {cog} cog."
            ).format(
                permissions=permissions,
                privilege_level=privilege_level,
                cog=inline(cog_or_command.qualified_name),
            ) if cog_or_command is self.ctx.cog else _(
                "The user has neither the channel permissions ({permissions}) nor"
                " the privilege level ({privilege_level}) required by the {command} command."
            ).format(
                permissions=permissions,
                privilege_level=privilege_level,
                command=self._format_command_name(cog_or_command),
            ))

        return CheckResult(
            False,
            label,
            details,
            self._format_multiple_resolutions(resolutions),
        )
示例#5
0
    async def _check_requires(
            self, label: str,
            cog_or_command: commands.CogCommandMixin) -> CheckResult:
        original_perm_state = self.ctx.permission_state
        try:
            allowed = await cog_or_command.requires.verify(self.ctx)
        except commands.DisabledCommand:
            return CheckResult(
                False,
                label,
                _("The cog of the given command is disabled in this guild."),
                _("To fix this issue, you can run {command}"
                  " which will enable the {affected_cog} cog in this guild.").
                format(
                    command=self._format_command_name(
                        f"command enablecog {self.ctx.cog.qualified_name}"),
                    affected_cog=inline(self.ctx.cog.qualified_name),
                ),
            )
        except commands.BotMissingPermissions as e:
            # No, go away, "some" can refer to a single permission so plurals are just fine here!
            # Seriously. They are. Don't even question it.
            details = (_(
                "Bot is missing some of the channel permissions ({permissions})"
                " required by the {cog} cog."
            ).format(
                permissions=format_perms_list(e.missing),
                cog=inline(cog_or_command.qualified_name),
            ) if cog_or_command is self.ctx.cog else _(
                "Bot is missing some of the channel permissions ({permissions})"
                " required by the {command} command.").format(
                    permissions=format_perms_list(e.missing),
                    command=self._format_command_name(cog_or_command),
                ))
            return CheckResult(
                False,
                label,
                details,
                _("To fix this issue, grant the required permissions to the bot"
                  " through role settings or channel overrides."),
            )
        if allowed:
            return CheckResult(True, label)

        self.ctx.permission_state = original_perm_state
        return await self._check_until_fail(
            label,
            (
                partial(self._check_requires_bot_owner, cog_or_command),
                partial(self._check_requires_permission_hooks, cog_or_command),
                partial(self._check_requires_permission_rules, cog_or_command),
            ),
            # unless there's some bug here, we should probably never run into this
            final_check_result=CheckResult(
                False,
                _("Other issues related to the permissions."),
                _("Fatal error: There's an issue related to the permissions for the"
                  " {cog} cog but we're not able to determine the exact cause."
                  ) if cog_or_command is self.ctx.cog else
                _("Fatal error: There's an issue related to the permissions for the"
                  " {command} command but we're not able to determine the exact cause."
                  ),
                _("This is an unexpected error, please report it on Red's issue tracker."
                  ),
            ),
        )
示例#6
0
    async def _check_requires(
            self, label: str,
            cog_or_command: commands.CogCommandMixin) -> CheckResult:
        original_perm_state = self.ctx.permission_state
        try:
            allowed = await cog_or_command.requires.verify(self.ctx)
        except commands.DisabledCommand:
            return CheckResult(
                False,
                label,
                _("The cog of the given command is disabled in this guild."),
                _("To fix this issue, you can run {command}"
                  " which will enable the {affected_cog} cog in this guild.").
                format(
                    command=self._format_command_name(
                        f"command enablecog {self.ctx.cog.qualified_name}"),
                    affected_cog=inline(self.ctx.cog.qualified_name),
                ),
            )
        except commands.BotMissingPermissions as e:
            # No, go away, "some" can refer to a single permission so plurals are just fine here!
            # Seriously. They are. Don't even question it.
            details = (_(
                "Bot is missing some of the channel permissions ({permissions})"
                " required by the {cog} cog."
            ).format(
                permissions=format_perms_list(e.missing),
                cog=inline(cog_or_command.qualified_name),
            ) if cog_or_command is self.ctx.cog else _(
                "Bot is missing some of the channel permissions ({permissions})"
                " required by the {command} command.").format(
                    permissions=format_perms_list(e.missing),
                    command=self._format_command_name(cog_or_command),
                ))
            return CheckResult(
                False,
                label,
                details,
                _("To fix this issue, grant the required permissions to the bot"
                  " through role settings or channel overrides."),
            )
        if allowed:
            return CheckResult(True, label)

        self.ctx.permission_state = original_perm_state
        return await self._check_until_fail(
            label,
            (
                partial(self._check_requires_bot_owner, cog_or_command),
                partial(self._check_requires_permission_hooks, cog_or_command),
            ),
            # TODO: Split the `final_check_result` into parts to be ran by this function
            final_check_result=CheckResult(
                False,
                _("User's discord permissions, privilege level and rules from Permissions cog"
                  ),
                _("One of the above is the issue."),
                _("To fix this issue, verify each of these"
                  " and determine which part is the issue."),
            ),
        )