Projet

Général

Profil

0001-report-all-password-requirements-at-once-on-password.patch

Benjamin Dauvergne, 24 mars 2015 16:52

Télécharger (5,94 ko)

Voir les différences:

Subject: [PATCH 1/2] report all password requirements at once on password
 input (fixes #6805)

 src/authentic2/registration_backend/forms.py |  9 +++++---
 src/authentic2/validators.py                 | 33 +++++++++++++++++++++++-----
 2 files changed, 33 insertions(+), 9 deletions(-)
src/authentic2/registration_backend/forms.py
68 68
            send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
69 69
                      [data['email']], fail_silently=True)
70 70

  
71 71
class RegistrationCompletionForm(forms.UserAttributeFormMixin, Form):
72 72
    error_css_class = 'form-field-error'
73 73
    required_css_class = 'form-field-required'
74 74

  
75 75
    password1 = CharField(widget=PasswordInput, label=_("Password"),
76
            validators=[validators.validate_password])
76
            validators=[validators.validate_password],
77
            help_text=validators.password_help_text())
77 78
    password2 = CharField(widget=PasswordInput, label=_("Password (again)"))
78 79

  
79 80
    def __init__(self, *args, **kwargs):
80 81
        """
81 82
        Inject required fields in registration form
82 83
        """
83 84
        super(RegistrationCompletionForm, self).__init__(*args, **kwargs)
84 85
        User = compat.get_user_model()
......
193 194
                return ret
194 195
            self.user.save = save
195 196
        return ret
196 197

  
197 198

  
198 199
class SetPasswordForm(PasswordResetMixin, auth_forms.SetPasswordForm):
199 200
    new_password1 = CharField(label=_("New password"),
200 201
                                    widget=PasswordInput,
201
                                    validators=[validators.validate_password])
202
                                    validators=[validators.validate_password],
203
                                    help_text=validators.password_help_text())
202 204

  
203 205

  
204 206
class PasswordChangeForm(forms.NextUrlFormMixin, PasswordResetMixin,
205 207
        auth_forms.PasswordChangeForm):
206 208
    new_password1 = CharField(label=_("New password"),
207 209
                                    widget=PasswordInput,
208
                                    validators=[validators.validate_password])
210
                                    validators=[validators.validate_password],
211
                                    help_text=validators.password_help_text())
209 212

  
210 213

  
src/authentic2/validators.py
1 1
from __future__ import unicode_literals
2 2
import string
3 3
import re
4
import six
4 5

  
5 6
import smtplib
6 7

  
7
from django.utils.translation import ugettext_lazy as _
8
from django.utils.translation import ugettext_lazy as _, ugettext
8 9
from django.utils.encoding import force_text
9 10
from django.core.exceptions import ValidationError
11
from django.utils.functional import lazy
10 12

  
11 13
import socket
12 14
import dns.resolver
13 15
import dns.exception
14 16

  
15 17
from . import app_settings
16 18

  
17 19
# copied from http://www.djangotips.com/real-email-validation
......
74 76
email_validator = EmailValidator()
75 77

  
76 78
def validate_password(password):
77 79
    password_set = set(password)
78 80
    digits = set(string.digits)
79 81
    lower = set(string.lowercase)
80 82
    upper = set(string.uppercase)
81 83
    punc = set(string.punctuation)
84
    errors = []
82 85

  
83 86
    if not password:
84 87
        return
85 88
    min_len = app_settings.A2_PASSWORD_POLICY_MIN_LENGTH
86 89
    if len(password) < min_len:
87
        raise ValidationError(_('password must contain at least %d '
88
            'characters') % min_len)
90
        errors.append(ValidationError(_('password must contain at least %d '
91
            'characters') % min_len))
89 92

  
90 93
    class_count = 0
91 94
    for cls in (digits, lower, upper, punc):
92 95
        if not password_set.isdisjoint(cls):
93 96
            class_count += 1
94 97
    min_class_count = app_settings.A2_PASSWORD_POLICY_MIN_CLASSES
95 98
    if class_count < min_class_count:
96
        raise ValidationError(_('password must contain characters '
99
        errors.append(ValidationError(_('password must contain characters '
97 100
            'from at least %d classes among: lowercase letters, '
98
            'uppercase letters, digits, and punctuations') % min_class_count)
101
            'uppercase letters, digits, and punctuations') % min_class_count))
99 102
    if app_settings.A2_PASSWORD_POLICY_REGEX:
100 103
        if not re.match(app_settings.A2_PASSWORD_POLICY_REGEX, password):
101 104
            msg = app_settings.A2_PASSWORD_POLICY_REGEX_ERROR_MSG
102 105
            msg = msg or _('your password dit not match the regular expession %s') % app_settings.A2_PASSWORD_POLICY_REGEX
103
            raise ValidationError(msg)
106
            errors.append(ValidationError(msg))
107
    if errors:
108
        raise ValidationError(errors)
109

  
110
def __password_help_text_helper():
111
    if app_settings.A2_PASSWORD_POLICY_MIN_LENGTH:
112
        yield ugettext('Your password must contain at least %(min_length)d characters.') % {'min_length': app_settings.A2_PASSWORD_POLICY_MIN_LENGTH}
113
    if app_settings.A2_PASSWORD_POLICY_MIN_CLASSES:
114
        yield ugettext('Your password must contain characters from at least %(min_classes)d '
115
                'classes among: lowercase letters, uppercase letters, digits, '
116
                'and punctuations') % {'min_classes': app_settings.A2_PASSWORD_POLICY_MIN_CLASSES}
117
    if app_settings.A2_PASSWORD_POLICY_REGEX:
118
        yield ugettext(app_settings.A2_PASSWORD_POLICY_REGEX_ERROR_MSG) or \
119
                ugettext('Your password must match the regular expression: %(regexp)s') % {'regexp': app_settings.A2_PASSWORD_POLICY_REGEX}
120

  
121
def password_help_text():
122
    return ' '.join(__password_help_text_helper())
123

  
124
password_help_text = lazy(password_help_text, six.text_type)
104
-