예제 #1
0
def kick_user_and_raise_max_tries(user: User):
    user.kick()
    logger.info(f'{user} has been kicked for failing captcha auth too may '
                'times')
    raise MaxCaptchaTriesError(
        'You have been kicked for failing the captcha authentication too '
        'many times',
        is_kick=True)
예제 #2
0
def ban_user_and_raise_max_tries(user: User, duration):
    now = datetime.utcnow()
    user.ban(end_date=now + duration, reason='Too many captcha failures')
    logger.info(
        f'{user} has been banned until {now + duration} for failing captcha '
        'auth too may times')
    raise MaxCaptchaTriesError(
        f'You have been banned until {now+duration}'
        ' for failing the captcha'
        'authentication too many times',
        is_ban=True,
        end_date=now + duration)
예제 #3
0
    def filter(self, message):
        user = User(self._db_man, message.from_user)
        if user.is_active:
            return True

        logger.debug(
            f'{user}\'s Message ({message}) was filtered because he\'s '
            'not active')
        return False
예제 #4
0
    def send_message(self, update_or_message, msg):
        if isinstance(update_or_message, Update):
            message = update_or_message.message
        elif isinstance(update_or_message, Message):
            message = update_or_message

        user = User(self._db_man, message.from_user)
        if self._msg_broker:
            self._msg_broker.send_or_forward_msg(user, msg)
        else:
            update_or_message.reply_text(msg)
예제 #5
0
    def filter(self, message):
        user = User(self._db_man, message.from_user)
        if not user.is_banned:
            return True

        logger.debug(f'banned user {user} has tried to use the bot')

        if not self._sent_warnings[user.id]:
            self.send_message(message, 'You have been banned from the bot')
            self._sent_warnings[user.id] = True
        return False
예제 #6
0
    def filter(self, update):
        user = User(self._db_man, update.from_user)
        if user.captcha_status.passed:
            return True

        # Proceed with captcha verification
        if user.captcha_status.current_value:
            try:
                self._captcha_manager.submit_captcha(user, update.text)
                if user.captcha_status.passed:
                    logger.info(f'{user} has passed the captcha challenge')
                    user_join(user, self._config, self._msg_broker)
                    return False
                else:
                    self.send_message(update, 'Wrong captcha')
                    max_tries = self._captcha_manager\
                        ._config["Captcha"]["MaxCaptchaTries"]
                    logger.info(f'{user} has failed the captcha challenge'
                                f' ({user.captcha_status.failed_attempts}/'
                                f'{max_tries})')
            except MaxCaptchaTriesError as e:
                self.send_message(update, e.reason)
            except CaptchaFloodError:
                try:
                    if self._last_attempt_dict[user.id]['sent_warning']:
                        logger.info(f'{user} is flooding the captcha')
                    else:
                        self.send_message(
                            update, 'You can try once every '
                            f'{self._captcha_manager.delay}')
                except KeyError:
                    self.send_message(
                        update, 'You can try once every '
                        f'{self._captcha_manager.delay}')
                finally:
                    self._last_attempt_dict[user.id] = {'sent_warning': True}
                    return False
        captcha_img = self._captcha_manager.start_captcha_session(user)
        if captcha_img:
            logger.info(f'{user} generated captcha '
                        f'{user.captcha_status.current_value}')
            update.reply_photo(captcha_img,
                               caption='Please complete the captcha challenge '
                               '(no spaces)')
            self._last_attempt_dict[user.id] = {'sent_warning': False}
        return False
예제 #7
0
    def filter(self, message):
        user = User(self._db_man, message.from_user)
        try:
            # Take the first word an drop the initial slash
            cmd = message.text.split()[0][1:]
            cmd_dict = self._command_dicts[cmd]
            if cmd_dict['permissions_required'] in user.permissions:
                return True
            else:
                self.send_message(
                    message, 'You do not have the necessary permissions '
                    'to execute this command')
                logger.warning(f'{user} has tried to execute {cmd} without '
                               'the appropriate permissions')
        except (KeyError, IndexError):

            self.send_message(message, 'Unknown command')
        return False
예제 #8
0
    def filter(self, message):
        user = User(self._db_man, message.from_user)
        now = datetime.utcnow()

        if now - self._last_cleanup_time > self._cleanup_time_delta:
            self._last_message_dict = {
                user_id: data
                for (user_id, data) in self._last_message_dict.items() if now -
                data['last_msg_time'] < self._inactivity_cleanup_time_delta
            }

        if Permissions.BYPASS_ANTIFLOOD in user.permissions:
            return True

        try:
            delay = user.chat_delay
        except ValueError:
            delay = self._default_time_delta

        try:
            elapsed_time = now - \
                    self._last_message_dict[user.id]['last_msg_time']
            if elapsed_time > delay:
                # sent_warning is necessary to avoid a DOS by malicious
                # users that try to flood anyway
                self._last_message_dict[user.id] = {
                    'last_msg_time': now,
                    'sent_warning': False
                }
                return True
        except KeyError:
            self._last_message_dict[user.id] = {
                'last_msg_time': now,
                'sent_warning': False
            }
            return True

        if not self._last_message_dict[user.id]['sent_warning']:
            logger.warning(f'{user} is trying to flood the chat')
            self.send_message(
                message, f'You must wait {delay - elapsed_time} '
                'before sending another message or command')
        return False
예제 #9
0
    def filter(self, update):
        user = User(self._db_man, update.message.from_user)
        data_filter = None

        for perm in set(self._filter_map) & set(user.permissions):
            perm_data = self._filter_map[perm]
            if data_filter:
                data_filter |= perm_data['filter']
            else:
                data_filter = perm_data['filter']

        if data_filter and data_filter(update):
            return True

        for perm, data in self._filter_map.items():
            if data['filter'](update):
                self.send_message(update, data['user_msg'])
                logger.debug(data['log_msg'].format(user_log_str=user,
                                                    user_perm=user.permissions,
                                                    message=update.message))
                return False

        self.send_message(update, 'Unsupported message type')
        return False
예제 #10
0
def load_role_users_from_config_section(database_manager, config):
    for role_name in config['Roles'].sections:
        for user_id in config['Roles'][role_name]['UserIds']:
            User(database_manager, int(user_id)).role = \
                Role(database_manager, role_name)