示例#1
0
async def is_user_admin(user_id: int, chat_id):
    if user_id in SUDO_USERS:
        return True

    try:
        participant = await tbot(GetParticipantRequest(chat_id, user_id))
        return isinstance(participant.participant,
                          (ChannelParticipantAdmin, ChannelParticipantCreator))
    except TypeError:
        async for user in tbot.iter_participants(
                chat_id, filter=ChannelParticipantsAdmins):
            if user_id == user.id:
                return True
    return False
示例#2
0
async def is_admin(catub, chat_id, userid):
    if not str(chat_id).startswith("-100"):
        return False
    try:
        req_jo = await catub(GetParticipantRequest(chat_id, userid))
        chat_participant = req_jo.participant
        if isinstance(chat_participant,
                      (ChannelParticipantCreator, ChannelParticipantAdmin)):
            return True
    except Exception as e:
        LOGS.info(str(e))
        return False
    else:
        return False
示例#3
0
async def is_admin(client, chat_id, user_id):
    if not str(chat_id).startswith("-100"):
        return False
    try:
        req_jo = await client(
            GetParticipantRequest(channel=chat_id, user_id=user_id))
        chat_participant = req_jo.participant
        if isinstance(chat_participant,
                      (ChannelParticipantCreator, ChannelParticipantAdmin)):
            return True
    except Exception:
        return False
    else:
        return False
示例#4
0
文件: feds.py 项目: n8wachT/SophieBot
async def leave_fed(event, chat_id, user):
    peep = await bot(GetParticipantRequest(
        channel=chat_id,
        user_id=user,
    ))
    if not peep.participant == ChannelParticipantCreator(user_id=user):
        await event.reply(get_string('feds', 'only_creators', chat_id))
        return

    old = mongodb.fed_groups.delete_one({'chat_id': chat_id}).deleted_count
    if old < 1:  # If chat not was in any federation
        await event.reply(get_string('feds', 'chat_not_in_fed', chat_id))
        return

    return True
示例#5
0
 async def on_pm_click(event):
     hunter = (event.data_match.group(1)).decode("UTF-8")
     hell = hunter.split("+")
     if not event.sender_id == int(hell[0]):
         return await event.answer("This Ain't For You!!", alert=True)
     try:
         await bot(GetParticipantRequest(int(hell[1]), int(hell[0])))
     except UserNotParticipantError:
         return await event.answer("You need to join the channel first.",
                                   alert=True)
     await bot.edit_permissions(event.chat_id,
                                int(hell[0]),
                                send_message=True,
                                until_date=None)
     await event.edit("Yay! You can chat now !!")
示例#6
0
async def diesoon(e):
    match = (e.data_match.group(1)).decode("UTF-8")
    spli = match.split("_")
    if not e.sender_id == int(spli[0]):
        return await e.answer("This Message is Not for You", alert=True)
    try:
        await ultroid_bot(GetParticipantRequest(int(spli[1]), int(spli[0])))
    except UserNotParticipantError:
        return await e.answer(
            "Join that Channel first then click this button.", alert=True)
    await ultroid_bot.edit_permissions(e.chat_id,
                                       int(spli[0]),
                                       send_messages=True,
                                       until_date=None)
    await e.edit("User unmuted. Welcome to the group!")
示例#7
0
async def diesoon(e):
    match = (e.data_match.group(1)).decode("UTF-8")
    spli = match.split("_")
    if e.sender_id != int(spli[0]):
        return await e.answer("This Message is Not for You", alert=True)
    try:
        await ultroid_bot(GetParticipantRequest(int(spli[1]), int(spli[0])))
    except UserNotParticipantError:
        return await e.answer(
            "Please Join That Channel !\nThen Click This Button !", alert=True)
    await ultroid_bot.edit_permissions(e.chat_id,
                                       int(spli[0]),
                                       send_messages=True,
                                       until_date=None)
    await e.edit("Thanks For Joining ! ")
示例#8
0
async def user_is_admin(user_id: int, message):
    if message.is_private or user_id in SUDO_USERS:
        return True

    if message.is_channel:
        participant = await tbot(
            GetParticipantRequest(message.chat_id, user_id))
        return isinstance(participant.participant,
                          (ChannelParticipantAdmin, ChannelParticipantCreator))

    async for user in tbot.iter_participants(message.chat_id,
                                             filter=ChannelParticipantsAdmins):
        if user_id == user.id:
            return True
    return False
