[1.11.x] Fixed #27891 -- Added PasswordResetConfirmView.post_reset_login_backend.
Backport of 5db465d5a6
from master
This commit is contained in:
parent
36d640cd1f
commit
33d2c53fb1
|
@ -442,6 +442,7 @@ class PasswordResetDoneView(PasswordContextMixin, TemplateView):
|
||||||
class PasswordResetConfirmView(PasswordContextMixin, FormView):
|
class PasswordResetConfirmView(PasswordContextMixin, FormView):
|
||||||
form_class = SetPasswordForm
|
form_class = SetPasswordForm
|
||||||
post_reset_login = False
|
post_reset_login = False
|
||||||
|
post_reset_login_backend = None
|
||||||
success_url = reverse_lazy('password_reset_complete')
|
success_url = reverse_lazy('password_reset_complete')
|
||||||
template_name = 'registration/password_reset_confirm.html'
|
template_name = 'registration/password_reset_confirm.html'
|
||||||
title = _('Enter new password')
|
title = _('Enter new password')
|
||||||
|
@ -494,7 +495,7 @@ class PasswordResetConfirmView(PasswordContextMixin, FormView):
|
||||||
user = form.save()
|
user = form.save()
|
||||||
del self.request.session[INTERNAL_RESET_SESSION_TOKEN]
|
del self.request.session[INTERNAL_RESET_SESSION_TOKEN]
|
||||||
if self.post_reset_login:
|
if self.post_reset_login:
|
||||||
auth_login(self.request, user)
|
auth_login(self.request, user, self.post_reset_login_backend)
|
||||||
return super(PasswordResetConfirmView, self).form_valid(form)
|
return super(PasswordResetConfirmView, self).form_valid(form)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
|
|
@ -118,6 +118,8 @@ Minor features
|
||||||
* The new ``post_reset_login`` attribute for
|
* The new ``post_reset_login`` attribute for
|
||||||
:class:`~django.contrib.auth.views.PasswordResetConfirmView` allows
|
:class:`~django.contrib.auth.views.PasswordResetConfirmView` allows
|
||||||
automatically logging in a user after a successful password reset.
|
automatically logging in a user after a successful password reset.
|
||||||
|
If you have multiple ``AUTHENTICATION_BACKENDS`` configured, use the
|
||||||
|
``post_reset_login_backend`` attribute to choose which one to use.
|
||||||
|
|
||||||
* To avoid the possibility of leaking a password reset token via the HTTP
|
* To avoid the possibility of leaking a password reset token via the HTTP
|
||||||
Referer header (for example, if the reset page includes a reference to CSS or
|
Referer header (for example, if the reset page includes a reference to CSS or
|
||||||
|
|
|
@ -1506,6 +1506,11 @@ implementation details see :ref:`using-the-views`.
|
||||||
automatically authenticated after a successful password reset. Defaults
|
automatically authenticated after a successful password reset. Defaults
|
||||||
to ``False``.
|
to ``False``.
|
||||||
|
|
||||||
|
* ``post_reset_login_backend``: A dotted path to the authentication
|
||||||
|
backend to use when authenticating a user if ``post_reset_login`` is
|
||||||
|
``True``. Required only if you have multiple
|
||||||
|
:setting:`AUTHENTICATION_BACKENDS` configured. Defaults to ``None``.
|
||||||
|
|
||||||
* ``form_class``: Form that will be used to set the password. Defaults to
|
* ``form_class``: Form that will be used to set the password. Defaults to
|
||||||
:class:`~django.contrib.auth.forms.SetPasswordForm`.
|
:class:`~django.contrib.auth.forms.SetPasswordForm`.
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,9 @@ from importlib import import_module
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.admin.models import LogEntry
|
from django.contrib.admin.models import LogEntry
|
||||||
from django.contrib.auth import REDIRECT_FIELD_NAME, SESSION_KEY
|
from django.contrib.auth import (
|
||||||
|
BACKEND_SESSION_KEY, REDIRECT_FIELD_NAME, SESSION_KEY,
|
||||||
|
)
|
||||||
from django.contrib.auth.forms import (
|
from django.contrib.auth.forms import (
|
||||||
AuthenticationForm, PasswordChangeForm, SetPasswordForm,
|
AuthenticationForm, PasswordChangeForm, SetPasswordForm,
|
||||||
)
|
)
|
||||||
|
@ -331,6 +333,22 @@ class PasswordResetTest(AuthViewsTestCase):
|
||||||
self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
|
self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
|
||||||
self.assertIn(SESSION_KEY, self.client.session)
|
self.assertIn(SESSION_KEY, self.client.session)
|
||||||
|
|
||||||
|
@override_settings(
|
||||||
|
AUTHENTICATION_BACKENDS=[
|
||||||
|
'django.contrib.auth.backends.ModelBackend',
|
||||||
|
'django.contrib.auth.backends.AllowAllUsersModelBackend',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_confirm_login_post_reset_custom_backend(self):
|
||||||
|
# This backend is specified in the url().
|
||||||
|
backend = 'django.contrib.auth.backends.AllowAllUsersModelBackend'
|
||||||
|
url, path = self._test_confirm_start()
|
||||||
|
path = path.replace('/reset/', '/reset/post_reset_login_custom_backend/')
|
||||||
|
response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'})
|
||||||
|
self.assertRedirects(response, '/reset/done/', fetch_redirect_response=False)
|
||||||
|
self.assertIn(SESSION_KEY, self.client.session)
|
||||||
|
self.assertEqual(self.client.session[BACKEND_SESSION_KEY], backend)
|
||||||
|
|
||||||
def test_confirm_login_post_reset_already_logged_in(self):
|
def test_confirm_login_post_reset_already_logged_in(self):
|
||||||
url, path = self._test_confirm_start()
|
url, path = self._test_confirm_start()
|
||||||
path = path.replace('/reset/', '/reset/post_reset_login/')
|
path = path.replace('/reset/', '/reset/post_reset_login/')
|
||||||
|
|
|
@ -90,6 +90,13 @@ urlpatterns = auth_urlpatterns + [
|
||||||
views.PasswordResetConfirmView.as_view(success_url=reverse_lazy('password_reset'))),
|
views.PasswordResetConfirmView.as_view(success_url=reverse_lazy('password_reset'))),
|
||||||
url(r'^reset/post_reset_login/{}/$'.format(uid_token),
|
url(r'^reset/post_reset_login/{}/$'.format(uid_token),
|
||||||
views.PasswordResetConfirmView.as_view(post_reset_login=True)),
|
views.PasswordResetConfirmView.as_view(post_reset_login=True)),
|
||||||
|
url(
|
||||||
|
r'^reset/post_reset_login_custom_backend/{}/$'.format(uid_token),
|
||||||
|
views.PasswordResetConfirmView.as_view(
|
||||||
|
post_reset_login=True,
|
||||||
|
post_reset_login_backend='django.contrib.auth.backends.AllowAllUsersModelBackend',
|
||||||
|
),
|
||||||
|
),
|
||||||
url(r'^password_change/custom/$',
|
url(r'^password_change/custom/$',
|
||||||
views.PasswordChangeView.as_view(success_url='/custom/')),
|
views.PasswordChangeView.as_view(success_url='/custom/')),
|
||||||
url(r'^password_change/custom/named/$',
|
url(r'^password_change/custom/named/$',
|
||||||
|
|
Loading…
Reference in New Issue