client.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import re
  2. from django.contrib.auth.views import (
  3. INTERNAL_RESET_SESSION_TOKEN, PasswordResetConfirmView,
  4. )
  5. from django.test import Client
  6. def extract_token_from_url(url):
  7. token_search = re.search(r'/reset/.*/(.+?)/', url)
  8. if token_search:
  9. return token_search.group(1)
  10. class PasswordResetConfirmClient(Client):
  11. """
  12. This client eases testing the password reset flow by emulating the
  13. PasswordResetConfirmView's redirect and saving of the reset token in the
  14. user's session. This request puts 'my-token' in the session and redirects
  15. to '/reset/bla/set-password/':
  16. >>> client = PasswordResetConfirmClient()
  17. >>> client.get('/reset/bla/my-token/')
  18. """
  19. reset_url_token = PasswordResetConfirmView.reset_url_token
  20. def _get_password_reset_confirm_redirect_url(self, url):
  21. token = extract_token_from_url(url)
  22. if not token:
  23. return url
  24. # Add the token to the session
  25. session = self.session
  26. session[INTERNAL_RESET_SESSION_TOKEN] = token
  27. session.save()
  28. return url.replace(token, self.reset_url_token)
  29. def get(self, path, *args, **kwargs):
  30. redirect_url = self._get_password_reset_confirm_redirect_url(path)
  31. return super().get(redirect_url, *args, **kwargs)
  32. def post(self, path, *args, **kwargs):
  33. redirect_url = self._get_password_reset_confirm_redirect_url(path)
  34. return super().post(redirect_url, *args, **kwargs)