示例#9
0
async def on_update_chan(e):
    channel_id = utils.get_peer_id(PeerChannel(e.channel_id))
    entity = e._entities.get(channel_id)
    if isinstance(entity, tl.types.ChannelForbidden):
        return
    if isinstance(entity, tl.types.Channel) and entity.left:
        return
    channel = await borg.get_input_entity(channel_id)
    self_participant = await borg(
        GetParticipantRequest(channel, InputUserSelf()))
    if not isinstance(
            self_participant,
        (tl.types.ChannelParticipantSelf, tl.types.ChannelParticipantAdmin)):
        return
    inviter_id = self_participant.participant.inviter_id
    await on_added(inviter_id, channel_id)
示例#10
0
async def leave_fed_comm(message, strings, **kwargs):
    chat_id = message.chat.id
    user = message.from_user.id
    peep = await tbot(GetParticipantRequest(
        channel=chat_id,
        user_id=user,
    ))
    if not peep.participant == ChannelParticipantCreator(user_id=user):
        await message.reply(get_string('feds', 'only_creators', chat_id))
        return

    old = mongodb.fed_groups.delete_one({'chat_id': chat_id}).deleted_count
    if old < 1:  # If chat not was in any federation
        await message.reply(get_string('feds', 'chat_not_in_fed', chat_id))
        return
    await message.reply(strings['leave_fed_success'])
示例#11
0
async def join_fed_comm(message, strings, status, chat_id, chat_title,
                        **kwargs):
    fed_id = message.get_args().split(' ')[0]
    peep = await tbot(
        GetParticipantRequest(
            channel=chat_id,
            user_id=message.from_user.id,
        ))
    if not peep.participant == ChannelParticipantCreator(
            user_id=message.from_user.id):
        await message.reply(get_string('feds', 'only_creators', chat_id))
        return

    # Assume Fed ID invalid
    if not (fed := await db.feds.find_one({'fed_id': fed_id})):
        await message.reply(get_string('feds', 'fed_id_invalid', chat_id))
        return
示例#12
0
async def admin(event):
    try:
        if str(event.chat_id).startswith("-100"):
            sender = await event.get_sender()
            member = await client(
                GetParticipantRequest(channel=event.chat_id,
                                      user_id=event.from_id))
            if isinstance(member.participant,
                          (ChannelParticipantAdmin,
                           ChannelParticipantCreator)) and not sender.bot:
                return True
            else:
                return False
        else:
            return False
    except:
        return False
示例#13
0
    async def _can_use_commands(self, chat, tgid):
        if tgid in self.tg_whitelist:
            return True

        user = u.User.get_by_tgid(tgid)
        if user and user.is_admin:
            self.tg_whitelist.append(user.tgid)
            return True

        if self.whitelist_group_admins:
            if isinstance(chat, PeerChannel):
                p = await self.client(GetParticipantRequest(chat, tgid))
                return isinstance(p, (ChannelParticipantCreator, ChannelParticipantAdmin))
            elif isinstance(chat, PeerChat):
                chat = await self.client(GetFullChatRequest(chat.chat_id))
                participants = chat.full_chat.participants.participants
                for p in participants:
                    if p.user_id == tgid:
                        return isinstance(p, (ChatParticipantCreator, ChatParticipantAdmin))
示例#14
0
async def unban_user(message, user_id, chat_id):
    real_chat_id = message.chat.id

    if user_id == BOT_ID:
        await message.reply(
            get_string("bans", "bot_cant_be_unbanned", real_chat_id))
        return False
    try:
        peep = await tbot(GetParticipantRequest(chat_id, user_id))

        if not isinstance(peep.participant, ChannelParticipantBanned):
            await message.reply(
                get_string('bans', 'usernt_banned', real_chat_id))
            return False
    except Exception:
        pass

    await bot.unban_chat_member(chat_id, user_id)
    return True
