Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from django.contrib.auth import views as auth_views
- url(r"^accounts/password_change/$",
- auth_views.PasswordChangeView.as_view(),
- name="password_change"),
- url(r"^accounts/password_change/done/$",
- auth_views.PasswordChangeDoneView.as_view(),
- name="password_change_done"),
- url(r"^accounts/password_reset/$",
- auth_views.PasswordResetView.as_view(email_template_name="app/email/accounts/password_reset_email.html",
- success_url=reverse_lazy("app:password_reset_done"),
- subject_template_name="app/email/accounts/password_reset_subject.html"),
- name="password_reset"),
- url(r"^accounts/password_reset/done/$",
- auth_views.PasswordResetDoneView.as_view(),
- name="password_reset_done"),
- url(r"^accounts/reset/(?P<uidb64>[0-9A-Za-z_-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$",
- auth_views.PasswordResetConfirmView.as_view(
- success_url=reverse_lazy("app:password_reset_complete"),
- form_class=CustomSetPasswordForm),
- name="password_reset_confirm"),
- url(r"^accounts/reset/complete/$",
- auth_views.PasswordResetCompleteView.as_view(),
- name="password_reset_complete"),
- import re
- from django.urls import reverse, NoReverseMatch
- from django.test import TestCase, Client
- from django.core import mail
- from django.test.utils import override_settings
- from django.contrib.auth import authenticate
- VALID_USER_NAME = "username"
- USER_OLD_PSW = "oldpassword"
- USER_NEW_PSW = "newpassword"
- PASSWORD_RESET_URL = reverse("app:password_reset")
- def PASSWORD_RESET_CONFIRM_URL(uidb64, token):
- try:
- return reverse("app:password_reset_confirm", args=(uidb64, token))
- except NoReverseMatch:
- return f"/accounts/reset/invaliduidb64/invalid-token/"
- def utils_extract_reset_tokens(full_url):
- return re.findall(r"/([w-]+)",
- re.search(r"^http://.+$", full_url, flags=re.MULTILINE)[0])[3:5]
- @override_settings(EMAIL_BACKEND="anymail.backends.test.EmailBackend")
- class PasswordResetTestCase(TestCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.myclient = Client()
- def test_password_reset_ok(self):
- # ask for password reset
- response = self.myclient.post(PASSWORD_RESET_URL,
- {"email": VALID_USER_NAME},
- follow=True)
- # extract reset token from email
- self.assertEqual(len(mail.outbox), 1)
- msg = mail.outbox[0]
- uidb64, token = utils_extract_reset_tokens(msg.body)
- # change the password
- response = self.myclient.post(PASSWORD_RESET_CONFIRM_URL(uidb64, token),
- {"new_password1": USER_NEW_PSW,
- "new_password2": USER_NEW_PSW},
- follow=True)
- self.assertIsNone(authenticate(username=VALID_USER_NAME,password=USER_OLD_PSW))
- def test_password_reset_ok(self):
- # ask for password reset
- response = self.myclient.post(PASSWORD_RESET_URL,
- {"email": VALID_USER_NAME},
- follow=True)
- # extract reset token from email
- self.assertEqual(len(mail.outbox), 1)
- msg = mail.outbox[0]
- uidb64, token = utils_extract_reset_tokens(msg.body)
- # change the password
- self.myclient.get(PASSWORD_RESET_CONFIRM_URL(uidb64, token), follow=True)
- response = self.myclient.post(PASSWORD_RESET_CONFIRM_URL(uidb64, "set-password"),
- {"new_password1": USER_NEW_PSW,
- "new_password2": USER_NEW_PSW},
- follow=True)
- self.assertIsNone(authenticate(username=VALID_USER_NAME,password=USER_OLD_PSW))
- INTERNAL_RESET_URL_TOKEN = 'set-password'
- INTERNAL_RESET_SESSION_TOKEN = '_password_reset_token'
- @method_decorator(sensitive_post_parameters())
- @method_decorator(never_cache)
- def dispatch(self, *args, **kwargs):
- assert 'uidb64' in kwargs and 'token' in kwargs
- self.validlink = False
- self.user = self.get_user(kwargs['uidb64'])
- if self.user is not None:
- token = kwargs['token']
- if token == INTERNAL_RESET_URL_TOKEN:
- session_token = self.request.session.get(INTERNAL_RESET_SESSION_TOKEN)
- if self.token_generator.check_token(self.user, session_token):
- # If the token is valid, display the password reset form.
- self.validlink = True
- return super().dispatch(*args, **kwargs)
- else:
- if self.token_generator.check_token(self.user, token):
- # Store the token in the session and redirect to the
- # password reset form at a URL without the token. That
- # avoids the possibility of leaking the token in the
- # HTTP Referer header.
- self.request.session[INTERNAL_RESET_SESSION_TOKEN] = token
- redirect_url = self.request.path.replace(token, INTERNAL_RESET_URL_TOKEN)
- return HttpResponseRedirect(redirect_url)
- # Display the "Password reset unsuccessful" page.
- return self.render_to_response(self.get_context_data())
Add Comment
Please, Sign In to add comment