diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index aa33640..4bff8cd 100644
a
|
b
|
|
1 | | from django.contrib.auth.models import User |
| 1 | from django.contrib.auth.models import User, UNUSABLE_PASSWORD |
2 | 2 | from django.contrib.auth import authenticate |
3 | 3 | from django.contrib.auth.tokens import default_token_generator |
4 | 4 | from django.contrib.sites.models import get_current_site |
… |
… |
class PasswordResetForm(forms.Form):
|
112 | 112 | """ |
113 | 113 | email = self.cleaned_data["email"] |
114 | 114 | self.users_cache = User.objects.filter(email__iexact=email) |
115 | | if len(self.users_cache) == 0: |
| 115 | if self.users_cache.filter(password=UNUSABLE_PASSWORD).exists(): |
| 116 | raise forms.ValidationError(_("The user account associated with this email address cannot reset it's password.")) |
| 117 | if self.users_cache.exists(): |
116 | 118 | raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?")) |
117 | 119 | return email |
118 | 120 | |
diff --git a/django/contrib/auth/tests/forms.py b/django/contrib/auth/tests/forms.py
index 5aa49e0..e0561dc 100644
a
|
b
|
class PasswordResetFormTest(TestCase):
|
250 | 250 | self.assertEqual(user.email, 'tesT@example.com') |
251 | 251 | user = User.objects.create_user('forms_test3', 'tesT', 'test') |
252 | 252 | self.assertEqual(user.email, 'tesT') |
| 253 | |
| 254 | def test_unusable_password(self): |
| 255 | user = User.objects.create_user('testuser', 'test@example.com', 'test') |
| 256 | data = {"email": "test@example.com"} |
| 257 | form = PasswordResetForm(data) |
| 258 | self.assertTrue(form.is_valid()) |
| 259 | user.set_unusable_password() |
| 260 | user.save() |
| 261 | form = PasswordResetForm(data) |
| 262 | self.assertFalse(form.is_valid()) |
| 263 | self.assertEqual(form["email"].errors, |
| 264 | [u"The user account associated with this email address is not allowed to reset it's password."]) |
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index f45c61a..a64caec 100644
a
|
b
|
includes a few other useful built-in views located in
|
945 | 945 | |
946 | 946 | * ``form``: The form for resetting the user's password. |
947 | 947 | |
| 948 | .. note:: |
| 949 | |
| 950 | Users flagged with an unusable password (see |
| 951 | :meth:`~django.contrib.auth.models.User.set_unusable_password()` |
| 952 | will not be able to request a password reset. This is done to |
| 953 | prevent a password reset when using an external authentication |
| 954 | source like LDAP. |
| 955 | |
948 | 956 | .. function:: views.password_reset_done(request[, template_name]) |
949 | 957 | |
950 | 958 | The page shown after a user has reset their password. |