示例#15
0
async def on_update_chan(e):
    channel_id = utils.get_peer_id(PeerChannel(e.channel_id))
    entity = e._entities.get(channel_id)
    if isinstance(entity, tl.types.ChannelForbidden):
        return
    if isinstance(entity, tl.types.Channel) and (entity.left or not entity.broadcast):
        return
    channel = await borg.get_input_entity(channel_id)
    self_participant = await borg(GetParticipantRequest(channel, InputUserSelf()))
    if not hasattr(self_participant.participant, 'inviter_id'):
        return
    # assume the participant date is the added date (idk what else it could be)
    added_on = getattr(self_participant.participant, 'date', None)
    if not added_on:
        return
    if datetime.now(timezone.utc) - added_on > timedelta(seconds=2):
        return
    inviter_id = self_participant.participant.inviter_id
    await on_added(inviter_id, channel_id)
示例#16
0
async def diesoon(e):
    match = (e.data_match.group(1)).decode("UTF-8")
    spli = match.split("_")
    if e.sender_id != int(spli[0]):
        return await e.answer(get_string("fsub_7"), alert=True)
    try:
        values = await ultroid_bot(
            GetParticipantRequest(int(spli[1]), int(spli[0])))
        if isinstance(values.participant, ChannelParticipantLeft) or (
                isinstance(values.participant, ChannelParticipantBanned)
                and values.left):
            raise UserNotParticipantError("")
    except UserNotParticipantError:
        return await e.answer(
            "Please Join That Channel !\nThen Click This Button !", alert=True)
    await ultroid_bot.edit_permissions(e.chat_id,
                                       int(spli[0]),
                                       send_messages=True,
                                       until_date=None)
    await e.edit(get_string("fsub_8"))
示例#17
0
async def forcesub(ult):
    if not udB.get("FORCESUB"):
        return
    if not (ult.user_joined or ult.user_added):
        return
    if not get_forcesetting(ult.chat_id):
        return
    user = await ult.get_user()
    if user.bot:
        return
    joinchat = get_forcesetting(ult.chat_id)
    try:
        await ultroid_bot(GetParticipantRequest(int(joinchat), user.id))
    except UserNotParticipantError:
        await ultroid_bot.edit_permissions(ult.chat_id,
                                           user.id,
                                           send_messages=False)
        res = await ultroid_bot.inline_query(asst.me.username,
                                             f"fsub {user.id}_{joinchat}")
        await res[0].click(ult.chat_id, reply_to=ult.action_message.id)
示例#18
0
async def stop(chat: Channel, client: Client, db: Database, event: Command, tags: Tags):
    if not event.message.is_reply:
        return
    db_chat = await db.chats.get(event.chat_id)
    start_id = db_chat.raid_start
    reply_msg = await event.message.get_reply_message()
    end_id = reply_msg.id
    await db.chats.stop_raid(event.chat_id)
    raidno = tags.get('raidno', None)

    user_ids = set()
    message_ids = set()
    async for msg in client.iter_messages(chat, min_id=start_id-1, reverse=True):
        if msg.id >= end_id + 1:
            break
        if isinstance(msg.action, MessageActionChatAddUser):
            action: MessageActionChatAddUser = msg.action
            if msg.sender_id in action.users:
                uid = msg.sender_id
                user_ids.add(uid)
                message_ids.add(msg.id)

    await client(DeleteMessagesRequest(chat, list(message_ids)))

    for uid in user_ids:
        try:
            result = await client(GetParticipantRequest(chat, uid))
            if not isinstance(result.participant, ChannelParticipantBanned):
                try:
                    await client.ban(chat, uid)
                except FloodWaitError as e:
                    flood_wait_message: Message = await client.send_message(chat, f'FloodWait for {e.seconds}')
                    await asyncio.sleep(e.seconds)
                    await flood_wait_message.delete()
                    await client.ban(chat, uid)
                    if raidno:
                        await client.gban(uid, f'Raid[{raidno}]')
            await asyncio.sleep(0.5)

        except (UserNotParticipantError, BadRequestError):
            pass
