diff -r b33d4705456a django/contrib/auth/forms.py
|
a
|
b
|
|
| 52 | 52 | """ |
| 53 | 53 | username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$', |
| 54 | 54 | help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."), |
| 55 | | error_messages = {'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")}) |
| | 55 | error_messages = { |
| | 56 | 'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters."), |
| | 57 | 'duplicate': _("A user with that username already exists."), |
| | 58 | }) |
| 56 | 59 | password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput) |
| 57 | 60 | password2 = forms.CharField(label=_("Password confirmation"), widget=forms.PasswordInput, |
| 58 | | help_text = _("Enter the same password as above, for verification.")) |
| | 61 | help_text = _("Enter the same password as above, for verification."), |
| | 62 | error_messages = {'mismatch': _("The two password fields didn't match.")}) |
| 59 | 63 | |
| 60 | 64 | class Meta: |
| 61 | 65 | model = User |
| … |
… |
|
| 67 | 71 | User.objects.get(username=username) |
| 68 | 72 | except User.DoesNotExist: |
| 69 | 73 | return username |
| 70 | | raise forms.ValidationError(_("A user with that username already exists.")) |
| | 74 | raise forms.ValidationError(self.fields['username'].error_messages['duplicate']) |
| 71 | 75 | |
| 72 | 76 | def clean_password2(self): |
| 73 | 77 | password1 = self.cleaned_data.get("password1", "") |
| 74 | 78 | password2 = self.cleaned_data["password2"] |
| 75 | 79 | if password1 != password2: |
| 76 | | raise forms.ValidationError(_("The two password fields didn't match.")) |
| | 80 | raise forms.ValidationError(self.fields['password2'].error_messages['mismatch']) |
| 77 | 81 | return password2 |
| 78 | 82 | |
| 79 | 83 | def save(self, commit=True): |
| … |
… |
|
| 109 | 113 | username = forms.CharField(label=_("Username"), max_length=30) |
| 110 | 114 | password = forms.CharField(label=_("Password"), widget=forms.PasswordInput) |
| 111 | 115 | |
| | 116 | error_messages = { |
| | 117 | 'invalid_login': _("Please enter a correct username and password. Note that both fields are case-sensitive."), |
| | 118 | 'inactive': _("This account is inactive."), |
| | 119 | 'nocookies': _("Your Web browser doesn't appear to have cookies enabled. " |
| | 120 | "Cookies are required for logging in."), |
| | 121 | } |
| | 122 | |
| 112 | 123 | def __init__(self, request=None, *args, **kwargs): |
| 113 | 124 | """ |
| 114 | 125 | If request is passed in, the form will validate that cookies are |
| … |
… |
|
| 127 | 138 | if username and password: |
| 128 | 139 | self.user_cache = authenticate(username=username, password=password) |
| 129 | 140 | if self.user_cache is None: |
| 130 | | raise forms.ValidationError(_("Please enter a correct username and password. Note that both fields are case-sensitive.")) |
| | 141 | raise forms.ValidationError(self.error_messages['invalid_login']) |
| 131 | 142 | elif not self.user_cache.is_active: |
| 132 | | raise forms.ValidationError(_("This account is inactive.")) |
| | 143 | raise forms.ValidationError(self.error_messages['inactive']) |
| 133 | 144 | self.check_for_test_cookie() |
| 134 | 145 | return self.cleaned_data |
| 135 | 146 | |
| 136 | 147 | def check_for_test_cookie(self): |
| 137 | 148 | if self.request and not self.request.session.test_cookie_worked(): |
| 138 | | raise forms.ValidationError( |
| 139 | | _("Your Web browser doesn't appear to have cookies enabled. " |
| 140 | | "Cookies are required for logging in.")) |
| | 149 | raise forms.ValidationError(self.error_messages['nocookies']) |
| 141 | 150 | |
| 142 | 151 | def get_user_id(self): |
| 143 | 152 | if self.user_cache: |
| … |
… |
|
| 148 | 157 | return self.user_cache |
| 149 | 158 | |
| 150 | 159 | class PasswordResetForm(forms.Form): |
| 151 | | email = forms.EmailField(label=_("E-mail"), max_length=75) |
| | 160 | email = forms.EmailField(label=_("E-mail"), max_length=75, |
| | 161 | error_messages={ |
| | 162 | 'unknown': _("That e-mail address doesn't have an associated user account. " |
| | 163 | "Are you sure you've registered?"), |
| | 164 | 'unusable': _("The user account associated with this e-mail address cannot reset the password."), |
| | 165 | }) |
| 152 | 166 | |
| 153 | 167 | def clean_email(self): |
| 154 | 168 | """ |
| … |
… |
|
| 159 | 173 | email__iexact=email, |
| 160 | 174 | is_active=True) |
| 161 | 175 | if not len(self.users_cache): |
| 162 | | raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?")) |
| | 176 | raise forms.ValidationError(self.fields['email'].error_messages['unknown']) |
| 163 | 177 | if any((user.password == UNUSABLE_PASSWORD) for user in self.users_cache): |
| 164 | | raise forms.ValidationError(_("The user account associated with this e-mail address cannot reset the password.")) |
| | 178 | raise forms.ValidationError(self.fields['email'].error_messages['unusable']) |
| 165 | 179 | return email |
| 166 | 180 | |
| 167 | 181 | def save(self, domain_override=None, |
| … |
… |
|
| 201 | 215 | entering the old password |
| 202 | 216 | """ |
| 203 | 217 | new_password1 = forms.CharField(label=_("New password"), widget=forms.PasswordInput) |
| 204 | | new_password2 = forms.CharField(label=_("New password confirmation"), widget=forms.PasswordInput) |
| | 218 | new_password2 = forms.CharField(label=_("New password confirmation"), |
| | 219 | widget=forms.PasswordInput, |
| | 220 | error_messages={'mismatch': _("The two password fields didn't match."), }) |
| 205 | 221 | |
| 206 | 222 | def __init__(self, user, *args, **kwargs): |
| 207 | 223 | self.user = user |
| … |
… |
|
| 212 | 228 | password2 = self.cleaned_data.get('new_password2') |
| 213 | 229 | if password1 and password2: |
| 214 | 230 | if password1 != password2: |
| 215 | | raise forms.ValidationError(_("The two password fields didn't match.")) |
| | 231 | raise forms.ValidationError(self.fields['new_password2'].error_messages['mismatch']) |
| 216 | 232 | return password2 |
| 217 | 233 | |
| 218 | 234 | def save(self, commit=True): |
| … |
… |
|
| 226 | 242 | A form that lets a user change his/her password by entering |
| 227 | 243 | their old password. |
| 228 | 244 | """ |
| 229 | | old_password = forms.CharField(label=_("Old password"), widget=forms.PasswordInput) |
| | 245 | old_password = forms.CharField(label=_("Old password"), widget=forms.PasswordInput, |
| | 246 | error_messages={'incorrect': _("Your old password was entered incorrectly. Please enter it again.")}) |
| 230 | 247 | |
| 231 | 248 | def clean_old_password(self): |
| 232 | 249 | """ |
| … |
… |
|
| 234 | 251 | """ |
| 235 | 252 | old_password = self.cleaned_data["old_password"] |
| 236 | 253 | if not self.user.check_password(old_password): |
| 237 | | raise forms.ValidationError(_("Your old password was entered incorrectly. Please enter it again.")) |
| | 254 | raise forms.ValidationError(self.fields['old_password'].error_messages['incorrect']) |
| 238 | 255 | return old_password |
| 239 | 256 | PasswordChangeForm.base_fields.keyOrder = ['old_password', 'new_password1', 'new_password2'] |
| 240 | 257 | |
diff -r b33d4705456a django/contrib/auth/tests/forms.py
|
a
|
b
|
|
| 1 | 1 | from __future__ import with_statement |
| 2 | 2 | import os |
| 3 | 3 | from django.core import mail |
| | 4 | from django.forms.fields import Field, EmailField |
| 4 | 5 | from django.contrib.auth.models import User |
| 5 | 6 | from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm |
| | 7 | from django.utils.encoding import force_unicode |
| 6 | 8 | from django.test import TestCase |
| 7 | 9 | |
| 8 | 10 | |
| … |
… |
|
| 19 | 21 | form = UserCreationForm(data) |
| 20 | 22 | self.assertFalse(form.is_valid()) |
| 21 | 23 | self.assertEqual(form["username"].errors, |
| 22 | | [u'A user with that username already exists.']) |
| | 24 | [force_unicode(form.fields['username'].error_messages['duplicate']),]) |
| 23 | 25 | |
| 24 | 26 | def test_invalid_data(self): |
| 25 | 27 | data = { |
| … |
… |
|
| 30 | 32 | form = UserCreationForm(data) |
| 31 | 33 | self.assertFalse(form.is_valid()) |
| 32 | 34 | self.assertEqual(form["username"].errors, |
| 33 | | [u'This value may contain only letters, numbers and @/./+/-/_ characters.']) |
| 34 | | |
| | 35 | [force_unicode(form.fields['username'].error_messages['invalid']),]) |
| 35 | 36 | |
| 36 | 37 | def test_password_verification(self): |
| 37 | 38 | # The verification password is incorrect. |
| … |
… |
|
| 43 | 44 | form = UserCreationForm(data) |
| 44 | 45 | self.assertFalse(form.is_valid()) |
| 45 | 46 | self.assertEqual(form["password2"].errors, |
| 46 | | [u"The two password fields didn't match."]) |
| 47 | | |
| | 47 | [force_unicode(form.fields['password2'].error_messages['mismatch']),]) |
| 48 | 48 | |
| 49 | 49 | def test_both_passwords(self): |
| 50 | 50 | # One (or both) passwords weren't given |
| … |
… |
|
| 52 | 52 | form = UserCreationForm(data) |
| 53 | 53 | self.assertFalse(form.is_valid()) |
| 54 | 54 | self.assertEqual(form['password1'].errors, |
| 55 | | [u'This field is required.']) |
| | 55 | [force_unicode(Field.default_error_messages['required']),]) |
| 56 | 56 | self.assertEqual(form['password2'].errors, |
| 57 | | [u'This field is required.']) |
| 58 | | |
| | 57 | [force_unicode(Field.default_error_messages['required']),]) |
| 59 | 58 | |
| 60 | 59 | data['password2'] = 'test123' |
| 61 | 60 | form = UserCreationForm(data) |
| 62 | 61 | self.assertFalse(form.is_valid()) |
| 63 | 62 | self.assertEqual(form['password1'].errors, |
| 64 | | [u'This field is required.']) |
| | 63 | [force_unicode(Field.default_error_messages['required']),]) |
| 65 | 64 | |
| 66 | 65 | def test_success(self): |
| 67 | 66 | # The success case. |
| … |
… |
|
| 91 | 90 | form = AuthenticationForm(None, data) |
| 92 | 91 | self.assertFalse(form.is_valid()) |
| 93 | 92 | self.assertEqual(form.non_field_errors(), |
| 94 | | [u'Please enter a correct username and password. Note that both fields are case-sensitive.']) |
| | 93 | [force_unicode(form.error_messages['invalid_login']),]) |
| 95 | 94 | |
| 96 | 95 | def test_inactive_user(self): |
| 97 | 96 | # The user is inactive. |
| … |
… |
|
| 102 | 101 | form = AuthenticationForm(None, data) |
| 103 | 102 | self.assertFalse(form.is_valid()) |
| 104 | 103 | self.assertEqual(form.non_field_errors(), |
| 105 | | [u'This account is inactive.']) |
| 106 | | |
| | 104 | [force_unicode(form.error_messages['inactive']),]) |
| 107 | 105 | |
| 108 | 106 | def test_success(self): |
| 109 | 107 | # The success case |
| … |
… |
|
| 130 | 128 | form = SetPasswordForm(user, data) |
| 131 | 129 | self.assertFalse(form.is_valid()) |
| 132 | 130 | self.assertEqual(form["new_password2"].errors, |
| 133 | | [u"The two password fields didn't match."]) |
| | 131 | [force_unicode(form.fields['new_password2'].error_messages['mismatch']),]) |
| 134 | 132 | |
| 135 | 133 | def test_success(self): |
| 136 | 134 | user = User.objects.get(username='testclient') |
| … |
… |
|
| 156 | 154 | form = PasswordChangeForm(user, data) |
| 157 | 155 | self.assertFalse(form.is_valid()) |
| 158 | 156 | self.assertEqual(form["old_password"].errors, |
| 159 | | [u'Your old password was entered incorrectly. Please enter it again.']) |
| 160 | | |
| | 157 | [force_unicode(form.fields['old_password'].error_messages['incorrect']),]) |
| 161 | 158 | |
| 162 | 159 | def test_password_verification(self): |
| 163 | 160 | # The two new passwords do not match. |
| … |
… |
|
| 170 | 167 | form = PasswordChangeForm(user, data) |
| 171 | 168 | self.assertFalse(form.is_valid()) |
| 172 | 169 | self.assertEqual(form["new_password2"].errors, |
| 173 | | [u"The two password fields didn't match."]) |
| 174 | | |
| | 170 | [force_unicode(form.fields['new_password2'].error_messages['mismatch']),]) |
| 175 | 171 | |
| 176 | 172 | def test_success(self): |
| 177 | 173 | # The success case. |
| … |
… |
|
| 200 | 196 | form = UserChangeForm(data, instance=user) |
| 201 | 197 | self.assertFalse(form.is_valid()) |
| 202 | 198 | self.assertEqual(form['username'].errors, |
| 203 | | [u'This value may contain only letters, numbers and @/./+/-/_ characters.']) |
| | 199 | [force_unicode(form.fields['username'].error_messages['invalid']),]) |
| 204 | 200 | |
| 205 | 201 | def test_bug_14242(self): |
| 206 | 202 | # A regression test, introduce by adding an optimization for the |
| … |
… |
|
| 236 | 232 | form = PasswordResetForm(data) |
| 237 | 233 | self.assertFalse(form.is_valid()) |
| 238 | 234 | self.assertEqual(form['email'].errors, |
| 239 | | [u'Enter a valid e-mail address.']) |
| | 235 | [force_unicode(EmailField.default_error_messages['invalid']),]) |
| 240 | 236 | |
| 241 | 237 | def test_nonexistant_email(self): |
| 242 | 238 | # Test nonexistant email address |
| … |
… |
|
| 244 | 240 | form = PasswordResetForm(data) |
| 245 | 241 | self.assertFalse(form.is_valid()) |
| 246 | 242 | self.assertEqual(form.errors, |
| 247 | | {'email': [u"That e-mail address doesn't have an associated user account. Are you sure you've registered?"]}) |
| | 243 | {'email': [force_unicode(form.fields['email'].error_messages['unknown']),]}) |
| 248 | 244 | |
| 249 | 245 | def test_cleaned_data(self): |
| 250 | 246 | # Regression test |
diff -r b33d4705456a django/contrib/auth/tests/views.py
|
a
|
b
|
|
| 5 | 5 | |
| 6 | 6 | from django.conf import settings |
| 7 | 7 | from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME |
| 8 | | from django.contrib.auth.forms import AuthenticationForm |
| | 8 | from django.contrib.auth.forms import (AuthenticationForm, PasswordChangeForm, |
| | 9 | SetPasswordForm, AuthenticationForm, PasswordResetForm, ) |
| 9 | 10 | from django.contrib.sites.models import Site, RequestSite |
| 10 | 11 | from django.contrib.auth.models import User |
| 11 | 12 | from django.core.urlresolvers import NoReverseMatch |
| | 13 | from django.utils.html import escape |
| | 14 | from django.utils.encoding import force_unicode |
| 12 | 15 | from django.test import TestCase |
| 13 | 16 | from django.core import mail |
| 14 | 17 | from django.core.urlresolvers import reverse |
| 15 | 18 | from django.http import QueryDict |
| 16 | 19 | |
| | 20 | def _escape(proxy): |
| | 21 | """Force proxy to unicode and escape""" |
| | 22 | return escape(force_unicode(proxy)) |
| 17 | 23 | |
| 18 | 24 | class AuthViewsTestCase(TestCase): |
| 19 | 25 | """ |
| … |
… |
|
| 80 | 86 | response = self.client.get('/password_reset/') |
| 81 | 87 | self.assertEqual(response.status_code, 200) |
| 82 | 88 | response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'}) |
| 83 | | self.assertContains(response, "That e-mail address doesn't have an associated user account") |
| | 89 | self.assertContains(response, _escape(PasswordResetForm.base_fields['email'].error_messages['unknown'])) |
| 84 | 90 | self.assertEqual(len(mail.outbox), 0) |
| 85 | 91 | |
| 86 | 92 | def test_email_found(self): |
| … |
… |
|
| 171 | 177 | response = self.client.post(path, {'new_password1': 'anewpassword', |
| 172 | 178 | 'new_password2':' x'}) |
| 173 | 179 | self.assertEqual(response.status_code, 200) |
| 174 | | self.assertTrue("The two password fields didn't match" in response.content) |
| | 180 | self.assertTrue(_escape(SetPasswordForm.base_fields['new_password2'].error_messages['mismatch']) in response.content) |
| 175 | 181 | |
| 176 | 182 | class ChangePasswordTest(AuthViewsTestCase): |
| 177 | 183 | |
| … |
… |
|
| 182 | 188 | } |
| 183 | 189 | ) |
| 184 | 190 | self.assertEqual(response.status_code, 200) |
| 185 | | self.assertTrue("Please enter a correct username and password. Note that both fields are case-sensitive." in response.content) |
| | 191 | self.assertTrue(_escape(AuthenticationForm.error_messages['invalid_login']) in response.content) |
| 186 | 192 | |
| 187 | 193 | def logout(self): |
| 188 | 194 | response = self.client.get('/logout/') |
| … |
… |
|
| 196 | 202 | } |
| 197 | 203 | ) |
| 198 | 204 | self.assertEqual(response.status_code, 200) |
| 199 | | self.assertTrue("Your old password was entered incorrectly. Please enter it again." in response.content) |
| | 205 | self.assertTrue(_escape(PasswordChangeForm.base_fields['old_password'].error_messages['incorrect']) in response.content) |
| 200 | 206 | |
| 201 | 207 | def test_password_change_fails_with_mismatched_passwords(self): |
| 202 | 208 | self.login() |
| … |
… |
|
| 207 | 213 | } |
| 208 | 214 | ) |
| 209 | 215 | self.assertEqual(response.status_code, 200) |
| 210 | | self.assertTrue("The two password fields didn't match." in response.content) |
| | 216 | self.assertTrue(_escape(SetPasswordForm.base_fields['new_password2'].error_messages['mismatch']) in response.content) |
| 211 | 217 | |
| 212 | 218 | def test_password_change_succeeds(self): |
| 213 | 219 | self.login() |