From 98ea7bbf3fb565e2024f6e1d1ab6b476c74e1d2d Mon Sep 17 00:00:00 2001 From: Bertrand Bordage Date: Mon, 26 Feb 2018 17:37:23 +0100 Subject: [PATCH] Prevents accounts leak through the password reset form. Also displays an error on invalid e-mail submit. --- wagtail/admin/forms.py | 34 ++----------------- .../account/password_reset/done.html | 2 +- .../account/password_reset/form.html | 7 ++++ .../admin/tests/test_account_management.py | 9 ++--- 4 files changed, 14 insertions(+), 38 deletions(-) diff --git a/wagtail/admin/forms.py b/wagtail/admin/forms.py index 812c4131b9..452705fdff 100644 --- a/wagtail/admin/forms.py +++ b/wagtail/admin/forms.py @@ -2,7 +2,6 @@ import copy from itertools import groupby from django import forms -from django.contrib.auth import get_user_model from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm from django.contrib.auth.models import Group, Permission from django.core import validators @@ -85,36 +84,9 @@ class LoginForm(AuthenticationForm): class PasswordResetForm(PasswordResetForm): - email = forms.EmailField(label=ugettext_lazy("Enter your email address to reset your password"), max_length=254) - - def clean(self): - cleaned_data = super().clean() - - # Find users of this email address - UserModel = get_user_model() - email = cleaned_data.get('email') - if not email: - raise forms.ValidationError(_("Please fill your email address.")) - active_users = UserModel._default_manager.filter(email__iexact=email, is_active=True) - - if active_users.exists(): - # Check if all users of the email address are LDAP users (and give an error if they are) - found_non_ldap_user = False - for user in active_users: - if user.has_usable_password(): - found_non_ldap_user = True - break - - if not found_non_ldap_user: - # All found users are LDAP users, give error message - raise forms.ValidationError( - _("Sorry, you cannot reset your password here as your user account is managed by another server.") - ) - else: - # No user accounts exist - raise forms.ValidationError(_("This email address is not recognised.")) - - return cleaned_data + email = forms.EmailField( + label=ugettext_lazy("Enter your email address to reset your password"), + max_length=254, required=True) class CopyForm(forms.Form): diff --git a/wagtail/admin/templates/wagtailadmin/account/password_reset/done.html b/wagtail/admin/templates/wagtailadmin/account/password_reset/done.html index ac8b3112ef..1b657b4b95 100644 --- a/wagtail/admin/templates/wagtailadmin/account/password_reset/done.html +++ b/wagtail/admin/templates/wagtailadmin/account/password_reset/done.html @@ -12,6 +12,6 @@ {% block furniture %}

{% trans "Check your email" %}

-

{% trans "A link to reset your password has been emailed to you." %}

+

{% trans "A link to reset your password has been emailed to you if an account exists for this address." %}

{% endblock %} diff --git a/wagtail/admin/templates/wagtailadmin/account/password_reset/form.html b/wagtail/admin/templates/wagtailadmin/account/password_reset/form.html index 292b4c3cbe..811035e2fe 100644 --- a/wagtail/admin/templates/wagtailadmin/account/password_reset/form.html +++ b/wagtail/admin/templates/wagtailadmin/account/password_reset/form.html @@ -30,6 +30,13 @@
{{ form.email.label_tag }} {{ form.email }} +
+
    + {% for error in form.email.errors %} +
  • {{ error }}
  • + {% endfor %} +
+
  • diff --git a/wagtail/admin/tests/test_account_management.py b/wagtail/admin/tests/test_account_management.py index b15ee2fa85..9ea6955a29 100644 --- a/wagtail/admin/tests/test_account_management.py +++ b/wagtail/admin/tests/test_account_management.py @@ -468,12 +468,9 @@ class TestPasswordReset(TestCase, WagtailTestUtils): } response = self.client.post(reverse('wagtailadmin_password_reset'), post_data) - # Check that the user wasn't redirected - self.assertEqual(response.status_code, 200) - - # Check that a validation error was raised - self.assertTrue('__all__' in response.context['form'].errors.keys()) - self.assertTrue("This email address is not recognised." in response.context['form'].errors['__all__']) + # Check that the user was redirected to the done page + self.assertRedirects(response, + reverse('wagtailadmin_password_reset_done')) # Check that an email was not sent self.assertEqual(len(mail.outbox), 0)