示例#19
0
async def unban(event, chat, chat_creator, chat_admin):
    """
    <b>param:</b> <code>(required if not reply) user</code>
    <b>return:</b> <i>Un-Bans an user in the chat!</i>
    """
    if chat_creator or chat_admin.can_ban:
        if event.is_reply:
            rep_msg = await event.get_reply_message()
            to_ban = rep_msg.from_id
        elif event.args.user:
            to_ban = event.args.user
        else:
            await event.reply("There's no user to unban!")
            return
        try:
            ent = await event.client.get_entity(to_ban)
        except Exception:
            await event.reply("I don't seem to find this user")
            return
        if isinstance(ent, User):
            try:
                chat_participant = await event.client(GetParticipantRequest(chat, ent.id))
            except UserNotParticipantError:
                await event.reply("This user is not a participant of this chat!")
                return
            if isinstance(
                chat_participant.participant,
                (ChannelParticipantAdmin,
                 ChannelParticipantCreator)):
                await event.reply("I can't unban chat admins because they can't be banned!")
            elif not isinstance(chat_participant.participant, ChannelParticipantBanned):
                await event.reply("This user isn't banned in this chat!")
            elif isinstance(chat_participant.participant, ChannelParticipantSelf):
                await event.reply("You can't unban yourself!")
            else:
                print(chat_participant.participant)
                await event.client(EditBannedRequest(chat, ent.id, ChatBannedRights(until_date=None,
                                                                                    view_messages=None)))
                await event.reply("Un-Banned <code>{}</code>".format(ent.username or ent.first_name))
    else:
        await event.reply("You don't have the rights to restrict users here!")
示例#20
0
async def purge_messages(event):
    start = time.perf_counter()
    if event.from_id is None:
        return

    if not await user_is_admin(user_id=event.from_id, message=event):
        await event.reply("Only Admins are allowed to use this command")
        return
        result = await message.client(
            GetParticipantRequest(channel=chat_id, user_id=user_id))

    if not await can_delete_messages(message=event):
        await event.reply("Can't seem to purge the message")
        return

    if not await user_can_delete_t(event.chat_id, event.from_id, event):
        await event.reply("You do not have enough rights to delete messages.")
        return

    reply_msg = await event.get_reply_message()
    if not reply_msg:
        await event.reply(
            "Reply to a message to select where to start purging from.")
        return
    messages = []
    message_id = reply_msg.id
    delete_to = event.message.id

    messages.append(event.reply_to_msg_id)
    for msg_id in range(message_id, delete_to + 1):
        messages.append(msg_id)
        if len(messages) == 100:
            await event.client.delete_messages(event.chat_id, messages)
            messages = []

    await event.client.delete_messages(event.chat_id, messages)
    time_ = time.perf_counter() - start
    text = f"Purged Successfully in {time_:0.2f} Second(s) This Message Self Destruct After 4 Seconds"
    x = await event.respond(text, parse_mode='markdown')
    await asyncio.sleep(4)
    await event.client.delete_messages(event.chat_id, x.id)
示例#21
0
文件: utils.py 项目: artxia/backup
async def is_user_admin(chat_id: hints.EntityLike, user_id: hints.EntityLike) -> tuple[Optional[bool], Optional[str]]:
    """
    Check if the user is an admin in the chat.

    :param chat_id: chat id
    :param user_id: user id
    :return: True if user is admin, False if not, None if self / the user not in the chat
    """
    is_admin = None
    participant_type = None
    try:
        input_chat = await env.bot.get_input_entity(chat_id)
        input_user = await env.bot.get_input_entity(user_id)
        # noinspection PyTypeChecker
        participant: types.channels.ChannelParticipant = await env.bot(
            GetParticipantRequest(input_chat, input_user))
        is_admin = isinstance(participant.participant,
                              (types.ChannelParticipantAdmin, types.ChannelParticipantCreator))
        participant_type = type(participant.participant).__name__
    except (UserNotParticipantError, ValueError):
        pass
    return is_admin, participant_type
示例#22
0
async def Function(cmd, event, delt, LANG):
    reply = await event.get_reply_message()
    result = await client(
        GetParticipantRequest(event.chat_id, event.message.from_id))
    if isadmin(result) == True:
        if (cmd[0].lower() == "mute"):
            if not (reply):
                if len(cmd) == 2:
                    try:
                        await client(
                            EditBannedRequest(event.chat_id, cmd[1],
                                              muted_rights))
                        await event.respond(lang['muteon'])
                    except Exception as error:
                        await event.respond(lang['notarg'])
                else:
                    await event.respond(lang['notreply'])
            else:
                await client(
                    EditBannedRequest(event.chat_id, reply.from_id,
                                      muted_rights))
                await event.respond(lang['muteon'])
        elif (cmd[0].lower() == "unmute"):
            if not (reply):
                if len(cmd) == 2:
                    try:
                        await client(
                            EditBannedRequest(event.chat_id, cmd[1],
                                              unmuted_rights))
                        await event.respond(lang['muteoff'])
                    except Exception as error:
                        await event.respond(lang['notarg'])
                else:
                    await event.respond(lang['notreply'])
            else:
                await client(
                    EditBannedRequest(event.chat_id, reply.from_id,
                                      unmuted_rights))
                await event.respond(lang['muteoff'])
