realm-deactivation: Send email to owners as part of deactivation.

Creates a new "realm_deactivated" email that can be sent to realm
owners as part of `do_deactivate_realm`, via a boolean flag,
`email_owners`.

This flag is set to `False` when `do_deactivate_realm` is used for
realm exports or changing a realm's subdomain, so that the active
organization owners are not emailed in those cases.

This flag is optional for the `deactivate_realm` management command,
but as there is no active user passed in that case, then the email
is sent without referencing who deactivated the realm.

It is passed as `True` for the support analytics view, but the email
that is generated does not include information about the support
admin user who completed the request for organization deactivation.

When an active organization owner deactivates the organization, then
the flag is `True` and an email is sent to them as well as any other
active organization owners, with a slight variation in the email text
for those two cases.

Adds specific tests for when `email_owners` is passed as `True`. All
existing tests for other functionality of `do_deactivate_user` pass
the flag as `False`.

Adds `localize` from django.util.formats as a jinja env filter so
that the dates in these emails are internationlized for the owner's
default language setting in the "realm_deactivated" email templates.

Fixes #24685.
This commit is contained in:
Lauryn Menard
2023-09-25 22:59:44 +02:00
committed by Tim Abbott
parent 2eaf098c5d
commit 673a01ea0c
22 changed files with 290 additions and 40 deletions

View File

@@ -215,7 +215,10 @@ class AuthBackendTest(ZulipTestCase):
# Verify auth fails with a deactivated realm
do_deactivate_realm(
user_profile.realm, acting_user=None, deactivation_reason="owner_request"
user_profile.realm,
acting_user=None,
deactivation_reason="owner_request",
email_owners=False,
)
result = backend.authenticate(**good_kwargs)
@@ -4992,7 +4995,10 @@ class FetchAPIKeyTest(ZulipTestCase):
def test_deactivated_realm(self) -> None:
do_deactivate_realm(
self.user_profile.realm, acting_user=None, deactivation_reason="owner_request"
self.user_profile.realm,
acting_user=None,
deactivation_reason="owner_request",
email_owners=False,
)
result = self.client_post(
"/api/v1/fetch_api_key",
@@ -5056,7 +5062,10 @@ class DevFetchAPIKeyTest(ZulipTestCase):
def test_deactivated_realm(self) -> None:
do_deactivate_realm(
self.user_profile.realm, acting_user=None, deactivation_reason="owner_request"
self.user_profile.realm,
acting_user=None,
deactivation_reason="owner_request",
email_owners=False,
)
result = self.client_post("/api/v1/dev_fetch_api_key", dict(username=self.email))
self.assert_json_error_contains(result, "This organization has been deactivated", 401)
@@ -6350,7 +6359,10 @@ class TestLDAP(ZulipLDAPTestCase):
backend = self.backend
email = "nonexisting@zulip.com"
do_deactivate_realm(
backend._realm, acting_user=None, deactivation_reason="owner_request"
backend._realm,
acting_user=None,
deactivation_reason="owner_request",
email_owners=False,
)
with self.assertRaisesRegex(Exception, "Realm has been deactivated"):
backend.get_or_build_user(email, _LDAPUser())
@@ -7473,7 +7485,10 @@ class JWTFetchAPIKeyTest(ZulipTestCase):
def test_inactive_realm_failure(self) -> None:
payload = {"email": self.email}
do_deactivate_realm(
self.user_profile.realm, acting_user=None, deactivation_reason="owner_request"
self.user_profile.realm,
acting_user=None,
deactivation_reason="owner_request",
email_owners=False,
)
with self.settings(JWT_AUTH_KEYS={"zulip": {"key": "key1", "algorithms": ["HS256"]}}):
key = settings.JWT_AUTH_KEYS["zulip"]["key"]