From 11d5df21b6a2bf0b62d3deefa5fe5619a3c8856c Mon Sep 17 00:00:00 2001 From: cl0ne Date: Sun, 21 Mar 2021 00:23:10 +0200 Subject: [PATCH] Add Anonymous Admins handling and logging to @admin_only Anonymous Admins came with Bot API 5.0: https://core.telegram.org/bots/api#november-4-2020 > Added the field sender_chat to the class Message, containing the sender of a message which is a chat (group or channel). For backward compatibility in non-channel chats, the field from in such messages will contain the user 777000 for messages automatically forwarded to the discussion group and the user 1087968824 (@GroupAnonymousBot) for messages from anonymous group administrators. --- devpotato_bot/helpers.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/devpotato_bot/helpers.py b/devpotato_bot/helpers.py index 5659d3e..1e8ee67 100644 --- a/devpotato_bot/helpers.py +++ b/devpotato_bot/helpers.py @@ -13,7 +13,11 @@ _logger = logging.getLogger(__name__) @cached(cache=TTLCache(maxsize=256, ttl=60*60)) def get_admin_ids(bot, chat_id): """Returns a list of admin IDs for a given chat. Results are cached for 1 hour.""" - return [admin.user.id for admin in bot.get_chat_administrators(chat_id)] + admin_ids = [admin.user.id for admin in bot.get_chat_administrators(chat_id)] + _logger.info( + 'Administrator ids requested for chat %d', chat_id + ) + return admin_ids class _AdminOnlyHandlerDecorator: @@ -26,7 +30,19 @@ class _AdminOnlyHandlerDecorator: user_id = update.effective_user.id chat: Chat = update.effective_chat message: Message = update.effective_message - if chat.type != Chat.PRIVATE and user_id not in get_admin_ids(context.bot, message.chat_id): + is_private_chat = chat.type == Chat.PRIVATE + # sent by anonymous group chat admin or in a channel post + is_requested_by_chat = chat == message.sender_chat + is_denied = not( + is_private_chat + or is_requested_by_chat + or user_id in get_admin_ids(context.bot, chat.id) + ) + if is_denied: + _logger.info( + 'User %d from chat %d denied from using an admin-only command: %s', + user_id, chat.id, func.__module__ + ) message.reply_text(self.message_text) return return func(update, context)