示例#23
0
文件: feds.py 项目: n8wachT/SophieBot
async def join_fed(event, chat_id, fed_id, user):
    peep = await bot(GetParticipantRequest(
        channel=chat_id,
        user_id=user,
    ))
    if not peep.participant == ChannelParticipantCreator(user_id=user):
        await event.reply(get_string('feds', 'only_creators', chat_id))
        return

    check = mongodb.fed_list.find_one({'fed_id': fed_id})
    if check is False:  # Assume Fed ID invalid
        await event.reply(get_string('feds', 'fed_id_invalid', chat_id))
        return

    old = mongodb.fed_groups.find_one({'chat_id': chat_id})
    if old:  # Assume chat already joined this/other fed
        await event.reply(get_string('feds', 'joined_fed_already', chat_id))
        return

    join_data = {'chat_id': chat_id, 'fed_id': fed_id}
    mongodb.fed_groups.insert_one(join_data)

    return True
示例#24
0
文件: bans.py 项目: n8wachT/SophieBot
async def unban_user(event, user_id, chat_id):

    unbanned_rights = ChatBannedRights(
        until_date=None,
        view_messages=False,
        send_messages=False,
        send_media=False,
        send_stickers=False,
        send_gifs=False,
        send_games=False,
        send_inline=False,
        embed_links=False,
    )

    bot_id = await bot.get_me()
    bot_id = bot_id.id

    if user_id == bot_id:
        await event.reply(
            get_string("bans", "bot_cant_be_unbanned", event.chat_id))
        return False
    try:
        peep = await bot(GetParticipantRequest(chat_id, user_id))

        if not isinstance(peep.participant, ChannelParticipantBanned):
            await event.reply(get_string('bans', 'usernt_banned', chat_id))
            return False
    except Exception:
        pass

    try:
        await event.client(EditBannedRequest(chat_id, user_id,
                                             unbanned_rights))
    except Exception as err:
        logger.error(str(err))
        return False
    return True
示例#25
0
async def unlock(client: Client, db: Database, chat, event: Command, msg: Message) -> KanTeXDocument:
    """Restore a chats previous permissions

    Arguments:
        `-self`: Use to make other Kantek instances ignore your command

    Examples:
        {cmd}
    """
    participant = (await client(GetParticipantRequest(chat, msg.sender_id))).participant
    permitted = False
    if isinstance(participant, ChannelParticipantCreator):
        permitted = True
    elif isinstance(participant, ChannelParticipantAdmin):
        rights = participant.admin_rights
        permitted = rights.ban_users
    if not permitted:
        return KanTeXDocument('Insufficient permission.')
    dbchat = await db.chats.get(event.chat_id)
    permissions = chat.default_banned_rights.to_dict()
    del permissions['_']
    if dbchat.locked:
        new_rights = permissions.copy()

        for k, v in dbchat.permissions.items():
            new_rights[k] = v
        try:
            await client(EditChatDefaultBannedRightsRequest(
                chat,
                banned_rights=ChatBannedRights(**new_rights)))
        except ChatNotModifiedError:
            pass
        await db.chats.unlock(event.chat_id)
        return KanTeXDocument('Chat unlocked.')
    else:
        return KanTeXDocument('Chat not locked.')
