From ab0cefb02910e0c16c42e30bcc84d14de62be06b Mon Sep 17 00:00:00 2001 From: Numerlor Date: Wed, 2 Oct 2019 00:13:18 +0200 Subject: rewrite override_in_channel to accept an optional new channel whitelist add checks for the new whitelist to in_channel_check --- bot/decorators.py | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'bot/decorators.py') diff --git a/bot/decorators.py b/bot/decorators.py index dbaad4a2..d7ce29cb 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -64,12 +64,13 @@ def without_role(*role_ids: int) -> bool: def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) -> typing.Callable[[Context], bool]: - """Checks that the message is in a whitelisted channel or optionally has a bypass role.""" + """Checks that the message is in a whitelisted channel or optionally has a bypass role. + + If `in_channel_override` is present, check if it contains channels and use them in place of global whitelist""" def predicate(ctx: Context) -> bool: if not ctx.guild: log.debug(f"{ctx.author} tried to use the '{ctx.command.name}' command from a DM.") return True - if ctx.channel.id in channels: log.debug( f"{ctx.author} tried to call the '{ctx.command.name}' command " @@ -78,11 +79,24 @@ def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) return True if hasattr(ctx.command.callback, "in_channel_override"): - log.debug( - f"{ctx.author} called the '{ctx.command.name}' command " - f"and the command was whitelisted to bypass the in_channel check." - ) - return True + override = ctx.command.callback.in_channel_override + if override is None: + log.debug( + f"{ctx.author} called the '{ctx.command.name}' command " + f"and the command was whitelisted to bypass the in_channel check." + ) + return True + else: + if ctx.channel.id in override: + log.debug( + f"{ctx.author} tried to call the '{ctx.command.name}' command " + f"and the command was used in an overridden whitelisted channel." + ) + return True + channels_str = ', '.join(f"<#{c_id}>" for c_id in override) + raise InChannelCheckFailure( + f"Sorry, but you may only use this command within {channels_str}." + ) if bypass_roles and any(r.id in bypass_roles for r in ctx.author.roles): log.debug( @@ -107,14 +121,19 @@ def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) in_channel = commands.check(in_channel_check) -def override_in_channel(func: typing.Callable) -> typing.Callable: +def override_in_channel(channels: typing.Tuple[int] = None) -> typing.Callable: """ Set command callback attribute for detection in `in_channel_check`. + Override global whitelist if channels are specified. + This decorator has to go before (below) below the `command` decorator. """ - func.in_channel_override = True - return func + def inner(func: typing.Callable): + func.in_channel_override = channels + return func + + return inner def locked() -> typing.Union[typing.Callable, None]: -- cgit v1.2.3 From 1c7a7371bde7a31f5fbda2730b0e81761ed08be4 Mon Sep 17 00:00:00 2001 From: Numerlor Date: Wed, 2 Oct 2019 00:17:35 +0200 Subject: add return type hint to override_in_channel inner function --- bot/decorators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot/decorators.py') diff --git a/bot/decorators.py b/bot/decorators.py index d7ce29cb..8748fd83 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -129,7 +129,7 @@ def override_in_channel(channels: typing.Tuple[int] = None) -> typing.Callable: This decorator has to go before (below) below the `command` decorator. """ - def inner(func: typing.Callable): + def inner(func: typing.Callable) -> typing.Callable: func.in_channel_override = channels return func -- cgit v1.2.3 From 2f349294d94eac5eec172674e868dcf281e69687 Mon Sep 17 00:00:00 2001 From: Numerlor Date: Wed, 2 Oct 2019 00:31:09 +0200 Subject: fix in_channel_check docstring style --- bot/decorators.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'bot/decorators.py') diff --git a/bot/decorators.py b/bot/decorators.py index 8748fd83..32c017d7 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -64,9 +64,11 @@ def without_role(*role_ids: int) -> bool: def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) -> typing.Callable[[Context], bool]: - """Checks that the message is in a whitelisted channel or optionally has a bypass role. + """ + Checks that the message is in a whitelisted channel or optionally has a bypass role. - If `in_channel_override` is present, check if it contains channels and use them in place of global whitelist""" + If `in_channel_override` is present, check if it contains channels and use them in place of global whitelist + """ def predicate(ctx: Context) -> bool: if not ctx.guild: log.debug(f"{ctx.author} tried to use the '{ctx.command.name}' command from a DM.") -- cgit v1.2.3 From 678e2dca0ef182ea51982547e78473d20457b46c Mon Sep 17 00:00:00 2001 From: Numerlor Date: Wed, 2 Oct 2019 14:03:26 +0200 Subject: add logging when an overriden in_channel_check fails --- bot/decorators.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'bot/decorators.py') diff --git a/bot/decorators.py b/bot/decorators.py index 32c017d7..471ea3be 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -95,6 +95,11 @@ def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) f"and the command was used in an overridden whitelisted channel." ) return True + + log.debug( + f"{ctx.author} tried to call the '{ctx.command.name}' command. " + f"The overridden in_channel check failed." + ) channels_str = ', '.join(f"<#{c_id}>" for c_id in override) raise InChannelCheckFailure( f"Sorry, but you may only use this command within {channels_str}." -- cgit v1.2.3 From 0e01bf0fb84fc91f691cd4f721180c4be0a5dd70 Mon Sep 17 00:00:00 2001 From: Numerlor Date: Wed, 2 Oct 2019 14:04:19 +0200 Subject: fix grammar in in_channel_override docstring --- bot/decorators.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot/decorators.py') diff --git a/bot/decorators.py b/bot/decorators.py index 471ea3be..2c042b56 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -67,7 +67,8 @@ def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) """ Checks that the message is in a whitelisted channel or optionally has a bypass role. - If `in_channel_override` is present, check if it contains channels and use them in place of global whitelist + If `in_channel_override` is present, check if it contains channels + and use them in place of the global whitelist. """ def predicate(ctx: Context) -> bool: if not ctx.guild: -- cgit v1.2.3 From b579d19beae6f92c5a53f110a3031a4e172d3aec Mon Sep 17 00:00:00 2001 From: Numerlor Date: Wed, 2 Oct 2019 18:24:45 +0200 Subject: put role bypass check above channel override to make sure bypass roles can activate commands everywhere even with override channels specified --- bot/decorators.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'bot/decorators.py') diff --git a/bot/decorators.py b/bot/decorators.py index 2c042b56..58f67a15 100644 --- a/bot/decorators.py +++ b/bot/decorators.py @@ -81,6 +81,13 @@ def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) ) return True + if bypass_roles and any(r.id in bypass_roles for r in ctx.author.roles): + log.debug( + f"{ctx.author} called the '{ctx.command.name}' command and " + f"had a role to bypass the in_channel check." + ) + return True + if hasattr(ctx.command.callback, "in_channel_override"): override = ctx.command.callback.in_channel_override if override is None: @@ -106,13 +113,6 @@ def in_channel_check(*channels: int, bypass_roles: typing.Container[int] = None) f"Sorry, but you may only use this command within {channels_str}." ) - if bypass_roles and any(r.id in bypass_roles for r in ctx.author.roles): - log.debug( - f"{ctx.author} called the '{ctx.command.name}' command and " - f"had a role to bypass the in_channel check." - ) - return True - log.debug( f"{ctx.author} tried to call the '{ctx.command.name}' command. " f"The in_channel check failed." -- cgit v1.2.3