Exemple #1
0
    def compare_profile(self, profile):
        '''
        Compara il profilo con un altro profilo per verificare se appartengono alla stessa persona

        Params:
        @profile: Profilo da comparare

        Return:
        Valore di accuratezza tra i profili, più è alto maggiore la similarità
        '''

        # Variabili locali
        match = 0

        # Compara i dati dei profili
        if self.phone is not None and profile.phone is not None:
            if self.phone.number == profile.phone.number:
                match += 1

        # Ottiene il nome completo del profilo corrente
        this_fullname = concat(self.first_name, self.last_name).lower()
        if self.full_name is not None:
            this_fullname = self.full_name.lower()

        # Ottiene il nome completo del profilo comparato
        profile_fullname = concat(
            profile.first_name,
            profile.last_name).lower()
        if profile.full_name is not None:
            profile_fullname = profile.full_name.lower()

        if this_fullname in profile_fullname or profile_fullname in this_fullname:
            match += 1

        # Compara i volti dei profili
        if len(self._face_encodings) > 0:
            for face_encoding in profile._face_encodings:
                results = face_recognition.compare_faces(
                    self._face_encodings, face_encoding)
                match += results.count(True)

        # Compara le immagini tramite hash per identificare quelle similari
        for cmp_hash in self._perceptual_hashes:
            for new_hash in profile._perceptual_hashes:
                if photohash.hashes_are_similar(cmp_hash, new_hash):
                    match += 1

        return match
Exemple #2
0
async def join_polizei(event: ChatAction.Event) -> None:
    """Plugin to ban users with blacklisted strings in their bio."""
    # avoid flood waits from chats mass adding users and don't check users leaving
    if not event.user_joined:
        return
    client: Client = event.client
    try:
        chat: Channel = await event.get_chat()
    except ChannelPrivateError:
        return
    db: Database = client.db
    tags = await Tags.from_event(event)
    bancmd = tags.get('gbancmd')
    polizei_tag = tags.get('polizei')
    if polizei_tag == 'exclude':
        return
    ban_type, ban_reason = False, False
    bio_blacklist = await db.blacklists.bio.get_all()
    mhash_blacklist = await db.blacklists.mhash.get_all()

    try:
        user: UserFull = await client(
            GetFullUserRequest(await event.get_input_user()))
    except TypeError as e:
        logger.error(e)
        return

    for item in bio_blacklist:
        if user.about and item.value in user.about and not item.retired:
            ban_type, ban_reason = db.blacklists.bio.hex_type, item.index

    if user.profile_photo:
        try:
            dl_photo = await client.download_file(user.profile_photo)
        except constants.DOWNLOAD_ERRORS:
            dl_photo = None
        if dl_photo:
            photo_hash = await hash_photo(dl_photo)

            for mhash in mhash_blacklist:
                if mhash and not mhash.retired:
                    if hashes_are_similar(mhash.value, photo_hash,
                                          tolerance=2):
                        ban_type, ban_reason = db.blacklists.mhash.hex_type, mhash.index

    if ban_type and ban_reason:
        await _banuser(event, event.user.id, bancmd, ban_type, ban_reason)
    def add_profile(self, profile):
        '''
        Aggiunge un profilo social all'elenco di profili associati all'utente

        Params:
        @profile: Profilo da associare
        '''

        # Aggiunge i dati del profilo alla persona
        if self.first_name is None and profile.first_name is not None:
            if len(profile.first_name) >= NAME_MIN_LENGHT and not any(
                    map(str.isdigit, profile.first_name)):
                self.first_name = profile.first_name
        if self.last_name is None and profile.last_name is not None:
            if len(profile.last_name) >= NAME_MIN_LENGHT and not any(
                    map(str.isdigit, profile.first_name)):
                self.last_name = profile.last_name
        if profile.phone is not None:
            self.phones.append(profile.phone)

        # Aggiunge i luoghi visitati dalla persona
        self.locations.extend(profile.locations)

        # Aggiunge i nuovi volti
        self.face_encodings.extend(profile._face_encodings)

        # Aggiunge gli hash delle nuove immagini
        for new_hash in profile._perceptual_hashes:
            for cmp_hash in self.perceptual_hashes:
                if photohash.hashes_are_similar(cmp_hash, new_hash):
                    self.perceptual_hashes.append(new_hash)
                    break

        # Ordina la lista dalla locazione più recente a quella meno recente
        if len(profile.locations) > 0:
            self.locations.sort(key=lambda loc: loc.utc_time, reverse=True)

        # Aggiunge il profilo
        self.profiles.append(profile)
