From e01faebd7e641844f5b7f124565d04b4c1bb9c33 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Thu, 14 Apr 2022 14:58:15 -0700 Subject: [PATCH] actions: Split out zerver.actions.create_realm. Signed-off-by: Anders Kaseorg --- .../commands/populate_analytics_db.py | 2 +- analytics/tests/test_counts.py | 2 +- analytics/views/support.py | 2 +- corporate/tests/test_stripe.py | 2 +- zerver/actions/create_realm.py | 238 +++++++++++++++++ zerver/lib/actions.py | 241 +----------------- zerver/lib/onboarding.py | 2 +- .../commands/change_realm_subdomain.py | 2 +- zerver/management/commands/create_realm.py | 2 +- zerver/tests/test_auth_backends.py | 2 +- zerver/tests/test_decorators.py | 2 +- zerver/tests/test_markdown.py | 2 +- zerver/tests/test_message_send.py | 2 +- zerver/tests/test_realm.py | 6 +- zerver/tests/test_realm_domains.py | 2 +- zerver/tests/test_realm_emoji.py | 2 +- zerver/tests/test_retention.py | 2 +- zerver/tests/test_signup.py | 2 +- zerver/tests/test_subs.py | 3 +- zerver/tests/test_upload.py | 2 +- zerver/views/realm.py | 2 +- zerver/views/registration.py | 2 +- zilencer/management/commands/populate_db.py | 4 +- 23 files changed, 265 insertions(+), 263 deletions(-) create mode 100644 zerver/actions/create_realm.py diff --git a/analytics/management/commands/populate_analytics_db.py b/analytics/management/commands/populate_analytics_db.py index fb8f16f6eb..5171cd73d1 100644 --- a/analytics/management/commands/populate_analytics_db.py +++ b/analytics/management/commands/populate_analytics_db.py @@ -16,8 +16,8 @@ from analytics.models import ( StreamCount, UserCount, ) +from zerver.actions.create_realm import do_create_realm from zerver.actions.users import do_change_user_role -from zerver.lib.actions import do_create_realm from zerver.lib.create_user import create_user from zerver.lib.stream_color import STREAM_ASSIGNMENT_COLORS from zerver.lib.timestamp import floor_to_day diff --git a/analytics/tests/test_counts.py b/analytics/tests/test_counts.py index cfab734b43..f81b1353cb 100644 --- a/analytics/tests/test_counts.py +++ b/analytics/tests/test_counts.py @@ -32,6 +32,7 @@ from analytics.models import ( UserCount, installation_epoch, ) +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import ( do_activate_mirror_dummy_user, do_create_user, @@ -49,7 +50,6 @@ from zerver.actions.message_flags import ( ) from zerver.actions.user_activity import update_user_activity_interval from zerver.actions.users import do_deactivate_user -from zerver.lib.actions import do_create_realm from zerver.lib.create_user import create_user from zerver.lib.exceptions import InvitationError from zerver.lib.test_classes import ZulipTestCase diff --git a/analytics/views/support.py b/analytics/views/support.py index 4174d0bde9..f4fc22f6d2 100644 --- a/analytics/views/support.py +++ b/analytics/views/support.py @@ -16,6 +16,7 @@ from django.utils.translation import gettext as _ from confirmation.models import Confirmation, confirmation_url from confirmation.settings import STATUS_ACTIVE +from zerver.actions.create_realm import do_change_realm_subdomain from zerver.actions.realm_settings import ( do_change_realm_org_type, do_change_realm_plan_type, @@ -25,7 +26,6 @@ from zerver.actions.realm_settings import ( ) from zerver.decorator import require_server_admin from zerver.forms import check_subdomain_available -from zerver.lib.actions import do_change_realm_subdomain from zerver.lib.exceptions import JsonableError from zerver.lib.realm_icon import realm_icon_url from zerver.lib.request import REQ, has_request_variables diff --git a/corporate/tests/test_stripe.py b/corporate/tests/test_stripe.py index 749b4a4b9e..faa7ca7cda 100644 --- a/corporate/tests/test_stripe.py +++ b/corporate/tests/test_stripe.py @@ -81,6 +81,7 @@ from corporate.models import ( get_current_plan_by_realm, get_customer_by_realm, ) +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import ( do_activate_mirror_dummy_user, do_create_user, @@ -88,7 +89,6 @@ from zerver.actions.create_user import ( ) from zerver.actions.realm_settings import do_deactivate_realm, do_reactivate_realm from zerver.actions.users import do_deactivate_user -from zerver.lib.actions import do_create_realm from zerver.lib.test_classes import ZulipTestCase from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime from zerver.lib.utils import assert_is_not_none diff --git a/zerver/actions/create_realm.py b/zerver/actions/create_realm.py new file mode 100644 index 0000000000..a4150bfb0e --- /dev/null +++ b/zerver/actions/create_realm.py @@ -0,0 +1,238 @@ +import datetime +import logging +from typing import Any, Dict, Optional + +from django.conf import settings +from django.db import transaction +from django.utils.timezone import now as timezone_now +from django.utils.translation import gettext as _ + +from zerver.actions.message_send import internal_send_stream_message +from zerver.actions.realm_settings import ( + do_add_deactivated_redirect, + do_change_realm_plan_type, + do_deactivate_realm, +) +from zerver.lib.bulk_create import create_users +from zerver.lib.server_initialization import create_internal_realm, server_initialized +from zerver.lib.streams import ensure_stream, get_signups_stream +from zerver.lib.user_groups import create_system_user_groups_for_realm +from zerver.models import ( + DefaultStream, + Realm, + RealmAuditLog, + RealmUserDefault, + Stream, + UserProfile, + get_realm, + get_system_bot, +) + + +def do_change_realm_subdomain( + realm: Realm, new_subdomain: str, *, acting_user: Optional[UserProfile] +) -> None: + """Changing a realm's subdomain is a highly disruptive operation, + because all existing clients will need to be updated to point to + the new URL. Further, requests to fetch data from existing event + queues will fail with an authentication error when this change + happens (because the old subdomain is no longer associated with + the realm), making it hard for us to provide a graceful update + experience for clients. + """ + old_subdomain = realm.subdomain + old_uri = realm.uri + # If the realm had been a demo organization scheduled for + # deleting, clear that state. + realm.demo_organization_scheduled_deletion_date = None + realm.string_id = new_subdomain + with transaction.atomic(): + realm.save(update_fields=["string_id", "demo_organization_scheduled_deletion_date"]) + RealmAuditLog.objects.create( + realm=realm, + event_type=RealmAuditLog.REALM_SUBDOMAIN_CHANGED, + event_time=timezone_now(), + acting_user=acting_user, + extra_data={"old_subdomain": old_subdomain, "new_subdomain": new_subdomain}, + ) + + # If a realm if being renamed multiple times, we should find all the placeholder + # realms and reset their deactivated_redirect field to point to the new realm uri + placeholder_realms = Realm.objects.filter(deactivated_redirect=old_uri, deactivated=True) + for placeholder_realm in placeholder_realms: + do_add_deactivated_redirect(placeholder_realm, realm.uri) + + # The below block isn't executed in a transaction with the earlier code due to + # the functions called below being complex and potentially sending events, + # which we don't want to do in atomic blocks. + # When we change a realm's subdomain the realm with old subdomain is basically + # deactivated. We are creating a deactivated realm using old subdomain and setting + # it's deactivated redirect to new_subdomain so that we can tell the users that + # the realm has been moved to a new subdomain. + placeholder_realm = do_create_realm(old_subdomain, realm.name) + do_deactivate_realm(placeholder_realm, acting_user=None) + do_add_deactivated_redirect(placeholder_realm, realm.uri) + + +def set_realm_permissions_based_on_org_type(realm: Realm) -> None: + """This function implements overrides for the default configuration + for new organizations when the administrator selected specific + organization types. + + This substantially simplifies our /help/ advice for folks setting + up new organizations of these types. + """ + + # Custom configuration for educational organizations. The present + # defaults are designed for a single class, not a department or + # larger institution, since those are more common. + if ( + realm.org_type == Realm.ORG_TYPES["education_nonprofit"]["id"] + or realm.org_type == Realm.ORG_TYPES["education"]["id"] + ): + # Limit email address visibility and user creation to administrators. + realm.email_address_visibility = Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS + realm.invite_to_realm_policy = Realm.POLICY_ADMINS_ONLY + # Restrict public stream creation to staff, but allow private + # streams (useful for study groups, etc.). + realm.create_public_stream_policy = Realm.POLICY_ADMINS_ONLY + # Don't allow members (students) to manage user groups or + # stream subscriptions. + realm.user_group_edit_policy = Realm.POLICY_MODERATORS_ONLY + realm.invite_to_stream_policy = Realm.POLICY_MODERATORS_ONLY + # Allow moderators (TAs?) to move topics between streams. + realm.move_messages_between_streams_policy = Realm.POLICY_MODERATORS_ONLY + + +def setup_realm_internal_bots(realm: Realm) -> None: + """Create this realm's internal bots. + + This function is idempotent; it does nothing for a bot that + already exists. + """ + internal_bots = [ + (bot["name"], bot["email_template"] % (settings.INTERNAL_BOT_DOMAIN,)) + for bot in settings.REALM_INTERNAL_BOTS + ] + create_users(realm, internal_bots, bot_type=UserProfile.DEFAULT_BOT) + bots = UserProfile.objects.filter( + realm=realm, + email__in=[bot_info[1] for bot_info in internal_bots], + bot_owner__isnull=True, + ) + for bot in bots: + bot.bot_owner = bot + bot.save() + + +def do_create_realm( + string_id: str, + name: str, + *, + emails_restricted_to_domains: Optional[bool] = None, + email_address_visibility: Optional[int] = None, + description: Optional[str] = None, + invite_required: Optional[bool] = None, + plan_type: Optional[int] = None, + org_type: Optional[int] = None, + date_created: Optional[datetime.datetime] = None, + is_demo_organization: Optional[bool] = False, + enable_spectator_access: Optional[bool] = False, +) -> Realm: + if string_id == settings.SOCIAL_AUTH_SUBDOMAIN: + raise AssertionError("Creating a realm on SOCIAL_AUTH_SUBDOMAIN is not allowed!") + if Realm.objects.filter(string_id=string_id).exists(): + raise AssertionError(f"Realm {string_id} already exists!") + if not server_initialized(): + logging.info("Server not yet initialized. Creating the internal realm first.") + create_internal_realm() + + kwargs: Dict[str, Any] = {} + if emails_restricted_to_domains is not None: + kwargs["emails_restricted_to_domains"] = emails_restricted_to_domains + if email_address_visibility is not None: + kwargs["email_address_visibility"] = email_address_visibility + if description is not None: + kwargs["description"] = description + if invite_required is not None: + kwargs["invite_required"] = invite_required + if plan_type is not None: + kwargs["plan_type"] = plan_type + if org_type is not None: + kwargs["org_type"] = org_type + if enable_spectator_access is not None: + kwargs["enable_spectator_access"] = enable_spectator_access + + if date_created is not None: + # The date_created parameter is intended only for use by test + # suites that want to backdate the date of a realm's creation. + assert not settings.PRODUCTION + kwargs["date_created"] = date_created + + with transaction.atomic(): + realm = Realm(string_id=string_id, name=name, **kwargs) + if is_demo_organization: + realm.demo_organization_scheduled_deletion_date = ( + realm.date_created + datetime.timedelta(days=settings.DEMO_ORG_DEADLINE_DAYS) + ) + + set_realm_permissions_based_on_org_type(realm) + realm.save() + + RealmAuditLog.objects.create( + realm=realm, event_type=RealmAuditLog.REALM_CREATED, event_time=realm.date_created + ) + + RealmUserDefault.objects.create(realm=realm) + + create_system_user_groups_for_realm(realm) + + # Create stream once Realm object has been saved + notifications_stream = ensure_stream( + realm, + Realm.DEFAULT_NOTIFICATION_STREAM_NAME, + stream_description="Everyone is added to this stream by default. Welcome! :octopus:", + acting_user=None, + ) + realm.notifications_stream = notifications_stream + + # With the current initial streams situation, the only public + # stream is the notifications_stream. + DefaultStream.objects.create(stream=notifications_stream, realm=realm) + + signup_notifications_stream = ensure_stream( + realm, + Realm.INITIAL_PRIVATE_STREAM_NAME, + invite_only=True, + stream_description="A private stream for core team members.", + acting_user=None, + ) + realm.signup_notifications_stream = signup_notifications_stream + + realm.save(update_fields=["notifications_stream", "signup_notifications_stream"]) + + if plan_type is None and settings.BILLING_ENABLED: + do_change_realm_plan_type(realm, Realm.PLAN_TYPE_LIMITED, acting_user=None) + + admin_realm = get_realm(settings.SYSTEM_BOT_REALM) + sender = get_system_bot(settings.NOTIFICATION_BOT, admin_realm.id) + # Send a notification to the admin realm + signup_message = _("Signups enabled") + + try: + signups_stream = get_signups_stream(admin_realm) + topic = realm.display_subdomain + + internal_send_stream_message( + sender, + signups_stream, + topic, + signup_message, + ) + except Stream.DoesNotExist: # nocoverage + # If the signups stream hasn't been created in the admin + # realm, don't auto-create it to send to it; just do nothing. + pass + + setup_realm_internal_bots(realm) + return realm diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index b799fe2da2..369dd38c7b 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -1,244 +1,7 @@ -import datetime -import logging -from typing import Any, Dict, List, Optional +from typing import List -from django.conf import settings -from django.db import transaction -from django.utils.timezone import now as timezone_now -from django.utils.translation import gettext as _ - -from zerver.actions.message_send import internal_send_stream_message -from zerver.actions.realm_settings import ( - do_add_deactivated_redirect, - do_change_realm_plan_type, - do_deactivate_realm, -) -from zerver.lib.bulk_create import create_users -from zerver.lib.server_initialization import create_internal_realm, server_initialized -from zerver.lib.streams import ensure_stream, get_signups_stream from zerver.lib.topic import filter_by_topic_name_via_message -from zerver.lib.user_groups import create_system_user_groups_for_realm -from zerver.models import ( - DefaultStream, - Message, - Realm, - RealmAuditLog, - RealmUserDefault, - Stream, - UserMessage, - UserProfile, - get_realm, - get_system_bot, -) - - -def do_change_realm_subdomain( - realm: Realm, new_subdomain: str, *, acting_user: Optional[UserProfile] -) -> None: - """Changing a realm's subdomain is a highly disruptive operation, - because all existing clients will need to be updated to point to - the new URL. Further, requests to fetch data from existing event - queues will fail with an authentication error when this change - happens (because the old subdomain is no longer associated with - the realm), making it hard for us to provide a graceful update - experience for clients. - """ - old_subdomain = realm.subdomain - old_uri = realm.uri - # If the realm had been a demo organization scheduled for - # deleting, clear that state. - realm.demo_organization_scheduled_deletion_date = None - realm.string_id = new_subdomain - with transaction.atomic(): - realm.save(update_fields=["string_id", "demo_organization_scheduled_deletion_date"]) - RealmAuditLog.objects.create( - realm=realm, - event_type=RealmAuditLog.REALM_SUBDOMAIN_CHANGED, - event_time=timezone_now(), - acting_user=acting_user, - extra_data={"old_subdomain": old_subdomain, "new_subdomain": new_subdomain}, - ) - - # If a realm if being renamed multiple times, we should find all the placeholder - # realms and reset their deactivated_redirect field to point to the new realm uri - placeholder_realms = Realm.objects.filter(deactivated_redirect=old_uri, deactivated=True) - for placeholder_realm in placeholder_realms: - do_add_deactivated_redirect(placeholder_realm, realm.uri) - - # The below block isn't executed in a transaction with the earlier code due to - # the functions called below being complex and potentially sending events, - # which we don't want to do in atomic blocks. - # When we change a realm's subdomain the realm with old subdomain is basically - # deactivated. We are creating a deactivated realm using old subdomain and setting - # it's deactivated redirect to new_subdomain so that we can tell the users that - # the realm has been moved to a new subdomain. - placeholder_realm = do_create_realm(old_subdomain, realm.name) - do_deactivate_realm(placeholder_realm, acting_user=None) - do_add_deactivated_redirect(placeholder_realm, realm.uri) - - -def set_realm_permissions_based_on_org_type(realm: Realm) -> None: - """This function implements overrides for the default configuration - for new organizations when the administrator selected specific - organization types. - - This substantially simplifies our /help/ advice for folks setting - up new organizations of these types. - """ - - # Custom configuration for educational organizations. The present - # defaults are designed for a single class, not a department or - # larger institution, since those are more common. - if ( - realm.org_type == Realm.ORG_TYPES["education_nonprofit"]["id"] - or realm.org_type == Realm.ORG_TYPES["education"]["id"] - ): - # Limit email address visibility and user creation to administrators. - realm.email_address_visibility = Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS - realm.invite_to_realm_policy = Realm.POLICY_ADMINS_ONLY - # Restrict public stream creation to staff, but allow private - # streams (useful for study groups, etc.). - realm.create_public_stream_policy = Realm.POLICY_ADMINS_ONLY - # Don't allow members (students) to manage user groups or - # stream subscriptions. - realm.user_group_edit_policy = Realm.POLICY_MODERATORS_ONLY - realm.invite_to_stream_policy = Realm.POLICY_MODERATORS_ONLY - # Allow moderators (TAs?) to move topics between streams. - realm.move_messages_between_streams_policy = Realm.POLICY_MODERATORS_ONLY - - -def setup_realm_internal_bots(realm: Realm) -> None: - """Create this realm's internal bots. - - This function is idempotent; it does nothing for a bot that - already exists. - """ - internal_bots = [ - (bot["name"], bot["email_template"] % (settings.INTERNAL_BOT_DOMAIN,)) - for bot in settings.REALM_INTERNAL_BOTS - ] - create_users(realm, internal_bots, bot_type=UserProfile.DEFAULT_BOT) - bots = UserProfile.objects.filter( - realm=realm, - email__in=[bot_info[1] for bot_info in internal_bots], - bot_owner__isnull=True, - ) - for bot in bots: - bot.bot_owner = bot - bot.save() - - -def do_create_realm( - string_id: str, - name: str, - *, - emails_restricted_to_domains: Optional[bool] = None, - email_address_visibility: Optional[int] = None, - description: Optional[str] = None, - invite_required: Optional[bool] = None, - plan_type: Optional[int] = None, - org_type: Optional[int] = None, - date_created: Optional[datetime.datetime] = None, - is_demo_organization: Optional[bool] = False, - enable_spectator_access: Optional[bool] = False, -) -> Realm: - if string_id == settings.SOCIAL_AUTH_SUBDOMAIN: - raise AssertionError("Creating a realm on SOCIAL_AUTH_SUBDOMAIN is not allowed!") - if Realm.objects.filter(string_id=string_id).exists(): - raise AssertionError(f"Realm {string_id} already exists!") - if not server_initialized(): - logging.info("Server not yet initialized. Creating the internal realm first.") - create_internal_realm() - - kwargs: Dict[str, Any] = {} - if emails_restricted_to_domains is not None: - kwargs["emails_restricted_to_domains"] = emails_restricted_to_domains - if email_address_visibility is not None: - kwargs["email_address_visibility"] = email_address_visibility - if description is not None: - kwargs["description"] = description - if invite_required is not None: - kwargs["invite_required"] = invite_required - if plan_type is not None: - kwargs["plan_type"] = plan_type - if org_type is not None: - kwargs["org_type"] = org_type - if enable_spectator_access is not None: - kwargs["enable_spectator_access"] = enable_spectator_access - - if date_created is not None: - # The date_created parameter is intended only for use by test - # suites that want to backdate the date of a realm's creation. - assert not settings.PRODUCTION - kwargs["date_created"] = date_created - - with transaction.atomic(): - realm = Realm(string_id=string_id, name=name, **kwargs) - if is_demo_organization: - realm.demo_organization_scheduled_deletion_date = ( - realm.date_created + datetime.timedelta(days=settings.DEMO_ORG_DEADLINE_DAYS) - ) - - set_realm_permissions_based_on_org_type(realm) - realm.save() - - RealmAuditLog.objects.create( - realm=realm, event_type=RealmAuditLog.REALM_CREATED, event_time=realm.date_created - ) - - RealmUserDefault.objects.create(realm=realm) - - create_system_user_groups_for_realm(realm) - - # Create stream once Realm object has been saved - notifications_stream = ensure_stream( - realm, - Realm.DEFAULT_NOTIFICATION_STREAM_NAME, - stream_description="Everyone is added to this stream by default. Welcome! :octopus:", - acting_user=None, - ) - realm.notifications_stream = notifications_stream - - # With the current initial streams situation, the only public - # stream is the notifications_stream. - DefaultStream.objects.create(stream=notifications_stream, realm=realm) - - signup_notifications_stream = ensure_stream( - realm, - Realm.INITIAL_PRIVATE_STREAM_NAME, - invite_only=True, - stream_description="A private stream for core team members.", - acting_user=None, - ) - realm.signup_notifications_stream = signup_notifications_stream - - realm.save(update_fields=["notifications_stream", "signup_notifications_stream"]) - - if plan_type is None and settings.BILLING_ENABLED: - do_change_realm_plan_type(realm, Realm.PLAN_TYPE_LIMITED, acting_user=None) - - admin_realm = get_realm(settings.SYSTEM_BOT_REALM) - sender = get_system_bot(settings.NOTIFICATION_BOT, admin_realm.id) - # Send a notification to the admin realm - signup_message = _("Signups enabled") - - try: - signups_stream = get_signups_stream(admin_realm) - topic = realm.display_subdomain - - internal_send_stream_message( - sender, - signups_stream, - topic, - signup_message, - ) - except Stream.DoesNotExist: # nocoverage - # If the signups stream hasn't been created in the admin - # realm, don't auto-create it to send to it; just do nothing. - pass - - setup_realm_internal_bots(realm) - return realm +from zerver.models import Message, Stream, UserMessage, UserProfile def get_topic_messages(user_profile: UserProfile, stream: Stream, topic_name: str) -> List[Message]: diff --git a/zerver/lib/onboarding.py b/zerver/lib/onboarding.py index a4cc2a8620..ece845fbf1 100644 --- a/zerver/lib/onboarding.py +++ b/zerver/lib/onboarding.py @@ -5,13 +5,13 @@ from django.db import transaction from django.db.models import Count from django.utils.translation import gettext as _ +from zerver.actions.create_realm import setup_realm_internal_bots from zerver.actions.message_send import ( do_send_messages, internal_prep_stream_message_by_name, internal_send_private_message, ) from zerver.actions.reactions import do_add_reaction -from zerver.lib.actions import setup_realm_internal_bots from zerver.lib.emoji import emoji_name_to_emoji_code from zerver.lib.message import SendMessageRequest from zerver.models import Message, Realm, UserProfile, get_system_bot diff --git a/zerver/management/commands/change_realm_subdomain.py b/zerver/management/commands/change_realm_subdomain.py index 99d26a1bc4..0b98245699 100644 --- a/zerver/management/commands/change_realm_subdomain.py +++ b/zerver/management/commands/change_realm_subdomain.py @@ -1,7 +1,7 @@ from argparse import ArgumentParser from typing import Any -from zerver.lib.actions import do_change_realm_subdomain +from zerver.actions.create_realm import do_change_realm_subdomain from zerver.lib.management import ZulipBaseCommand diff --git a/zerver/management/commands/create_realm.py b/zerver/management/commands/create_realm.py index 134f4b7663..05c9865d63 100644 --- a/zerver/management/commands/create_realm.py +++ b/zerver/management/commands/create_realm.py @@ -3,8 +3,8 @@ from typing import Any from django.core.management.base import CommandError +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import do_create_user -from zerver.lib.actions import do_create_realm from zerver.lib.management import ZulipBaseCommand from zerver.models import UserProfile diff --git a/zerver/tests/test_auth_backends.py b/zerver/tests/test_auth_backends.py index a6f98d03c8..5e2a7f922d 100644 --- a/zerver/tests/test_auth_backends.py +++ b/zerver/tests/test_auth_backends.py @@ -40,6 +40,7 @@ from social_django.storage import BaseDjangoStorage from social_django.strategy import DjangoStrategy from confirmation.models import Confirmation, create_confirmation_link +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import do_create_user, do_reactivate_user from zerver.actions.invites import do_invite_users from zerver.actions.realm_settings import ( @@ -49,7 +50,6 @@ from zerver.actions.realm_settings import ( ) from zerver.actions.user_settings import do_change_password from zerver.actions.users import change_user_is_active, do_deactivate_user -from zerver.lib.actions import do_create_realm from zerver.lib.avatar import avatar_url from zerver.lib.avatar_hash import user_avatar_path from zerver.lib.dev_ldap_directory import generate_dev_ldap_dir diff --git a/zerver/tests/test_decorators.py b/zerver/tests/test_decorators.py index 5384075001..999d6f3e9e 100644 --- a/zerver/tests/test_decorators.py +++ b/zerver/tests/test_decorators.py @@ -14,6 +14,7 @@ from django.core.exceptions import ValidationError from django.http import HttpRequest, HttpResponse from django.utils.timezone import now as timezone_now +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import do_reactivate_user from zerver.actions.realm_settings import ( do_deactivate_realm, @@ -35,7 +36,6 @@ from zerver.decorator import ( zulip_login_required, ) from zerver.forms import OurAuthenticationForm -from zerver.lib.actions import do_create_realm from zerver.lib.cache import dict_to_items_tuple, ignore_unhashable_lru_cache, items_tuple_to_dict from zerver.lib.exceptions import ( AccessDeniedError, diff --git a/zerver/tests/test_markdown.py b/zerver/tests/test_markdown.py index 1e0332f9a5..57e954b0a6 100644 --- a/zerver/tests/test_markdown.py +++ b/zerver/tests/test_markdown.py @@ -11,11 +11,11 @@ from django.test import override_settings from markdown import Markdown from zerver.actions.alert_words import do_add_alert_words +from zerver.actions.create_realm import do_create_realm from zerver.actions.realm_emoji import do_remove_realm_emoji from zerver.actions.realm_settings import do_set_realm_property from zerver.actions.user_settings import do_change_user_setting from zerver.actions.users import change_user_is_active -from zerver.lib.actions import do_create_realm from zerver.lib.alert_words import get_alert_word_automaton from zerver.lib.camo import get_camo_url from zerver.lib.create_user import create_user diff --git a/zerver/tests/test_message_send.py b/zerver/tests/test_message_send.py index 53d9b273f5..6409af571c 100644 --- a/zerver/tests/test_message_send.py +++ b/zerver/tests/test_message_send.py @@ -10,6 +10,7 @@ from django.http import HttpResponse from django.test import override_settings from django.utils.timezone import now as timezone_now +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import do_create_user from zerver.actions.message_send import ( build_message_send_dict, @@ -30,7 +31,6 @@ from zerver.actions.realm_domains import do_add_realm_domain from zerver.actions.realm_settings import do_set_realm_property from zerver.actions.streams import do_change_stream_post_policy from zerver.actions.users import do_change_can_forge_sender, do_deactivate_user -from zerver.lib.actions import do_create_realm from zerver.lib.addressee import Addressee from zerver.lib.cache import cache_delete, get_stream_cache_key from zerver.lib.exceptions import JsonableError diff --git a/zerver/tests/test_realm.py b/zerver/tests/test_realm.py index 1d4e75c1aa..54b2c22ad4 100644 --- a/zerver/tests/test_realm.py +++ b/zerver/tests/test_realm.py @@ -9,6 +9,7 @@ from django.conf import settings from django.utils.timezone import now as timezone_now from confirmation.models import Confirmation, create_confirmation_link +from zerver.actions.create_realm import do_change_realm_subdomain, do_create_realm from zerver.actions.realm_settings import ( do_add_deactivated_redirect, do_change_realm_org_type, @@ -20,7 +21,6 @@ from zerver.actions.realm_settings import ( do_set_realm_user_default_setting, ) from zerver.actions.streams import do_deactivate_stream -from zerver.lib.actions import do_change_realm_subdomain, do_create_realm from zerver.lib.realm_description import get_realm_rendered_description, get_realm_text_description from zerver.lib.send_email import send_future_email from zerver.lib.streams import create_stream_if_needed @@ -51,9 +51,9 @@ class RealmTest(ZulipTestCase): self.assertEqual(user_profile.realm.name, new_realm_name) def test_realm_creation_ensures_internal_realms(self) -> None: - with mock.patch("zerver.lib.actions.server_initialized", return_value=False): + with mock.patch("zerver.actions.create_realm.server_initialized", return_value=False): with mock.patch( - "zerver.lib.actions.create_internal_realm" + "zerver.actions.create_realm.create_internal_realm" ) as mock_create_internal, self.assertLogs(level="INFO") as info_logs: do_create_realm("testrealm", "Test Realm") mock_create_internal.assert_called_once() diff --git a/zerver/tests/test_realm_domains.py b/zerver/tests/test_realm_domains.py index 5fe2c78191..d3a3a16f6d 100644 --- a/zerver/tests/test_realm_domains.py +++ b/zerver/tests/test_realm_domains.py @@ -2,10 +2,10 @@ import orjson from django.core.exceptions import ValidationError from django.db.utils import IntegrityError +from zerver.actions.create_realm import do_create_realm from zerver.actions.realm_domains import do_change_realm_domain, do_remove_realm_domain from zerver.actions.realm_settings import do_set_realm_property from zerver.actions.users import do_change_user_role -from zerver.lib.actions import do_create_realm from zerver.lib.domains import validate_domain from zerver.lib.email_validation import email_allowed_for_realm from zerver.lib.test_classes import ZulipTestCase diff --git a/zerver/tests/test_realm_emoji.py b/zerver/tests/test_realm_emoji.py index c5f5308d81..d06611eee4 100644 --- a/zerver/tests/test_realm_emoji.py +++ b/zerver/tests/test_realm_emoji.py @@ -1,10 +1,10 @@ from unittest import mock +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import do_create_user from zerver.actions.realm_emoji import check_add_realm_emoji from zerver.actions.realm_settings import do_set_realm_property from zerver.actions.users import do_change_user_role -from zerver.lib.actions import do_create_realm from zerver.lib.exceptions import JsonableError from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_helpers import get_test_image_file diff --git a/zerver/tests/test_retention.py b/zerver/tests/test_retention.py index bc3d7200e9..cdfa40c394 100644 --- a/zerver/tests/test_retention.py +++ b/zerver/tests/test_retention.py @@ -5,11 +5,11 @@ from unittest import mock from django.conf import settings from django.utils.timezone import now as timezone_now +from zerver.actions.create_realm import do_create_realm from zerver.actions.message_edit import do_delete_messages from zerver.actions.message_send import internal_send_private_message from zerver.actions.realm_settings import do_set_realm_property from zerver.actions.submessage import do_add_submessage -from zerver.lib.actions import do_create_realm from zerver.lib.retention import ( archive_messages, clean_archived_data, diff --git a/zerver/tests/test_signup.py b/zerver/tests/test_signup.py index f62d9b08f4..f6db878f30 100644 --- a/zerver/tests/test_signup.py +++ b/zerver/tests/test_signup.py @@ -25,6 +25,7 @@ from confirmation.models import ( one_click_unsubscribe_link, ) from corporate.lib.stripe import get_latest_seat_count +from zerver.actions.create_realm import do_change_realm_subdomain, do_create_realm from zerver.actions.create_user import add_new_user_history, do_create_user, process_new_human_user from zerver.actions.default_streams import ( do_add_default_stream, @@ -46,7 +47,6 @@ from zerver.actions.users import change_user_is_active, do_change_user_role, do_ from zerver.context_processors import common_context from zerver.decorator import do_two_factor_login from zerver.forms import HomepageForm, check_subdomain_available -from zerver.lib.actions import do_change_realm_subdomain, do_create_realm from zerver.lib.email_notifications import enqueue_welcome_emails, followup_day2_email_delay from zerver.lib.initial_password import initial_password from zerver.lib.mobile_auth_otp import ( diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index ab097736e2..8a731de8bf 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -11,6 +11,7 @@ from django.core.exceptions import ValidationError from django.http import HttpResponse from django.utils.timezone import now as timezone_now +from zerver.actions.create_realm import do_create_realm from zerver.actions.default_streams import ( do_add_default_stream, do_add_streams_to_default_stream_group, @@ -32,7 +33,7 @@ from zerver.actions.streams import ( do_deactivate_stream, ) from zerver.actions.users import do_change_user_role, do_deactivate_user -from zerver.lib.actions import do_create_realm, get_topic_messages +from zerver.lib.actions import get_topic_messages from zerver.lib.exceptions import JsonableError from zerver.lib.message import UnreadStreamInfo, aggregate_unread_data, get_raw_unread_data from zerver.lib.response import json_success diff --git a/zerver/tests/test_upload.py b/zerver/tests/test_upload.py index dea2ba5624..ab4d01c0bb 100644 --- a/zerver/tests/test_upload.py +++ b/zerver/tests/test_upload.py @@ -19,13 +19,13 @@ from django_sendfile.utils import _get_sendfile from PIL import Image import zerver.lib.upload +from zerver.actions.create_realm import do_create_realm from zerver.actions.message_send import internal_send_private_message from zerver.actions.realm_icon import do_change_icon_source from zerver.actions.realm_logo import do_change_logo_source from zerver.actions.realm_settings import do_change_realm_plan_type, do_set_realm_property from zerver.actions.uploads import do_delete_old_unclaimed_attachments from zerver.actions.user_settings import do_delete_avatar_image -from zerver.lib.actions import do_create_realm from zerver.lib.avatar import avatar_url, get_avatar_field from zerver.lib.avatar_hash import user_avatar_path from zerver.lib.cache import cache_get, get_realm_used_upload_space_cache_key diff --git a/zerver/views/realm.py b/zerver/views/realm.py index 177606e449..c83fd6c8f5 100644 --- a/zerver/views/realm.py +++ b/zerver/views/realm.py @@ -7,6 +7,7 @@ from django.utils.translation import gettext as _ from django.views.decorators.http import require_safe from confirmation.models import Confirmation, ConfirmationKeyException, get_object_from_key +from zerver.actions.create_realm import do_change_realm_subdomain from zerver.actions.realm_settings import ( do_deactivate_realm, do_reactivate_realm, @@ -19,7 +20,6 @@ from zerver.actions.realm_settings import ( ) from zerver.decorator import require_realm_admin, require_realm_owner from zerver.forms import check_subdomain_available as check_subdomain -from zerver.lib.actions import do_change_realm_subdomain from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequired from zerver.lib.i18n import get_available_language_codes from zerver.lib.message import parse_message_content_delete_limit diff --git a/zerver/views/registration.py b/zerver/views/registration.py index 977a1de23e..c05285a56d 100644 --- a/zerver/views/registration.py +++ b/zerver/views/registration.py @@ -25,6 +25,7 @@ from confirmation.models import ( render_confirmation_key_error, validate_key, ) +from zerver.actions.create_realm import do_create_realm from zerver.actions.create_user import do_activate_mirror_dummy_user, do_create_user from zerver.actions.default_streams import lookup_default_stream_groups from zerver.actions.user_settings import ( @@ -41,7 +42,6 @@ from zerver.forms import ( RealmRedirectForm, RegistrationForm, ) -from zerver.lib.actions import do_create_realm from zerver.lib.email_validation import email_allowed_for_realm, validate_email_not_already_in_realm from zerver.lib.exceptions import RateLimited from zerver.lib.pysa import mark_sanitized diff --git a/zilencer/management/commands/populate_db.py b/zilencer/management/commands/populate_db.py index b4a9a71dac..1183a6002f 100644 --- a/zilencer/management/commands/populate_db.py +++ b/zilencer/management/commands/populate_db.py @@ -18,6 +18,7 @@ from django.utils.timezone import now as timezone_now from django.utils.timezone import timedelta as timezone_timedelta from scripts.lib.zulip_tools import get_or_create_dev_uuid_var_path +from zerver.actions.create_realm import do_create_realm from zerver.actions.custom_profile_fields import ( do_update_user_custom_profile_data_if_changed, try_add_realm_custom_profile_field, @@ -26,7 +27,6 @@ from zerver.actions.custom_profile_fields import ( from zerver.actions.message_send import build_message_send_dict, do_send_messages from zerver.actions.realm_emoji import check_add_realm_emoji from zerver.actions.users import do_change_user_role -from zerver.lib.actions import do_create_realm from zerver.lib.bulk_create import bulk_create_streams from zerver.lib.cache import cache_set from zerver.lib.generate_test_data import create_test_data, generate_topics @@ -302,7 +302,7 @@ class Command(BaseCommand): clear_database() # Create our three default realms - # Could in theory be done via zerver.lib.actions.do_create_realm, but + # Could in theory be done via zerver.actions.create_realm.do_create_realm, but # welcome-bot (needed for do_create_realm) hasn't been created yet create_internal_realm() zulip_realm = do_create_realm(