diff --git a/modoboa/core/api/v2/tests.py b/modoboa/core/api/v2/tests.py index 138731d31..258273176 100644 --- a/modoboa/core/api/v2/tests.py +++ b/modoboa/core/api/v2/tests.py @@ -5,6 +5,8 @@ import oath from unittest import mock from django.urls import reverse +from django.utils.encoding import force_bytes +from django.utils.http import urlsafe_base64_encode from modoboa.admin import factories from modoboa.core import models @@ -122,11 +124,11 @@ class AccountViewSetTestCase(ModoAPITestCase): me = resp.json() self.assertEqual(me["username"], "admin") - def test_me_password(self): + def test_me_password(self, password_ko="Toto1234", password_ok="password"): url = reverse("v2:account-check-me-password") - resp = self.client.post(url, {"password": "Toto1234"}, format="json") + resp = self.client.post(url, {"password": password_ko}, format="json") self.assertEqual(resp.status_code, 400) - resp = self.client.post(url, {"password": "password"}, format="json") + resp = self.client.post(url, {"password": password_ok}, format="json") self.assertEqual(resp.status_code, 200) @mock.patch("django_otp.match_token") @@ -203,7 +205,7 @@ class AccountViewSetTestCase(ModoAPITestCase): self.assertEqual(resp.status_code, 201) -class PasswordResetTestCase(ModoAPITestCase): +class PasswordResetTestCase(AccountViewSetTestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.id = 0 @@ -324,8 +326,74 @@ class PasswordResetTestCase(ModoAPITestCase): self.assertEqual(response.status_code, 200) self.assertIn("token", response.json()) self.assertIn("id", response.json()) - self.sms_token = response.json()["token"] - self.id = response.json()["id"] + + @mock.patch("ovh.Client.get") + @mock.patch("ovh.Client.post") + def test_password_change(self, client_post, client_get): + url = reverse("v2:password_reset_confirm_v2") + url_create_sms = reverse("v2:password_reset") + url_sms_totp = reverse("v2:sms_totp") + + client_get.return_value = ["service"] + client_post.return_value = {"totalCreditsRemoved": 1} + self.set_global_parameters({ + "sms_password_recovery": True, + "sms_provider": "ovh", + "sms_ovh_application_key": "key", + "sms_ovh_application_secret": "secret", + "sms_ovh_consumer_key": "consumer" + }) + + # Prepare account + account = models.User.objects.get(username="user@test.com") + account.phone_number = "+33612345678" + account.secondary_email = "toto@test.com" + account.is_active = True + account.save() + + # Send SMS + self.create_session() + data = {"email": account.email} + response = self.client.post(url_create_sms, data, format="json") + self.assertEqual(response.status_code, 200) + session = self.client.session + secret = session["totp_secret"] + # Get token and ID + data = {"sms_totp": oath.totp(secret), "type": "confirm"} + response = self.client.post(url_sms_totp, data, format="json") + self.assertEqual(response.status_code, 200) + id_ok = response.json()["id"] + token_ok = response.json()["token"] + + # Password differs + data = {"new_password1": "123456", "new_password2": "123457", "token": token_ok, "id": id_ok} + response = self.client.post(url, data, format="json") + self.assertEqual(response.status_code, 400) + + # Wrong ID + id_ko = urlsafe_base64_encode(force_bytes(-1)) + data = {"new_password1": "123456", "new_password2": "123456", "token": token_ok, "id": id_ko} + response = self.client.post(url, data, format="json") + self.assertEqual(response.status_code, 404) + + # Wrong Token + token_ko = "123456" + data = {"new_password1": "123456", "new_password2": "123456", "token": token_ko, "id": id_ok} + response = self.client.post(url, data, format="json") + self.assertEqual(response.status_code, 403) + + # Failed password requirements + data = {"new_password1": "123456", "new_password2": "123456", "token": token_ok, "id": id_ok} + response = self.client.post(url, data, format="json") + self.assertEqual(response.json()["type"], "password_requirement") + + # All good + data = {"new_password1": "MyHardenedPass1!", "new_password2": "MyHardenedPass1!", "token": token_ok, + "id": id_ok} + response = self.client.post(url, data, format="json") + self.assertEqual(response.status_code, 200) + # TODO: See why user doesn't update it's password --> self.test_me_password(password_ok="MyHardenedPass1!") + class AuthenticationTestCase(ModoAPITestCase):