From 336ad0fbb1c6cfe194b8d38d1dc6b0d321301324 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Sun, 20 May 2018 20:02:27 -0700 Subject: [PATCH] password reset: Handle deactivated users and realms. Since this is a logged-out view, need to actually write code for the case of deactivated realms. The change to get_active_user is more for clarity; the Django password reset form already checks for whether the user is active earlier. --- zerver/forms.py | 7 ++++-- zerver/tests/test_signup.py | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/zerver/forms.py b/zerver/forms.py index 971cfa4033..b3be965f83 100644 --- a/zerver/forms.py +++ b/zerver/forms.py @@ -24,7 +24,7 @@ from zerver.lib.request import JsonableError from zerver.lib.send_email import send_email, FromAddress from zerver.lib.subdomains import get_subdomain, user_matches_subdomain, is_root_domain_available from zerver.lib.users import check_full_name -from zerver.models import Realm, get_user, UserProfile, get_realm, email_to_domain, \ +from zerver.models import Realm, get_active_user, UserProfile, get_realm, email_to_domain, \ email_allowed_for_realm, DisposableEmailError, DomainNotAllowedForRealmError from zproject.backends import email_auth_enabled @@ -209,10 +209,13 @@ class ZulipPasswordResetForm(PasswordResetForm): if not email_auth_enabled(realm): logging.info("Password reset attempted for %s even though password auth is disabled." % (email,)) return + if realm.deactivated: + logging.info("Realm is deactivated") + return user = None # type: Optional[UserProfile] try: - user = get_user(email, realm) + user = get_active_user(email, realm) except UserProfile.DoesNotExist: pass diff --git a/zerver/tests/test_signup.py b/zerver/tests/test_signup.py index 1a12fa6645..d3aeaf0277 100644 --- a/zerver/tests/test_signup.py +++ b/zerver/tests/test_signup.py @@ -225,6 +225,55 @@ class PasswordResetTest(ZulipTestCase): self.assertNotIn('does have an active account in the zulip.testserver', outbox[0].body) + def test_password_reset_for_deactivated_user(self) -> None: + user_profile = self.example_user("hamlet") + email = user_profile.email + do_deactivate_user(user_profile) + + # start the password reset process by supplying an email address + result = self.client_post('/accounts/password/reset/', {'email': email}) + + # check the redirect link telling you to check mail for password reset link + self.assertEqual(result.status_code, 302) + self.assertTrue(result["Location"].endswith( + "/accounts/password/reset/done/")) + result = self.client_get(result["Location"]) + + self.assert_in_response("Check your email to finish the process.", result) + + # Check that the password reset email is from a noreply address. + from django.core.mail import outbox + from_email = outbox[0].from_email + self.assertIn("Zulip Account Security", from_email) + self.assertIn(FromAddress.NOREPLY, from_email) + + self.assertIn('Someone (possibly you) requested a password', + outbox[0].body) + self.assertNotIn('does have an active account in the zulip.testserver', + outbox[0].body) + + def test_password_reset_with_deactivated_realm(self) -> None: + user_profile = self.example_user("hamlet") + email = user_profile.email + do_deactivate_realm(user_profile.realm) + + # start the password reset process by supplying an email address + with patch('logging.info') as mock_logging: + result = self.client_post('/accounts/password/reset/', {'email': email}) + mock_logging.assert_called_once() + + # check the redirect link telling you to check mail for password reset link + self.assertEqual(result.status_code, 302) + self.assertTrue(result["Location"].endswith( + "/accounts/password/reset/done/")) + result = self.client_get(result["Location"]) + + self.assert_in_response("Check your email to finish the process.", result) + + # Check that the password reset email is from a noreply address. + from django.core.mail import outbox + self.assertEqual(len(outbox), 0) + def test_wrong_subdomain(self) -> None: email = self.example_email("hamlet")