From ea6a994280c67d5ebd12e110c2994514d9132fcb Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Tue, 3 Apr 2018 15:30:17 +0100 Subject: [PATCH] Convert password reset to class based views --- .../admin/tests/test_account_management.py | 10 ++++- wagtail/admin/urls/password_reset.py | 22 ++-------- wagtail/admin/views/account.py | 40 ++++++++++++++----- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/wagtail/admin/tests/test_account_management.py b/wagtail/admin/tests/test_account_management.py index ceb6a8201..70fcbece5 100644 --- a/wagtail/admin/tests/test_account_management.py +++ b/wagtail/admin/tests/test_account_management.py @@ -1,3 +1,4 @@ +from django.contrib.auth import views as auth_views from django.contrib.auth import get_user_model from django.contrib.auth.models import Group, Permission from django.contrib.auth.tokens import PasswordResetTokenGenerator @@ -555,7 +556,14 @@ class TestPasswordReset(TestCase, WagtailTestUtils): self.password_reset_uid = force_text(urlsafe_base64_encode(force_bytes(self.user.pk))) # Create url_args - self.url_kwargs = dict(uidb64=self.password_reset_uid, token=self.password_reset_token) + self.url_kwargs = dict(uidb64=self.password_reset_uid, token=auth_views.INTERNAL_RESET_URL_TOKEN) + + # Add token to session object + s = self.client.session + s.update({ + auth_views.INTERNAL_RESET_SESSION_TOKEN: self.password_reset_token, + }) + s.save() def test_password_reset_confirm_view_invalid_link(self): """ diff --git a/wagtail/admin/urls/password_reset.py b/wagtail/admin/urls/password_reset.py index f039f7a68..350987891 100644 --- a/wagtail/admin/urls/password_reset.py +++ b/wagtail/admin/urls/password_reset.py @@ -1,33 +1,19 @@ from django.conf.urls import url -from wagtail.admin.forms import PasswordResetForm from wagtail.admin.views import account urlpatterns = [ url( - r'^$', account.password_reset, { - 'template_name': 'wagtailadmin/account/password_reset/form.html', - 'email_template_name': 'wagtailadmin/account/password_reset/email.txt', - 'subject_template_name': 'wagtailadmin/account/password_reset/email_subject.txt', - 'password_reset_form': PasswordResetForm, - 'post_reset_redirect': 'wagtailadmin_password_reset_done', - }, name='wagtailadmin_password_reset' + r'^$', account.PasswordResetView.as_view(), name='wagtailadmin_password_reset' ), url( - r'^done/$', account.password_reset_done, { - 'template_name': 'wagtailadmin/account/password_reset/done.html' - }, name='wagtailadmin_password_reset_done' + r'^done/$', account.PasswordResetDoneView.as_view(), name='wagtailadmin_password_reset_done' ), url( r'^confirm/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', - account.password_reset_confirm, { - 'template_name': 'wagtailadmin/account/password_reset/confirm.html', - 'post_reset_redirect': 'wagtailadmin_password_reset_complete', - }, name='wagtailadmin_password_reset_confirm', + account.PasswordResetConfirmView.as_view(), name='wagtailadmin_password_reset_confirm', ), url( - r'^complete/$', account.password_reset_complete, { - 'template_name': 'wagtailadmin/account/password_reset/complete.html' - }, name='wagtailadmin_password_reset_complete' + r'^complete/$', account.PasswordResetCompleteView.as_view(), name='wagtailadmin_password_reset_complete' ), ] diff --git a/wagtail/admin/views/account.py b/wagtail/admin/views/account.py index 424253572..32a94ec11 100644 --- a/wagtail/admin/views/account.py +++ b/wagtail/admin/views/account.py @@ -1,5 +1,3 @@ -from functools import wraps - from django.conf import settings from django.contrib import messages from django.contrib.auth import views as auth_views @@ -7,6 +5,7 @@ from django.contrib.auth import update_session_auth_hash from django.contrib.auth.forms import PasswordChangeForm from django.http import Http404 from django.shortcuts import redirect, render +from django.urls import reverse_lazy from django.utils.translation import ugettext as _ from django.utils.translation import activate from django.views.decorators.cache import never_cache @@ -97,19 +96,38 @@ def change_email(request): }) -def _wrap_password_reset_view(view_func): - @wraps(view_func) - def wrapper(*args, **kwargs): +class PasswordResetEnabledViewMixin: + """ + Class based view mixin that disables the view if password reset is disabled by one of the following settings: + - WAGTAIL_PASSWORD_RESET_ENABLED + - WAGTAIL_PASSWORD_MANAGEMENT_ENABLED + """ + def dispatch(self, *args, **kwargs): if not password_reset_enabled(): raise Http404 - return view_func(*args, **kwargs) - return wrapper + + return super().dispatch(*args, **kwargs) -password_reset = _wrap_password_reset_view(auth_views.password_reset) -password_reset_done = _wrap_password_reset_view(auth_views.password_reset_done) -password_reset_confirm = _wrap_password_reset_view(auth_views.password_reset_confirm) -password_reset_complete = _wrap_password_reset_view(auth_views.password_reset_complete) +class PasswordResetView(PasswordResetEnabledViewMixin, auth_views.PasswordResetView): + template_name = 'wagtailadmin/account/password_reset/form.html' + email_template_name = 'wagtailadmin/account/password_reset/email.txt' + subject_template_name = 'wagtailadmin/account/password_reset/email_subject.txt' + form_class = forms.PasswordResetForm + success_url = reverse_lazy('wagtailadmin_password_reset_done') + + +class PasswordResetDoneView(PasswordResetEnabledViewMixin, auth_views.PasswordResetDoneView): + template_name = 'wagtailadmin/account/password_reset/done.html' + + +class PasswordResetConfirmView(PasswordResetEnabledViewMixin, auth_views.PasswordResetConfirmView): + template_name = 'wagtailadmin/account/password_reset/confirm.html' + success_url = reverse_lazy('wagtailadmin_password_reset_complete') + + +class PasswordResetCompleteView(PasswordResetEnabledViewMixin, auth_views.PasswordResetCompleteView): + template_name = 'wagtailadmin/account/password_reset/complete.html' def notification_preferences(request):