Exemple #4
0
async def _check_message(event):  # pylint: disable = R0911
    client: Client = event.client
    msg: Message = event.message
    user_id = msg.from_id
    if user_id is None:
        return False, False

    try:
        result = await client(GetParticipantRequest(event.chat_id, user_id))
        if isinstance(result.participant, ChannelParticipantAdmin):
            return False, False
    except (ValueError, TypeError, UserNotParticipantError, ChatAdminRequiredError):
        return False, False

    # no need to ban bots as they can only be added by users anyway
    user = await client.get_cached_entity(user_id)
    if user is None or user.bot:
        return False, False

    # commands used in bots to blacklist items, these will be used by admins
    # so they shouldnt be banned for it
    blacklisting_commands = [
        '/addblacklist',
    ]

    for cmd in blacklisting_commands:
        if msg.text and msg.text.startswith(cmd):
            return False, False

    db: Database = client.db
    # tld_blacklist = db.ab_tld_blacklist.get_all()

    inline_bot = msg.via_bot_id
    if inline_bot is not None:
        result = await db.blacklists.channel.get_by_value(inline_bot)
        if result:
            return db.blacklists.channel.hex_type, result.index

    if msg.buttons:
        _buttons = await msg.get_buttons()
        button: MessageButton
        for button in itertools.chain.from_iterable(_buttons):
            if button.url:
                _, chat_id, _ = await helpers.resolve_invite_link(button.url)
                result = await db.blacklists.channel.get_by_value(chat_id)
                if result:
                    return db.blacklists.channel.hex_type, result.index

                domain = await client.resolve_url(button.url)
                result = await db.blacklists.domain.get_by_value(domain)
                if result:
                    return db.blacklists.domain.hex_type, result.index

                # tld_index = await _check_tld(domain, tld_blacklist)
                # if tld_index:
                #     return db.ab_tld_blacklist.hex_type, tld_index

                face_domain = await helpers.netloc(button.url)
                result = await db.blacklists.domain.get_by_value(face_domain)
                if result:
                    return db.blacklists.domain.hex_type, result.index

                elif domain in constants.TELEGRAM_DOMAINS:
                    _entity = await client.get_cached_entity(domain)
                    if _entity:
                        result = await db.blacklists.channel.get_by_value(_entity)
                        if result:
                            return db.blacklists.channel.hex_type, result.index

    entities = msg.get_entities_text()
    for entity, text in entities:  # pylint: disable = R1702
        _, chat_id, _ = await helpers.resolve_invite_link(text)
        result = await db.blacklists.channel.get_by_value(chat_id)
        if result:
            return db.blacklists.channel.hex_type, result.index

        domain = ''
        face_domain = ''
        channel = ''
        _entity = None
        if isinstance(entity, MessageEntityUrl):
            try:
                domain = await client.resolve_url(text)
            except ValueError:
                pass
            face_domain = await helpers.netloc(text)
            if domain in constants.TELEGRAM_DOMAINS:
                # remove any query parameters like ?start=
                # replace @ since some spammers started using it, only Telegram X supports it
                url = await client.resolve_url(text, base_domain=False)
                username = url.split('?')[0].replace('@', '')
                _entity = username

        elif isinstance(entity, MessageEntityTextUrl):
            domain = await client.resolve_url(entity.url)
            face_domain = await helpers.netloc(entity.url)
            if domain in constants.TELEGRAM_DOMAINS:
                url = await client.resolve_url(entity.url, base_domain=False)
                username = url.split('?')[0].replace('@', '')
                _entity = username

        elif isinstance(entity, MessageEntityMention):
            _entity = text

        if _entity:
            try:
                try:
                    full_entity = await client.get_cached_entity(_entity)
                except (FloodWaitError, *GET_ENTITY_ERRORS):
                    full_entity = None
                if full_entity:
                    channel = full_entity.id
                    try:
                        profile_photo = await client.download_profile_photo(full_entity, bytes)
                    except constants.DOWNLOAD_ERRORS:
                        profile_photo = None
                    if profile_photo:
                        try:
                            photo_hash = await hash_photo(profile_photo)
                            for mhash in await db.blacklists.mhash.get_all():
                                if mhash and not mhash.retired:
                                    if hashes_are_similar(mhash.value, photo_hash, tolerance=2):
                                        return db.blacklists.mhash.hex_type, mhash.index
                        except UnidentifiedImageError:
                            pass

            except (*constants.GET_ENTITY_ERRORS, ChannelPrivateError):
                pass

        # urllib doesnt like urls without a protocol
        if not face_domain:
            face_domain = await helpers.netloc(f'http://{domain}')

        if domain:
            result = await db.blacklists.domain.get_by_value(domain)
            if result:
                return db.blacklists.domain.hex_type, result.index
            # else:
            # tld_index = await _check_tld(domain, tld_blacklist)
            # if tld_index:
            #     return db.ab_tld_blacklist.hex_type, tld_index

        if face_domain:
            result = await db.blacklists.domain.get_by_value(face_domain)
            if result:
                return db.blacklists.domain.hex_type, result.index
            # else:
            # tld_index = await _check_tld(face_domain, tld_blacklist)
            # if tld_index:
            #     return db.ab_tld_blacklist.hex_type, tld_index

        if channel:
            result = await db.blacklists.channel.get_by_value(channel)
            if result:
                return db.blacklists.channel.hex_type, result.index

    if msg.raw_text:
        for string in await db.blacklists.string.get_all():
            if string.value in msg.raw_text and not string.retired:
                return db.blacklists.string.hex_type, string.index

    if msg.file:
        # avoid a DoS when getting large files
        ten_mib = (1024 ** 2) * 10
        # Only download files to avoid downloading photos
        if msg.document and msg.file.size < ten_mib:
            try:
                dl_file = await msg.download_media(bytes)
            except constants.DOWNLOAD_ERRORS:
                dl_file = None
            if dl_file:
                filehash = helpers.hash_file(dl_file)
                result = await db.blacklists.file.get_by_value(filehash)
                if result:
                    return db.blacklists.file.hex_type, result.index
        else:
            pass

    if msg.photo:
        try:
            dl_photo = await msg.download_media(bytes)
        except constants.DOWNLOAD_ERRORS:
            dl_photo = None
        if dl_photo:
            try:
                photo_hash = await hash_photo(dl_photo)
            except UnidentifiedImageError:
                photo_hash = None
            if photo_hash:
                for mhash in await db.blacklists.mhash.get_all():
                    if not mhash.retired:
                        if hashes_are_similar(mhash.value, photo_hash, tolerance=2):
                            return db.blacklists.mhash.hex_type, mhash.index

    return False, False