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() |