diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
index 12bb666..ef5c9d8 100644
a
|
b
|
class PasswordResetConfirmView(PasswordContextMixin, FormView):
|
406 | 406 | template_name = 'registration/password_reset_confirm.html' |
407 | 407 | title = _('Enter new password') |
408 | 408 | token_generator = default_token_generator |
| 409 | post_reset_login = False |
409 | 410 | |
410 | 411 | @method_decorator(sensitive_post_parameters()) |
411 | 412 | @method_decorator(never_cache) |
… |
… |
class PasswordResetConfirmView(PasswordContextMixin, FormView):
|
429 | 430 | return kwargs |
430 | 431 | |
431 | 432 | def form_valid(self, form): |
432 | | form.save() |
| 433 | user = form.save() |
| 434 | if self.post_reset_login: |
| 435 | auth_login(self.request, user) |
433 | 436 | return super(PasswordResetConfirmView, self).form_valid(form) |
434 | 437 | |
435 | 438 | def get_context_data(self, **kwargs): |
diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt
index 5fd8ab4..9990bfb 100644
a
|
b
|
implementation details see :ref:`using-the-views`.
|
1475 | 1475 | will default to ``default_token_generator``, it's an instance of |
1476 | 1476 | ``django.contrib.auth.tokens.PasswordResetTokenGenerator``. |
1477 | 1477 | |
1478 | | * ``form_class``: Form that will be used to set the password. Defaults to |
| 1478 | * ``post_reset_login``: Boolean, if set to True the user is going to be |
| 1479 | automatically authenticated after the password has been successfully reset. |
| 1480 | Set to False by default. |
| 1481 | |
| 1482 | * ``form_class``: Form that will be used to set the password. Defaults to |
1479 | 1483 | :class:`~django.contrib.auth.forms.SetPasswordForm`. |
1480 | 1484 | |
1481 | 1485 | * ``success_url``: URL to redirect after the password reset done. Defaults |
diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py
index 32c51e4..f81452b 100644
a
|
b
|
class PasswordResetTest(AuthViewsTestCase):
|
306 | 306 | self.assertEqual(response.status_code, 302) |
307 | 307 | self.assertURLEqual(response.url, '/password_reset/') |
308 | 308 | |
| 309 | def test_confirm_login_post_reset(self): |
| 310 | url, path = self._test_confirm_start() |
| 311 | path = path.replace('/reset/', '/reset/post_reset_login/') |
| 312 | response = self.client.post(path, {'new_password1': 'anewpassword', 'new_password2': 'anewpassword'}) |
| 313 | self.assertEqual(response.status_code, 302) |
| 314 | self.assertURLEqual(response.url, '/reset/done/') |
| 315 | self.assertIn(SESSION_KEY, self.client.session) |
| 316 | |
309 | 317 | def test_confirm_display_user_from_form(self): |
310 | 318 | url, path = self._test_confirm_start() |
311 | 319 | response = self.client.get(path) |
diff --git a/tests/auth_tests/urls.py b/tests/auth_tests/urls.py
index 6a7574b..e8174fb 100644
a
|
b
|
urlpatterns = auth_urlpatterns + [
|
85 | 85 | views.PasswordResetConfirmView.as_view(success_url='/custom/')), |
86 | 86 | url(r'^reset/custom/named/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', |
87 | 87 | views.PasswordResetConfirmView.as_view(success_url=reverse_lazy('password_reset'))), |
| 88 | url(r'^reset/post_reset_login/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', |
| 89 | views.PasswordResetConfirmView.as_view(post_reset_login=True)), |
88 | 90 | url(r'^password_change/custom/$', |
89 | 91 | views.PasswordChangeView.as_view(success_url='/custom/')), |
90 | 92 | url(r'^password_change/custom/named/$', |