示例#26
0
    async def _check(self, message, func):
        config = self.get_flags(func)
        if not config:  # Either False or 0, either way we can failfast
            return False
        logger.debug("Checking security match for %d", config)

        f_owner = config & OWNER
        f_sudo = config & SUDO
        f_support = config & SUPPORT
        f_group_owner = config & GROUP_OWNER
        f_group_admin_add_admins = config & GROUP_ADMIN_ADD_ADMINS
        f_group_admin_change_info = config & GROUP_ADMIN_CHANGE_INFO
        f_group_admin_ban_users = config & GROUP_ADMIN_BAN_USERS
        f_group_admin_delete_messages = config & GROUP_ADMIN_DELETE_MESSAGES
        f_group_admin_pin_messages = config & GROUP_ADMIN_PIN_MESSAGES
        f_group_admin_invite_users = config & GROUP_ADMIN_INVITE_USERS
        f_group_admin = config & GROUP_ADMIN
        f_group_member = config & GROUP_MEMBER
        f_pm = config & PM

        f_group_admin_any = (f_group_admin_add_admins or f_group_admin_change_info or f_group_admin_ban_users
                             or f_group_admin_delete_messages or f_group_admin_pin_messages
                             or f_group_admin_invite_users or f_group_admin)

        if f_owner and message.from_id in self._owner:
            return True
        if f_sudo and message.from_id in self._sudo:
            return True
        if f_support and message.from_id in self._support:
            return True

        if message.from_id in self._db.get(main.__name__, "blacklist_users", []):
            return False

        if f_pm and message.is_private:
            return True

        if f_group_member and message.is_group:
            return True

        if f_group_admin_any or f_group_owner:
            if message.is_channel:
                if not message.is_group:
                    if message.edit_date:
                        return False  # anyone can assume identity of another in channels
                        # TODO: iter admin log and search for the edit event, to check who edited
                    chat = await message.get_chat()
                    if not chat.creator and not (chat.admin_rights and chat.admin_rights.post_messages):
                        return False
                    if self._any_admin and f_group_admin_any:
                        return True

                    if f_group_admin:
                        return True
                    # TODO: when running as bot, send an inline button which allows confirmation of command
                else:
                    participant = await message.client(GetParticipantRequest(await message.get_input_chat(),
                                                                             await message.get_input_sender()))
                    participant = participant.participant
                    if isinstance(participant, telethon.types.ChannelParticipantCreator):
                        return True
                    if isinstance(participant, telethon.types.ChannelParticipantAdmin):
                        if self._any_admin and f_group_admin_any:
                            return True
                        rights = participant.admin_rights

                        if f_group_admin:
                            return True
                        if f_group_admin_add_admins and rights.add_admins:
                            return True
                        if f_group_admin_change_info and rights.change_info:
                            return True
                        if f_group_admin_ban_users and rights.ban_users:
                            return True
                        if f_group_admin_delete_messages and rights.delete_messages:
                            return True
                        if f_group_admin_pin_messages and rights.pin_messages:
                            return True
                        if f_group_admin_invite_users and rights.invite_users:
                            return True
            elif message.is_group:
                full_chat = await message.client(telethon.functions.messages.GetFullChatRequest(message.chat_id))
                participants = full_chat.full_chat.participants.participants
                participant = None
                for possible_participant in participants:
                    if possible_participant.user_id == message.from_id:
                        participant = possible_participant
                        break
                if not participant:
                    return
                if isinstance(participant, telethon.types.ChatParticipantCreator):
                    return True
                if isinstance(participant, telethon.types.ChatParticipantAdmin):
                    if f_group_admin_any:
                        return True
        return False
