demo-orgs: Create dev environment demo organization without email.

To make creation of demo organizations feel lightweight for users,
we do not want to require an email address at sign-up. Instead an
empty string will used for the new realm owner's email. Currently
implements that for new demo organizations in the development
environment.

Because the user's email address does not exist, we don't enqueue
any of the welcome emails upon account/realm creation, and we
don't create/send new login emails.

This is a part of #19523.

Co-authored by: Tim Abbott <tabbott@zulip.com>
Co-authored by: Lauryn Menard <lauryn@zulip.com>
This commit is contained in:
Eeshan Garg 2021-12-22 19:41:41 -05:00 committed by Tim Abbott
parent dacb5c89af
commit 5e33ae8adf
6 changed files with 60 additions and 13 deletions

View File

@ -280,7 +280,7 @@ def process_new_human_user(
# from being sent after the user is created. # from being sent after the user is created.
clear_scheduled_invitation_emails(user_profile.delivery_email) clear_scheduled_invitation_emails(user_profile.delivery_email)
if realm.send_welcome_emails: if realm.send_welcome_emails:
enqueue_welcome_emails(user_profile) enqueue_welcome_emails(user_profile, realm_creation)
# Schedule an initial email with the user's # Schedule an initial email with the user's
# new account details and log-in information. # new account details and log-in information.

View File

@ -767,6 +767,13 @@ def send_account_registered_email(user: UserProfile, realm_creation: bool = Fals
# Imported here to avoid import cycles. # Imported here to avoid import cycles.
from zerver.context_processors import common_context from zerver.context_processors import common_context
if user.delivery_email == "":
# Do not attempt to enqueue welcome emails for users without an email address.
# The assertions here are to help document the only circumstance under which
# this condition should be possible.
assert user.realm.demo_organization_scheduled_deletion_date is not None and realm_creation
return
from_name, from_address = welcome_sender_information() from_name, from_address = welcome_sender_information()
realm_url = user.realm.uri realm_url = user.realm.uri
@ -811,10 +818,17 @@ def send_account_registered_email(user: UserProfile, realm_creation: bool = Fals
) )
def enqueue_welcome_emails(user: UserProfile) -> None: def enqueue_welcome_emails(user: UserProfile, realm_creation: bool = False) -> None:
# Imported here to avoid import cycles. # Imported here to avoid import cycles.
from zerver.context_processors import common_context from zerver.context_processors import common_context
if user.delivery_email == "":
# Do not attempt to enqueue welcome emails for users without an email address.
# The assertions here are to help document the only circumstance under which
# this condition should be possible.
assert user.realm.demo_organization_scheduled_deletion_date is not None and realm_creation
return
from_name, from_address = welcome_sender_information() from_name, from_address = welcome_sender_information()
other_account_count = ( other_account_count = (
UserProfile.objects.filter(delivery_email__iexact=user.delivery_email) UserProfile.objects.filter(delivery_email__iexact=user.delivery_email)

View File

@ -67,6 +67,16 @@ def get_device_os(user_agent: str) -> Optional[str]:
def email_on_new_login(sender: Any, user: UserProfile, request: Any, **kwargs: Any) -> None: def email_on_new_login(sender: Any, user: UserProfile, request: Any, **kwargs: Any) -> None:
if not user.enable_login_emails: if not user.enable_login_emails:
return return
if user.delivery_email == "":
# Do not attempt to send new login emails for users without an email address.
# The assertions here are to help document the only circumstance under which
# this condition should be possible.
assert (
user.realm.demo_organization_scheduled_deletion_date is not None and user.is_realm_owner
)
return
# We import here to minimize the dependencies of this module, # We import here to minimize the dependencies of this module,
# since it runs as part of `manage.py` initialization # since it runs as part of `manage.py` initialization
from zerver.context_processors import common_context from zerver.context_processors import common_context

View File

@ -3952,6 +3952,11 @@ class UserSignUpTest(ZulipTestCase):
assert user_profile is not None assert user_profile is not None
self.assert_logged_in_user_id(user_profile.id) self.assert_logged_in_user_id(user_profile.id)
# Demo organizations are created without setting an email address for the owner.
self.assertEqual(user_profile.delivery_email, "")
scheduled_email = ScheduledEmail.objects.filter(users=user_profile).last()
assert scheduled_email is None
expected_deletion_date = realm.date_created + datetime.timedelta( expected_deletion_date = realm.date_created + datetime.timedelta(
days=settings.DEMO_ORG_DEADLINE_DAYS days=settings.DEMO_ORG_DEADLINE_DAYS
) )

View File

@ -88,9 +88,9 @@ def register_development_realm(request: HttpRequest) -> HttpResponse:
@csrf_exempt @csrf_exempt
def register_demo_development_realm(request: HttpRequest) -> HttpResponse: def register_demo_development_realm(request: HttpRequest) -> HttpResponse:
count = UserProfile.objects.count() # Demo organization owners are not required to provide a name or email.
name = f"user-{count}" name = "Your name"
email = f"{name}@zulip.com" email = ""
realm_name = generate_demo_realm_name() realm_name = generate_demo_realm_name()
realm_type = Realm.ORG_TYPES["business"]["id"] realm_type = Realm.ORG_TYPES["business"]["id"]
realm_subdomain = realm_name realm_subdomain = realm_name

View File

@ -213,6 +213,7 @@ def registration_helper(
source_realm_id: Optional[int] = REQ( source_realm_id: Optional[int] = REQ(
default=None, converter=to_converted_or_fallback(to_non_negative_int, None) default=None, converter=to_converted_or_fallback(to_non_negative_int, None)
), ),
form_is_demo_organization: Optional[str] = REQ("is_demo_organization", default=None),
) -> HttpResponse: ) -> HttpResponse:
try: try:
prereg_object, realm_creation = check_prereg_key(request, key) prereg_object, realm_creation = check_prereg_key(request, key)
@ -233,6 +234,23 @@ def registration_helper(
password_required = prereg_object.password_required password_required = prereg_object.password_required
role = prereg_object.invited_as role = prereg_object.invited_as
if form_is_demo_organization is None:
demo_organization_creation = False
else:
# Check the explicit strings that return false
# in django.forms.BooleanField.to_python.
false_strings = ("false", "0")
demo_organization_creation = form_is_demo_organization.strip().lower() not in false_strings
if email == "":
# Do not attempt to validate email for users without an email address.
# The assertions here are to help document the only circumstance under which
# this condition should be possible.
assert realm_creation and demo_organization_creation
# TODO: Remove settings.DEVELOPMENT when demo organization feature ready
# to be fully implemented.
assert settings.DEVELOPMENT
else:
try: try:
validators.validate_email(email) validators.validate_email(email)
except ValidationError: except ValidationError:
@ -419,12 +437,12 @@ def registration_helper(
string_id = form.cleaned_data["realm_subdomain"] string_id = form.cleaned_data["realm_subdomain"]
realm_name = form.cleaned_data["realm_name"] realm_name = form.cleaned_data["realm_name"]
realm_type = form.cleaned_data["realm_type"] realm_type = form.cleaned_data["realm_type"]
is_demo_org = form.cleaned_data["is_demo_organization"] is_demo_organization = form.cleaned_data["is_demo_organization"]
realm = do_create_realm( realm = do_create_realm(
string_id, string_id,
realm_name, realm_name,
org_type=realm_type, org_type=realm_type,
is_demo_organization=is_demo_org, is_demo_organization=is_demo_organization,
prereg_realm=prereg_realm, prereg_realm=prereg_realm,
) )
assert realm is not None assert realm is not None