test_user_changepassword_api.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. from django.core import mail
  2. from django.urls import reverse
  3. from ...conf.test import override_dynamic_settings
  4. from ..test import AuthenticatedUserTestCase
  5. class UserChangePasswordTests(AuthenticatedUserTestCase):
  6. """tests for user change password RPC (/api/users/1/change-password/)"""
  7. def setUp(self):
  8. super().setUp()
  9. self.link = "/api/users/%s/change-password/" % self.user.pk
  10. def test_unsupported_methods(self):
  11. """api isn't supporting GET"""
  12. response = self.client.get(self.link)
  13. self.assertEqual(response.status_code, 405)
  14. def test_empty_input(self):
  15. """api errors correctly for empty input"""
  16. response = self.client.post(self.link, data={})
  17. self.assertEqual(response.status_code, 400)
  18. self.assertEqual(
  19. response.json(),
  20. {
  21. "new_password": ["This field is required."],
  22. "password": ["This field is required."],
  23. },
  24. )
  25. def test_invalid_password(self):
  26. """api errors correctly for invalid password"""
  27. response = self.client.post(
  28. self.link, data={"new_password": "N3wP@55w0rd", "password": "Lor3mIpsum"}
  29. )
  30. self.assertEqual(response.status_code, 400)
  31. self.assertEqual(
  32. response.json(), {"password": ["Entered password is invalid."]}
  33. )
  34. def test_blank_input(self):
  35. """api errors correctly for blank input"""
  36. response = self.client.post(
  37. self.link, data={"new_password": "", "password": self.USER_PASSWORD}
  38. )
  39. self.assertEqual(response.status_code, 400)
  40. self.assertEqual(
  41. response.json(), {"new_password": ["This field may not be blank."]}
  42. )
  43. def test_short_new_pasword(self):
  44. """api errors correctly for short new password"""
  45. response = self.client.post(
  46. self.link, data={"new_password": "n", "password": self.USER_PASSWORD}
  47. )
  48. self.assertEqual(response.status_code, 400)
  49. self.assertEqual(
  50. response.json(),
  51. {
  52. "new_password": [
  53. "This password is too short. It must contain at least 7 characters."
  54. ]
  55. },
  56. )
  57. @override_dynamic_settings(forum_address="http://test.com/")
  58. def test_change_password(self):
  59. """api allows users to change their passwords"""
  60. new_password = "N3wP@55w0rd"
  61. response = self.client.post(
  62. self.link,
  63. data={"new_password": new_password, "password": self.USER_PASSWORD},
  64. )
  65. self.assertEqual(response.status_code, 200)
  66. self.assertIn("Confirm password change", mail.outbox[0].subject)
  67. for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
  68. if line.startswith("http://"):
  69. token = line.rstrip("/").split("/")[-1]
  70. break
  71. else:
  72. self.fail("E-mail sent didn't contain confirmation url")
  73. response = self.client.get(
  74. reverse("misago:options-confirm-password-change", kwargs={"token": token})
  75. )
  76. self.assertEqual(response.status_code, 200)
  77. self.reload_user()
  78. self.assertTrue(self.user.check_password(new_password))
  79. @override_dynamic_settings(forum_address="http://test.com/")
  80. def test_change_password_with_whitespaces(self):
  81. """api handles users with whitespaces around their passwords"""
  82. old_password = " old password "
  83. new_password = " N3wP@55w0rd "
  84. self.user.set_password(old_password)
  85. self.user.save()
  86. self.login_user(self.user)
  87. response = self.client.post(
  88. self.link, data={"new_password": new_password, "password": old_password}
  89. )
  90. self.assertEqual(response.status_code, 200)
  91. self.assertIn("Confirm password change", mail.outbox[0].subject)
  92. for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
  93. if line.startswith("http://"):
  94. token = line.rstrip("/").split("/")[-1]
  95. break
  96. else:
  97. self.fail("E-mail sent didn't contain confirmation url")
  98. response = self.client.get(
  99. reverse("misago:options-confirm-password-change", kwargs={"token": token})
  100. )
  101. self.assertEqual(response.status_code, 200)
  102. self.reload_user()
  103. self.assertTrue(self.user.check_password(new_password))
  104. @override_dynamic_settings(
  105. enable_oauth2_client=True,
  106. oauth2_provider="Lorem",
  107. )
  108. def test_change_password_api_returns_403_if_oauth_is_enabled(self):
  109. new_password = " N3wP@55w0rd "
  110. self.login_user(self.user)
  111. response = self.client.post(
  112. self.link,
  113. data={"new_password": new_password, "password": self.USER_PASSWORD},
  114. )
  115. self.assertEqual(response.status_code, 403)
  116. self.assertEqual(len(mail.outbox), 0)
  117. @override_dynamic_settings(forum_address="http://test.com/")
  118. def test_confirm_change_password_view_returns_403_if_oauth_is_enabled(self):
  119. new_password = " N3wP@55w0rd "
  120. self.login_user(self.user)
  121. response = self.client.post(
  122. self.link,
  123. data={"new_password": new_password, "password": self.USER_PASSWORD},
  124. )
  125. self.assertEqual(response.status_code, 200)
  126. self.assertIn("Confirm password change", mail.outbox[0].subject)
  127. for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
  128. if line.startswith("http://"):
  129. token = line.rstrip("/").split("/")[-1]
  130. break
  131. else:
  132. self.fail("E-mail sent didn't contain confirmation url")
  133. with override_dynamic_settings(
  134. enable_oauth2_client=True, oauth2_provider="Lorem"
  135. ):
  136. response = self.client.get(
  137. reverse(
  138. "misago:options-confirm-password-change", kwargs={"token": token}
  139. )
  140. )
  141. self.assertEqual(response.status_code, 403)