示例#27
0
async def challenge_user(event):
    global config, current_challenges

    bot = event.client
    chat = event.chat
    target = event.user

    if event.user_added:
        me = await bot.get_me()
        if me.id in event.user_ids:
            async with config_lock:
                group_config = config.get(str(event.chat.id), config['*'])
                await event.respond(
                    message=group_config['msg_self_introduction'])
        return None
    elif not event.user_joined:
        return None

    # get previous restriction data
    async with upr_lock:
        key = '{chat}|{user}'.format(chat=chat.id, user=target.id)
        # a record probably means the user didn't pass the challenge previously
        # (and is fully restricted)
        # this time they leave & rejoin the group in order to pass the test
        # so we won't update the record which is likely fully restricted
        if not user_previous_restrictions.get(key):
            try:
                member = await bot(GetParticipantRequest(chat, target))
                member = member.participant
                user_previous_restrictions[key] = member
            except errors.UserNotParticipantError:
                logging.warning(
                    f'UserNotParticipantError on challenge_user: user={target.id}, chat={chat.id}'
                )

    # Attempt to restrict the user
    try:
        await bot(
            EditBannedRequest(
                chat, target,
                ChatBannedRights(until_date=None,
                                 view_messages=None,
                                 send_messages=True,
                                 send_media=True,
                                 send_stickers=True,
                                 send_gifs=True,
                                 send_games=True,
                                 send_inline=True,
                                 send_polls=True,
                                 embed_links=True,
                                 invite_users=True)))
    except errors.ChatAdminRequiredError:
        return None

    async with config_lock:
        group_config = config.get(str(chat.id), config['*'])

    challenge = Challenge()

    def challenge_to_buttons(ch):
        # There can be 8 buttons per row at most (more are ignored).
        buttons = [
            KeyboardButtonCallback(text=str(c), data=str(c))
            for c in ch.choices()
        ]
        choices = [
            buttons[i * 8:i * 8 + 8] for i in range((len(buttons) + 7) // 8)
        ]
        # manual approval/refusal by group admins
        choices.extend([[
            KeyboardButtonCallback(text=group_config['msg_approve_manually'],
                                   data='+'),
            KeyboardButtonCallback(text=group_config['msg_refuse_manually'],
                                   data='-')
        ]])
        return choices

    timeout = group_config['challenge_timeout']

    try:
        bot_msg_id = await event.reply(
            message=group_config['msg_challenge'].format(
                timeout=timeout, challenge=challenge.qus()),
            buttons=challenge_to_buttons(challenge))
        bot_msg_id = bot_msg_id.id
    except errors.BadRequestError:  # msg to reply not found
        bot_msg_id = await event.respond(
            message=group_config['msg_challenge'].format(
                timeout=timeout, challenge=challenge.qus()),
            buttons=challenge_to_buttons(challenge))
        bot_msg_id = bot_msg_id.id

    timeout_event = asyncio.create_task(
        handle_challenge_timeout(bot, group_config['challenge_timeout'], chat,
                                 target, bot_msg_id))

    async with cch_lock:
        current_challenges['{chat}|{msg}'.format(
            chat=chat.id,
            msg=bot_msg_id)] = (challenge, target.id, timeout_event)

    try:
        await timeout_event
    except asyncio.CancelledError:
        pass
示例#28
0
async def handle_challenge_response(event):
    global config, current_challenges

    user_ans = event.data.decode()

    bot = event.client
    chat = event.chat
    user = await event.get_sender()
    username = '******' + user.username if user.username else (
        user.first_name + (' ' + user.last_name if user.last_name else ''))
    bot_msg = event.message_id

    async with config_lock:
        group_config = config.get(str(chat.id), config['*'])

    # handle manual approval/refusal by group admins
    if user_ans in ['+', '-']:
        try:
            participant = await bot(
                GetParticipantRequest(channel=chat, user_id=user))
            participant = participant.participant
        except errors.UserNotParticipantError:
            logging.warning(
                f'UserNotParticipantError on handle_challenge_response: user={user.id}, chat={chat.id}'
            )
            await event.answer(message=group_config['msg_permission_denied'])
            return None
        can_ban = False
        try:
            if type(
                    participant
            ) is ChannelParticipantCreator or participant.admin_rights.ban_users:
                can_ban = True
        except AttributeError:
            pass
        if not can_ban:
            await event.answer(message=group_config['msg_permission_denied'])
            return None

        ch_id = '{chat}|{msg}'.format(chat=chat.id, msg=bot_msg)
        async with cch_lock:
            challenge, target, timeout_event = current_challenges.get(
                ch_id, (None, None, None))
            try:
                del current_challenges[ch_id]
            except KeyError:
                return None
        timeout_event.cancel()

        if user_ans == '+':
            try:
                await lift_restriction(bot, chat, target)
            except errors.ChatAdminRequiredError:
                await event.answer(
                    message=group_config['msg_bot_no_permission'])
            try:
                await event.edit(
                    text=group_config['msg_approved'].format(user=username),
                    buttons=None)
            except errors.BadRequestError:  # message to edit not found
                pass
        else:  # user_ans == '-'
            try:
                await bot(
                    EditBannedRequest(
                        chat, target,
                        ChatBannedRights(until_date=None, view_messages=True)))
            except errors.ChatAdminRequiredError:
                await event.answer(
                    message=group_config['msg_bot_no_permission'])
                return None
            try:
                await event.edit(
                    text=group_config['msg_refused'].format(user=username),
                    buttons=None)
            except errors.BadRequestError:  # message to edit not found
                pass

            async with upr_lock:
                member = user_previous_restrictions.get('{chat}|{user}'.format(
                    chat=chat.id, user=target))
                if member:
                    del user_previous_restrictions['{chat}|{user}'.format(
                        chat=chat.id, user=target)]

        await event.answer()
        return None

    ch_id = '{chat}|{msg}'.format(chat=chat.id, msg=bot_msg)
    async with cch_lock:
        challenge, target, timeout_event = current_challenges.get(
            ch_id, (None, None, None))

    if user.id != target:
        await event.answer(message=group_config['msg_challenge_not_for_you'])
        return None

    timeout_event.cancel()

    async with cch_lock:
        del current_challenges[ch_id]

    await event.answer()

    # verify the ans
    correct = (str(challenge.ans()) == user_ans)
    delete = None
    if correct or not group_config.get('challenge_strict_mode'):
        try:
            await lift_restriction(bot, chat, target)
        except errors.ChatAdminRequiredError:
            # This my happen when the bot is deop-ed after the user join
            # and before the user click the button
            # TODO: design messages for this occation
            pass
        msg = 'msg_challenge_passed' if correct else 'msg_challenge_mercy_passed'
        if correct:
            if group_config['delete_passed_challenge']:
                delete = asyncio.create_task(
                    safe_delete_message(
                        bot,
                        group_config['delete_passed_challenge_interval'],
                        channel=chat,
                        id=[bot_msg]))
    else:
        msg = 'msg_challenge_failed'

    await event.edit(text=group_config[msg], buttons=None)
    if delete: await delete
示例#29
0
async def fwgban(client: Client, db: Database, tags: Tags, chat: Channel,
                 msg: Message, args: List, kwargs: Dict,
                 event: Command) -> Optional[KanTeXDocument]:
    """Globally ban a user.

    This will not actively ban them from any chats except the one command was issued in as reply. GBanned users will be automatically banned on join or when writing a message by the Grenzschutz module.
    When banning by reply the message content will be automatically sent to the SpamWatch API if enabled.

    Arguments:

        `reason`: Ban reason, defaults to `spam[gban]`


    Tags:
        gban:
            verbose: Send a message when a user was banned by id


    Examples (as replies):
        {cmd} "some reason here"
        {cmd}
    """
    _gban = tags.get('gban')
    if event.is_private:
        admin = False
    else:
        admin = bool(chat.creator or chat.admin_rights)
    only_joinspam = kwargs.get('only_joinspam', False) or kwargs.get(
        'oj', False)

    verbose = False
    if _gban == 'verbose' or event.is_private:
        verbose = True

    if msg.is_reply:
        bancmd = tags.get('gbancmd')
        reply_msg: Message = await msg.get_reply_message()
        forward: Forward = reply_msg.forward
        if forward.sender_id is None:
            raise Error('User has forward privacy enabled or is a Channel')

        uid = forward.sender_id
        if args:
            ban_reason = ' '.join(args)
        else:
            ban_reason = DEFAULT_REASON
            try:
                participant = await client(
                    GetParticipantRequest(event.chat_id, reply_msg.from_id))
                if not isinstance(participant.participant,
                                  ChannelParticipantCreator):
                    join_date = participant.participant.date

                    if (reply_msg.date -
                            datetime.timedelta(hours=1)) < join_date:
                        ban_reason = 'joinspam'
                    elif only_joinspam:
                        return
            except (UserNotParticipantError, TypeError):
                pass
        banned_uids: Dict = {}
        message = await helpers.textify_message(reply_msg)
        banned, reason = await client.gban(uid, ban_reason, message)
        banned_uids[reason] = banned_uids.get(reason, []) + [str(uid)]
        if verbose:
            sections = []
            if not banned:
                sections.append(KeyValueItem(Bold('Error'), reason))
                await client.respond(msg,
                                     KanTeXDocument(*sections),
                                     reply=True)
                return

            if banned_uids:
                bans = _build_message(banned_uids, message)
                sections.append(Section(f'GBanned User', *bans))

            await client.respond(msg, KanTeXDocument(*sections), reply=True)
            return

    else:
        pass
示例#30
0
async def is_admin(chat_id, user_id):
    req_jo = await bot(GetParticipantRequest(channel=chat_id, user_id=user_id))
    chat_participant = req_jo.participant
    return isinstance(
        chat_participant, (ChannelParticipantCreator, ChannelParticipantAdmin)
    )