Commit c6424efb authored by Vincenzo Pandolfo's avatar Vincenzo Pandolfo Committed by Tim Graham
Browse files

[1.9.x] Fixed #26334 -- Removed whitespace stripping from contrib.auth password fields.

Backport of d0fe6c91 from master
parent b50e4ffe
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -69,9 +69,11 @@ class UserCreationForm(forms.ModelForm):
        'password_mismatch': _("The two password fields didn't match."),
    }
    password1 = forms.CharField(label=_("Password"),
        strip=False,
        widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password confirmation"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=_("Enter the same password as before, for verification."))

    class Meta:
@@ -127,7 +129,7 @@ class AuthenticationForm(forms.Form):
    username/password logins.
    """
    username = forms.CharField(max_length=254)
    password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
    password = forms.CharField(label=_("Password"), strip=False, widget=forms.PasswordInput)

    error_messages = {
        'invalid_login': _("Please enter a correct %(username)s and password. "
@@ -269,8 +271,10 @@ class SetPasswordForm(forms.Form):
    }
    new_password1 = forms.CharField(label=_("New password"),
                                    widget=forms.PasswordInput,
                                    strip=False,
                                    help_text=password_validation.password_validators_help_text_html())
    new_password2 = forms.CharField(label=_("New password confirmation"),
                                    strip=False,
                                    widget=forms.PasswordInput)

    def __init__(self, user, *args, **kwargs):
@@ -307,6 +311,7 @@ class PasswordChangeForm(SetPasswordForm):
                                "Please enter it again."),
    })
    old_password = forms.CharField(label=_("Old password"),
                                   strip=False,
                                   widget=forms.PasswordInput)

    field_order = ['old_password', 'new_password1', 'new_password2']
@@ -335,11 +340,13 @@ class AdminPasswordChangeForm(forms.Form):
    password1 = forms.CharField(
        label=_("Password"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=password_validation.password_validators_help_text_html(),
    )
    password2 = forms.CharField(
        label=_("Password (again)"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=_("Enter the same password as before, for verification."),
    )

+6 −0
Original line number Diff line number Diff line
@@ -19,3 +19,9 @@ Bugfixes

* Fixed data loss on SQLite where ``DurationField`` values with fractional
  seconds could be saved as ``None`` (:ticket:`26324`).

* The forms in ``contrib.auth`` no longer strip trailing and leading whitespace
  from the password fields (:ticket:`26334`). The change requires users who set
  their password to something with such whitespace after a site updated to
  Django 1.9 to reset their password. It provides backwards-compatibility for
  earlier versions of Django.
+56 −0
Original line number Diff line number Diff line
@@ -169,6 +169,17 @@ class UserCreationFormTest(TestDataMixin, TestCase):
        form = CustomUserCreationForm(data)
        self.assertTrue(form.is_valid())

    def test_password_whitespace_not_stripped(self):
        data = {
            'username': 'testuser',
            'password1': '   testpassword   ',
            'password2': '   testpassword   ',
        }
        form = UserCreationForm(data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data['password1'], data['password1'])
        self.assertEqual(form.cleaned_data['password2'], data['password2'])


@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'])
class AuthenticationFormTest(TestDataMixin, TestCase):
@@ -279,6 +290,15 @@ class AuthenticationFormTest(TestDataMixin, TestCase):
        form = CustomAuthenticationForm()
        self.assertEqual(form.fields['username'].label, "")

    def test_password_whitespace_not_stripped(self):
        data = {
            'username': 'testuser',
            'password': ' pass ',
        }
        form = AuthenticationForm(None, data)
        form.is_valid()  # Not necessary to have valid credentails for the test.
        self.assertEqual(form.cleaned_data['password'], data['password'])


@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'])
class SetPasswordFormTest(TestDataMixin, TestCase):
@@ -330,6 +350,17 @@ class SetPasswordFormTest(TestDataMixin, TestCase):
            form["new_password2"].errors
        )

    def test_password_whitespace_not_stripped(self):
        user = User.objects.get(username='testclient')
        data = {
            'new_password1': '   password   ',
            'new_password2': '   password   ',
        }
        form = SetPasswordForm(user, data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data['new_password1'], data['new_password1'])
        self.assertEqual(form.cleaned_data['new_password2'], data['new_password2'])


@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'])
class PasswordChangeFormTest(TestDataMixin, TestCase):
@@ -381,6 +412,20 @@ class PasswordChangeFormTest(TestDataMixin, TestCase):
        self.assertEqual(list(PasswordChangeForm(user, {}).fields),
                         ['old_password', 'new_password1', 'new_password2'])

    def test_password_whitespace_not_stripped(self):
        user = User.objects.get(username='testclient')
        user.set_password('   oldpassword   ')
        data = {
            'old_password': '   oldpassword   ',
            'new_password1': ' pass ',
            'new_password2': ' pass ',
        }
        form = PasswordChangeForm(user, data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data['old_password'], data['old_password'])
        self.assertEqual(form.cleaned_data['new_password1'], data['new_password1'])
        self.assertEqual(form.cleaned_data['new_password2'], data['new_password2'])


@override_settings(USE_TZ=False, PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'])
class UserChangeFormTest(TestDataMixin, TestCase):
@@ -673,3 +718,14 @@ class AdminPasswordChangeFormTest(TestDataMixin, TestCase):
        self.assertEqual(password_changed.call_count, 0)
        form.save()
        self.assertEqual(password_changed.call_count, 1)

    def test_password_whitespace_not_stripped(self):
        user = User.objects.get(username='testclient')
        data = {
            'password1': ' pass ',
            'password2': ' pass ',
        }
        form = AdminPasswordChangeForm(user, data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data['password1'], data['password1'])
        self.assertEqual(form.cleaned_data['password2'], data['password2'])