Exemple #1
0
    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')

        if username and password:
            self.user_cache = authenticate(username=username,
                                           password=password)
            key, timeout = generate_key(self.request, username, 'login')
            attempts, timeout = set_attempts_to_cache(key, timeout)

            if self.user_cache is None or attempts > 3 or (
                    settings.SECURITY_OWASP_AT_002
                    and not self.user_cache.is_active):
                if attempts > 3:
                    logger.warning(
                        'Ignoring login request from user "%s", %s attempts lock will expire in %s seconds.',
                        username, attempts, timeout)
                    if not settings.SECURITY_OWASP_AT_002:
                        self.error_messages['invalid_login'] = _(
                            'You made %(attempts)s wrong login attempts, all '
                            'further attempts will be ignored for %(timeout)s '
                            'seconds.') % {
                                'attempts': attempts,
                                'timeout': timeout
                            }

                raise forms.ValidationError(
                    self.error_messages['invalid_login'],
                    code='invalid_login',
                    params={'username': self.username_field.verbose_name})
            elif not self.user_cache.is_active:
                raise forms.ValidationError(self.error_messages['inactive'],
                                            code='inactive')

        return self.cleaned_data
Exemple #2
0
    def clean_email(self, *args, **kwargs):
        """
        We never raise an ValidationError, because user Enumeration and Guessable User Account OWASP-AT-002.
        Change this behaviour with settings.SECURITY_OWASP_AT_002.
        """
        email = self.cleaned_data['email']
        users = User.objects.filter(
            email__iexact=email,
            is_active=True).exclude(password=UNUSABLE_PASSWORD)
        self.users_cache = []

        # Check for valid user:
        if users:
            key, timeout = generate_key(self.request, email, 'forgot')
            attempts, timeout = set_attempts_to_cache(key, timeout)
            # Don't allow a password reset if user is trying more than 2 time in calculated timeout
            if attempts > 2:
                logger.warning(
                    'Ignoring password reset request from user "%s", %s attempts lock will expire in %s '
                    'seconds.', email, attempts, timeout)
                if settings.SECURITY_OWASP_AT_002:
                    return email
                else:
                    raise forms.ValidationError(
                        _('You have requested password reset %(attempts)s times. '
                          'All further attempts will be ignored for %(timeout)s '
                          'seconds.') % {
                              'attempts': attempts,
                              'timeout': timeout
                          })
        else:
            logger.warning(
                'Ignoring password reset request from invalid user "%s"',
                email)
            if settings.SECURITY_OWASP_AT_002:
                return email
            else:
                raise forms.ValidationError(
                    _("That email address doesn't have an associated user account. Are you "
                      "sure you've registered?"))

        # A valid user is part of a self.users_cache list used in save()
        # noinspection PyAttributeOutsideInit
        self.users_cache = users

        return email