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.
This commit is contained in:
Tim Abbott 2018-05-20 20:02:27 -07:00
parent e7fa77f120
commit 336ad0fbb1
2 changed files with 54 additions and 2 deletions

View File

@ -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

View File

@ -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")