mirror of https://github.com/zulip/zulip.git
actions: Split out zerver.actions.realm_settings.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
12de8d797e
commit
59f6b090c7
|
@ -8,7 +8,7 @@ from django.utils.timezone import now as timezone_now
|
|||
from corporate.lib.stripe import add_months, update_sponsorship_status
|
||||
from corporate.models import Customer, CustomerPlan, LicenseLedger, get_customer_by_realm
|
||||
from zerver.actions.invites import do_create_multiuse_invite_link
|
||||
from zerver.lib.actions import do_send_realm_reactivation_email, do_set_realm_property
|
||||
from zerver.actions.realm_settings import do_send_realm_reactivation_email, do_set_realm_property
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.lib.test_helpers import reset_emails_in_zulip_realm
|
||||
from zerver.models import (
|
||||
|
|
|
@ -16,16 +16,16 @@ from django.utils.translation import gettext as _
|
|||
|
||||
from confirmation.models import Confirmation, confirmation_url
|
||||
from confirmation.settings import STATUS_ACTIVE
|
||||
from zerver.decorator import require_server_admin
|
||||
from zerver.forms import check_subdomain_available
|
||||
from zerver.lib.actions import (
|
||||
from zerver.actions.realm_settings import (
|
||||
do_change_realm_org_type,
|
||||
do_change_realm_plan_type,
|
||||
do_change_realm_subdomain,
|
||||
do_deactivate_realm,
|
||||
do_scrub_realm,
|
||||
do_send_realm_reactivation_email,
|
||||
)
|
||||
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
|
||||
|
|
|
@ -748,7 +748,7 @@ def process_initial_upgrade(
|
|||
)
|
||||
stripe.Invoice.finalize_invoice(stripe_invoice)
|
||||
|
||||
from zerver.lib.actions import do_change_realm_plan_type
|
||||
from zerver.actions.realm_settings import do_change_realm_plan_type
|
||||
|
||||
do_change_realm_plan_type(realm, Realm.PLAN_TYPE_STANDARD, acting_user=user)
|
||||
|
||||
|
@ -972,7 +972,7 @@ def update_sponsorship_status(
|
|||
|
||||
def approve_sponsorship(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||
from zerver.actions.message_send import internal_send_private_message
|
||||
from zerver.lib.actions import do_change_realm_plan_type
|
||||
from zerver.actions.realm_settings import do_change_realm_plan_type
|
||||
|
||||
do_change_realm_plan_type(realm, Realm.PLAN_TYPE_STANDARD_FREE, acting_user=acting_user)
|
||||
customer = get_customer_by_realm(realm)
|
||||
|
@ -1021,7 +1021,7 @@ def do_change_plan_status(plan: CustomerPlan, status: int) -> None:
|
|||
|
||||
|
||||
def process_downgrade(plan: CustomerPlan) -> None:
|
||||
from zerver.lib.actions import do_change_realm_plan_type
|
||||
from zerver.actions.realm_settings import do_change_realm_plan_type
|
||||
|
||||
assert plan.customer.realm is not None
|
||||
do_change_realm_plan_type(plan.customer.realm, Realm.PLAN_TYPE_LIMITED, acting_user=None)
|
||||
|
|
|
@ -86,8 +86,9 @@ from zerver.actions.create_user import (
|
|||
do_create_user,
|
||||
do_reactivate_user,
|
||||
)
|
||||
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, do_deactivate_realm, do_reactivate_realm
|
||||
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
|
||||
|
|
|
@ -38,7 +38,7 @@ organization in Zulip). The following files are involved in the process:
|
|||
- `zerver/models.py`: Defines the database model.
|
||||
- `zerver/views/realm.py`: The view function that implements the API endpoint
|
||||
for editing realm objects.
|
||||
- `zerver/lib/actions.py`: Contains code for updating and interacting with the database.
|
||||
- `zerver/actions/realm_settings.py`: Contains code for updating and interacting with the database.
|
||||
- `zerver/lib/events.py`: Ensures that the state Zulip sends to clients is always
|
||||
consistent and correct.
|
||||
|
||||
|
@ -101,7 +101,7 @@ the flow of events even if the `property_types` framework means you don't
|
|||
have to write much code for a new setting.
|
||||
|
||||
**Database interaction:** Add any necessary code for updating and
|
||||
interacting with the database in `zerver/lib/actions.py`. It should
|
||||
interacting with the database in `zerver/actions/realm_settings.py`. It should
|
||||
update the database and send an event announcing the change.
|
||||
|
||||
**Application state:** Modify the `fetch_initial_state_data` and
|
||||
|
@ -290,10 +290,10 @@ gory details.
|
|||
Anyway, getting back to implementation details...
|
||||
|
||||
If you are working on a feature that is in the realm `property_types`
|
||||
dictionary, you will not need to add code to `zerver/lib/actions.py`, but
|
||||
dictionary, you will not need to add code to `zerver/actions/realm_settings.py`, but
|
||||
we will describe what the process in that file does:
|
||||
|
||||
In `zerver/lib/actions.py`, the function `do_set_realm_property` takes
|
||||
In `zerver/actions/realm_settings.py`, the function `do_set_realm_property` takes
|
||||
in the name of a realm property to update and the value it should
|
||||
have. This function updates the database and triggers an event to
|
||||
notify clients about the change. It uses the field's type, specified
|
||||
|
@ -310,7 +310,7 @@ time display format), members in a particular stream only or all
|
|||
active users in a realm.
|
||||
|
||||
```python
|
||||
# zerver/lib/actions.py
|
||||
# zerver/actions/realm_settings.py
|
||||
|
||||
def do_set_realm_property(
|
||||
realm: Realm, name: str, value: Any, *, acting_user: Optional[UserProfile]
|
||||
|
@ -340,7 +340,7 @@ field), you'll need to create a new function to explicitly update this
|
|||
field and send an event. For example:
|
||||
|
||||
```python
|
||||
# zerver/lib/actions.py
|
||||
# zerver/actions/realm_settings.p
|
||||
|
||||
def do_set_realm_authentication_methods(
|
||||
realm: Realm, authentication_methods: Dict[str, bool], *, acting_user: Optional[UserProfile]
|
||||
|
@ -480,7 +480,7 @@ with the new value. E.g., for `authentication_methods`, we created
|
|||
# zerver/views/realm.py
|
||||
|
||||
# import do_set_realm_authentication_methods from actions.py
|
||||
from zerver.lib.actions import (
|
||||
from zerver.actions.realm_settings import (
|
||||
do_set_realm_message_editing,
|
||||
do_set_realm_authentication_methods,
|
||||
# ...
|
||||
|
|
|
@ -32,8 +32,8 @@ with test_server_running(
|
|||
# zerver imports should happen after `django.setup()` is run
|
||||
# by the test_server_running decorator.
|
||||
from zerver.actions.create_user import do_create_user, do_reactivate_user
|
||||
from zerver.actions.realm_settings import do_deactivate_realm, do_reactivate_realm
|
||||
from zerver.actions.users import change_user_is_active
|
||||
from zerver.lib.actions import do_deactivate_realm, do_reactivate_realm
|
||||
from zerver.lib.test_helpers import reset_emails_in_zulip_realm
|
||||
from zerver.lib.users import get_api_key
|
||||
from zerver.models import get_realm, get_user
|
||||
|
|
|
@ -0,0 +1,472 @@
|
|||
from typing import Any, Dict, Optional, Sequence
|
||||
|
||||
import orjson
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from django.utils.timezone import now as timezone_now
|
||||
|
||||
from confirmation.models import Confirmation, create_confirmation_link, generate_key
|
||||
from zerver.actions.custom_profile_fields import do_remove_realm_custom_profile_fields
|
||||
from zerver.actions.message_edit import do_delete_messages_by_sender
|
||||
from zerver.actions.user_groups import update_users_in_full_members_system_group
|
||||
from zerver.actions.user_settings import do_delete_avatar_image, send_user_email_update_event
|
||||
from zerver.lib.cache import flush_user_profile
|
||||
from zerver.lib.create_user import get_display_email_address
|
||||
from zerver.lib.message import update_first_visible_message_id
|
||||
from zerver.lib.send_email import FromAddress, send_email_to_admins
|
||||
from zerver.lib.sessions import delete_user_sessions
|
||||
from zerver.lib.user_counts import realm_user_count_by_role
|
||||
from zerver.models import (
|
||||
Attachment,
|
||||
Realm,
|
||||
RealmAuditLog,
|
||||
RealmUserDefault,
|
||||
ScheduledEmail,
|
||||
Stream,
|
||||
UserProfile,
|
||||
active_user_ids,
|
||||
)
|
||||
from zerver.tornado.django_api import send_event
|
||||
|
||||
if settings.BILLING_ENABLED:
|
||||
from corporate.lib.stripe import downgrade_now_without_creating_additional_invoices
|
||||
|
||||
|
||||
def active_humans_in_realm(realm: Realm) -> Sequence[UserProfile]:
|
||||
return UserProfile.objects.filter(realm=realm, is_active=True, is_bot=False)
|
||||
|
||||
|
||||
@transaction.atomic(savepoint=False)
|
||||
def do_set_realm_property(
|
||||
realm: Realm, name: str, value: Any, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
"""Takes in a realm object, the name of an attribute to update, the
|
||||
value to update and and the user who initiated the update.
|
||||
"""
|
||||
property_type = Realm.property_types[name]
|
||||
assert isinstance(
|
||||
value, property_type
|
||||
), f"Cannot update {name}: {value} is not an instance of {property_type}"
|
||||
|
||||
old_value = getattr(realm, name)
|
||||
setattr(realm, name, value)
|
||||
realm.save(update_fields=[name])
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update",
|
||||
property=name,
|
||||
value=value,
|
||||
)
|
||||
transaction.on_commit(lambda: send_event(realm, event, active_user_ids(realm.id)))
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: value,
|
||||
"property": name,
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
if name == "email_address_visibility":
|
||||
if Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE not in [old_value, value]:
|
||||
# We use real email addresses on UserProfile.email only if
|
||||
# EMAIL_ADDRESS_VISIBILITY_EVERYONE is configured, so
|
||||
# changes between values that will not require changing
|
||||
# that field, so we can save work and return here.
|
||||
return
|
||||
|
||||
user_profiles = UserProfile.objects.filter(realm=realm, is_bot=False)
|
||||
for user_profile in user_profiles:
|
||||
user_profile.email = get_display_email_address(user_profile)
|
||||
UserProfile.objects.bulk_update(user_profiles, ["email"])
|
||||
|
||||
for user_profile in user_profiles:
|
||||
transaction.on_commit(
|
||||
lambda: flush_user_profile(sender=UserProfile, instance=user_profile)
|
||||
)
|
||||
# TODO: Design a bulk event for this or force-reload all clients
|
||||
send_user_email_update_event(user_profile)
|
||||
|
||||
if name == "waiting_period_threshold":
|
||||
update_users_in_full_members_system_group(realm)
|
||||
|
||||
|
||||
def do_set_realm_authentication_methods(
|
||||
realm: Realm, authentication_methods: Dict[str, bool], *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.authentication_methods_dict()
|
||||
with transaction.atomic():
|
||||
for key, value in list(authentication_methods.items()):
|
||||
index = getattr(realm.authentication_methods, key).number
|
||||
realm.authentication_methods.set_bit(index, int(value))
|
||||
realm.save(update_fields=["authentication_methods"])
|
||||
updated_value = realm.authentication_methods_dict()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: updated_value,
|
||||
"property": "authentication_methods",
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update_dict",
|
||||
property="default",
|
||||
data=dict(authentication_methods=updated_value),
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_message_editing(
|
||||
realm: Realm,
|
||||
allow_message_editing: bool,
|
||||
message_content_edit_limit_seconds: int,
|
||||
edit_topic_policy: int,
|
||||
*,
|
||||
acting_user: Optional[UserProfile],
|
||||
) -> None:
|
||||
old_values = dict(
|
||||
allow_message_editing=realm.allow_message_editing,
|
||||
message_content_edit_limit_seconds=realm.message_content_edit_limit_seconds,
|
||||
edit_topic_policy=realm.edit_topic_policy,
|
||||
)
|
||||
|
||||
realm.allow_message_editing = allow_message_editing
|
||||
realm.message_content_edit_limit_seconds = message_content_edit_limit_seconds
|
||||
realm.edit_topic_policy = edit_topic_policy
|
||||
|
||||
event_time = timezone_now()
|
||||
updated_properties = dict(
|
||||
allow_message_editing=allow_message_editing,
|
||||
message_content_edit_limit_seconds=message_content_edit_limit_seconds,
|
||||
edit_topic_policy=edit_topic_policy,
|
||||
)
|
||||
|
||||
with transaction.atomic():
|
||||
for updated_property, updated_value in updated_properties.items():
|
||||
if updated_value == old_values[updated_property]:
|
||||
continue
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_values[updated_property],
|
||||
RealmAuditLog.NEW_VALUE: updated_value,
|
||||
"property": updated_property,
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
realm.save(update_fields=list(updated_properties.keys()))
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update_dict",
|
||||
property="default",
|
||||
data=updated_properties,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_notifications_stream(
|
||||
realm: Realm, stream: Optional[Stream], stream_id: int, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.notifications_stream_id
|
||||
realm.notifications_stream = stream
|
||||
with transaction.atomic():
|
||||
realm.save(update_fields=["notifications_stream"])
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: stream_id,
|
||||
"property": "notifications_stream",
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update",
|
||||
property="notifications_stream_id",
|
||||
value=stream_id,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_signup_notifications_stream(
|
||||
realm: Realm, stream: Optional[Stream], stream_id: int, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.signup_notifications_stream_id
|
||||
realm.signup_notifications_stream = stream
|
||||
with transaction.atomic():
|
||||
realm.save(update_fields=["signup_notifications_stream"])
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: stream_id,
|
||||
"property": "signup_notifications_stream",
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update",
|
||||
property="signup_notifications_stream_id",
|
||||
value=stream_id,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_user_default_setting(
|
||||
realm_user_default: RealmUserDefault,
|
||||
name: str,
|
||||
value: Any,
|
||||
*,
|
||||
acting_user: Optional[UserProfile],
|
||||
) -> None:
|
||||
old_value = getattr(realm_user_default, name)
|
||||
realm = realm_user_default.realm
|
||||
event_time = timezone_now()
|
||||
|
||||
with transaction.atomic(savepoint=False):
|
||||
setattr(realm_user_default, name, value)
|
||||
realm_user_default.save(update_fields=[name])
|
||||
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_DEFAULT_USER_SETTINGS_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: value,
|
||||
"property": name,
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
event = dict(
|
||||
type="realm_user_settings_defaults",
|
||||
op="update",
|
||||
property=name,
|
||||
value=value,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_deactivate_realm(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||
"""
|
||||
Deactivate this realm. Do NOT deactivate the users -- we need to be able to
|
||||
tell the difference between users that were intentionally deactivated,
|
||||
e.g. by a realm admin, and users who can't currently use Zulip because their
|
||||
realm has been deactivated.
|
||||
"""
|
||||
if realm.deactivated:
|
||||
return
|
||||
|
||||
realm.deactivated = True
|
||||
realm.save(update_fields=["deactivated"])
|
||||
|
||||
if settings.BILLING_ENABLED:
|
||||
downgrade_now_without_creating_additional_invoices(realm)
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_DEACTIVATED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.ROLE_COUNT: realm_user_count_by_role(realm),
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
ScheduledEmail.objects.filter(realm=realm).delete()
|
||||
for user in active_humans_in_realm(realm):
|
||||
# Don't deactivate the users, but do delete their sessions so they get
|
||||
# bumped to the login screen, where they'll get a realm deactivation
|
||||
# notice when they try to log in.
|
||||
delete_user_sessions(user)
|
||||
|
||||
# This event will only ever be received by clients with an active
|
||||
# longpoll connection, because by this point clients will be
|
||||
# unable to authenticate again to their event queue (triggering an
|
||||
# immediate reload into the page explaining the realm was
|
||||
# deactivated). So the purpose of sending this is to flush all
|
||||
# active longpoll connections for the realm.
|
||||
event = dict(type="realm", op="deactivated", realm_id=realm.id)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_reactivate_realm(realm: Realm) -> None:
|
||||
realm.deactivated = False
|
||||
with transaction.atomic():
|
||||
realm.save(update_fields=["deactivated"])
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_REACTIVATED,
|
||||
event_time=event_time,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.ROLE_COUNT: realm_user_count_by_role(realm),
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
|
||||
def do_add_deactivated_redirect(realm: Realm, redirect_url: str) -> None:
|
||||
realm.deactivated_redirect = redirect_url
|
||||
realm.save(update_fields=["deactivated_redirect"])
|
||||
|
||||
|
||||
def do_scrub_realm(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||
if settings.BILLING_ENABLED:
|
||||
downgrade_now_without_creating_additional_invoices(realm)
|
||||
|
||||
users = UserProfile.objects.filter(realm=realm)
|
||||
for user in users:
|
||||
do_delete_messages_by_sender(user)
|
||||
do_delete_avatar_image(user, acting_user=acting_user)
|
||||
user.full_name = f"Scrubbed {generate_key()[:15]}"
|
||||
scrubbed_email = f"scrubbed-{generate_key()[:15]}@{realm.host}"
|
||||
user.email = scrubbed_email
|
||||
user.delivery_email = scrubbed_email
|
||||
user.save(update_fields=["full_name", "email", "delivery_email"])
|
||||
|
||||
do_remove_realm_custom_profile_fields(realm)
|
||||
Attachment.objects.filter(realm=realm).delete()
|
||||
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
event_type=RealmAuditLog.REALM_SCRUBBED,
|
||||
)
|
||||
|
||||
|
||||
@transaction.atomic(durable=True)
|
||||
def do_change_realm_org_type(
|
||||
realm: Realm,
|
||||
org_type: int,
|
||||
acting_user: Optional[UserProfile],
|
||||
) -> None:
|
||||
old_value = realm.org_type
|
||||
realm.org_type = org_type
|
||||
realm.save(update_fields=["org_type"])
|
||||
|
||||
RealmAuditLog.objects.create(
|
||||
event_type=RealmAuditLog.REALM_ORG_TYPE_CHANGED,
|
||||
realm=realm,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
extra_data={"old_value": old_value, "new_value": org_type},
|
||||
)
|
||||
|
||||
|
||||
@transaction.atomic(savepoint=False)
|
||||
def do_change_realm_plan_type(
|
||||
realm: Realm, plan_type: int, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.plan_type
|
||||
realm.plan_type = plan_type
|
||||
realm.save(update_fields=["plan_type"])
|
||||
RealmAuditLog.objects.create(
|
||||
event_type=RealmAuditLog.REALM_PLAN_TYPE_CHANGED,
|
||||
realm=realm,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
extra_data={"old_value": old_value, "new_value": plan_type},
|
||||
)
|
||||
|
||||
if plan_type == Realm.PLAN_TYPE_PLUS:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_STANDARD
|
||||
elif plan_type == Realm.PLAN_TYPE_STANDARD:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_STANDARD
|
||||
elif plan_type == Realm.PLAN_TYPE_SELF_HOSTED:
|
||||
realm.max_invites = None # type: ignore[assignment] # Apparent mypy bug with Optional[int] setter.
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = None
|
||||
elif plan_type == Realm.PLAN_TYPE_STANDARD_FREE:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_STANDARD
|
||||
elif plan_type == Realm.PLAN_TYPE_LIMITED:
|
||||
realm.max_invites = settings.INVITES_DEFAULT_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = Realm.MESSAGE_VISIBILITY_LIMITED
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_LIMITED
|
||||
else:
|
||||
raise AssertionError("Invalid plan type")
|
||||
|
||||
update_first_visible_message_id(realm)
|
||||
|
||||
realm.save(update_fields=["_max_invites", "message_visibility_limit", "upload_quota_gb"])
|
||||
|
||||
event = {
|
||||
"type": "realm",
|
||||
"op": "update",
|
||||
"property": "plan_type",
|
||||
"value": plan_type,
|
||||
"extra_data": {"upload_quota": realm.upload_quota_bytes()},
|
||||
}
|
||||
transaction.on_commit(lambda: send_event(realm, event, active_user_ids(realm.id)))
|
||||
|
||||
|
||||
def do_send_realm_reactivation_email(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||
url = create_confirmation_link(realm, Confirmation.REALM_REACTIVATION)
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
acting_user=acting_user,
|
||||
event_type=RealmAuditLog.REALM_REACTIVATION_EMAIL_SENT,
|
||||
event_time=timezone_now(),
|
||||
)
|
||||
context = {"confirmation_url": url, "realm_uri": realm.uri, "realm_name": realm.name}
|
||||
language = realm.default_language
|
||||
send_email_to_admins(
|
||||
"zerver/emails/realm_reactivation",
|
||||
realm,
|
||||
from_address=FromAddress.tokenized_no_reply_address(),
|
||||
from_name=FromAddress.security_email_from_name(language=language),
|
||||
language=language,
|
||||
context=context,
|
||||
)
|
|
@ -1,6 +1,6 @@
|
|||
import datetime
|
||||
import logging
|
||||
from typing import Any, Dict, List, Optional, Sequence
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import orjson
|
||||
from django.conf import settings
|
||||
|
@ -8,32 +8,25 @@ from django.db import transaction
|
|||
from django.utils.timezone import now as timezone_now
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from confirmation.models import Confirmation, create_confirmation_link, generate_key
|
||||
from zerver.actions.custom_profile_fields import do_remove_realm_custom_profile_fields
|
||||
from zerver.actions.message_edit import do_delete_messages_by_sender
|
||||
from zerver.actions.message_send import internal_send_stream_message
|
||||
from zerver.actions.user_groups import update_users_in_full_members_system_group
|
||||
from zerver.actions.user_settings import do_delete_avatar_image, send_user_email_update_event
|
||||
from zerver.actions.realm_settings import (
|
||||
do_add_deactivated_redirect,
|
||||
do_change_realm_plan_type,
|
||||
do_deactivate_realm,
|
||||
do_set_realm_property,
|
||||
)
|
||||
from zerver.lib.bulk_create import create_users
|
||||
from zerver.lib.cache import flush_user_profile
|
||||
from zerver.lib.create_user import get_display_email_address
|
||||
from zerver.lib.message import update_first_visible_message_id
|
||||
from zerver.lib.send_email import FromAddress, send_email_to_admins
|
||||
from zerver.lib.server_initialization import create_internal_realm, server_initialized
|
||||
from zerver.lib.sessions import delete_user_sessions
|
||||
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_counts import realm_user_count_by_role
|
||||
from zerver.lib.user_groups import create_system_user_groups_for_realm
|
||||
from zerver.models import (
|
||||
Attachment,
|
||||
DefaultStream,
|
||||
Message,
|
||||
Realm,
|
||||
RealmAuditLog,
|
||||
RealmDomain,
|
||||
RealmUserDefault,
|
||||
ScheduledEmail,
|
||||
Stream,
|
||||
UserMessage,
|
||||
UserProfile,
|
||||
|
@ -44,328 +37,6 @@ from zerver.models import (
|
|||
)
|
||||
from zerver.tornado.django_api import send_event
|
||||
|
||||
if settings.BILLING_ENABLED:
|
||||
from corporate.lib.stripe import downgrade_now_without_creating_additional_invoices
|
||||
|
||||
|
||||
def active_humans_in_realm(realm: Realm) -> Sequence[UserProfile]:
|
||||
return UserProfile.objects.filter(realm=realm, is_active=True, is_bot=False)
|
||||
|
||||
|
||||
@transaction.atomic(savepoint=False)
|
||||
def do_set_realm_property(
|
||||
realm: Realm, name: str, value: Any, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
"""Takes in a realm object, the name of an attribute to update, the
|
||||
value to update and and the user who initiated the update.
|
||||
"""
|
||||
property_type = Realm.property_types[name]
|
||||
assert isinstance(
|
||||
value, property_type
|
||||
), f"Cannot update {name}: {value} is not an instance of {property_type}"
|
||||
|
||||
old_value = getattr(realm, name)
|
||||
setattr(realm, name, value)
|
||||
realm.save(update_fields=[name])
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update",
|
||||
property=name,
|
||||
value=value,
|
||||
)
|
||||
transaction.on_commit(lambda: send_event(realm, event, active_user_ids(realm.id)))
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: value,
|
||||
"property": name,
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
if name == "email_address_visibility":
|
||||
if Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE not in [old_value, value]:
|
||||
# We use real email addresses on UserProfile.email only if
|
||||
# EMAIL_ADDRESS_VISIBILITY_EVERYONE is configured, so
|
||||
# changes between values that will not require changing
|
||||
# that field, so we can save work and return here.
|
||||
return
|
||||
|
||||
user_profiles = UserProfile.objects.filter(realm=realm, is_bot=False)
|
||||
for user_profile in user_profiles:
|
||||
user_profile.email = get_display_email_address(user_profile)
|
||||
UserProfile.objects.bulk_update(user_profiles, ["email"])
|
||||
|
||||
for user_profile in user_profiles:
|
||||
transaction.on_commit(
|
||||
lambda: flush_user_profile(sender=UserProfile, instance=user_profile)
|
||||
)
|
||||
# TODO: Design a bulk event for this or force-reload all clients
|
||||
send_user_email_update_event(user_profile)
|
||||
|
||||
if name == "waiting_period_threshold":
|
||||
update_users_in_full_members_system_group(realm)
|
||||
|
||||
|
||||
def do_set_realm_authentication_methods(
|
||||
realm: Realm, authentication_methods: Dict[str, bool], *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.authentication_methods_dict()
|
||||
with transaction.atomic():
|
||||
for key, value in list(authentication_methods.items()):
|
||||
index = getattr(realm.authentication_methods, key).number
|
||||
realm.authentication_methods.set_bit(index, int(value))
|
||||
realm.save(update_fields=["authentication_methods"])
|
||||
updated_value = realm.authentication_methods_dict()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: updated_value,
|
||||
"property": "authentication_methods",
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update_dict",
|
||||
property="default",
|
||||
data=dict(authentication_methods=updated_value),
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_message_editing(
|
||||
realm: Realm,
|
||||
allow_message_editing: bool,
|
||||
message_content_edit_limit_seconds: int,
|
||||
edit_topic_policy: int,
|
||||
*,
|
||||
acting_user: Optional[UserProfile],
|
||||
) -> None:
|
||||
old_values = dict(
|
||||
allow_message_editing=realm.allow_message_editing,
|
||||
message_content_edit_limit_seconds=realm.message_content_edit_limit_seconds,
|
||||
edit_topic_policy=realm.edit_topic_policy,
|
||||
)
|
||||
|
||||
realm.allow_message_editing = allow_message_editing
|
||||
realm.message_content_edit_limit_seconds = message_content_edit_limit_seconds
|
||||
realm.edit_topic_policy = edit_topic_policy
|
||||
|
||||
event_time = timezone_now()
|
||||
updated_properties = dict(
|
||||
allow_message_editing=allow_message_editing,
|
||||
message_content_edit_limit_seconds=message_content_edit_limit_seconds,
|
||||
edit_topic_policy=edit_topic_policy,
|
||||
)
|
||||
|
||||
with transaction.atomic():
|
||||
for updated_property, updated_value in updated_properties.items():
|
||||
if updated_value == old_values[updated_property]:
|
||||
continue
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_values[updated_property],
|
||||
RealmAuditLog.NEW_VALUE: updated_value,
|
||||
"property": updated_property,
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
realm.save(update_fields=list(updated_properties.keys()))
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update_dict",
|
||||
property="default",
|
||||
data=updated_properties,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_notifications_stream(
|
||||
realm: Realm, stream: Optional[Stream], stream_id: int, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.notifications_stream_id
|
||||
realm.notifications_stream = stream
|
||||
with transaction.atomic():
|
||||
realm.save(update_fields=["notifications_stream"])
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: stream_id,
|
||||
"property": "notifications_stream",
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update",
|
||||
property="notifications_stream_id",
|
||||
value=stream_id,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_signup_notifications_stream(
|
||||
realm: Realm, stream: Optional[Stream], stream_id: int, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.signup_notifications_stream_id
|
||||
realm.signup_notifications_stream = stream
|
||||
with transaction.atomic():
|
||||
realm.save(update_fields=["signup_notifications_stream"])
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_PROPERTY_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: stream_id,
|
||||
"property": "signup_notifications_stream",
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update",
|
||||
property="signup_notifications_stream_id",
|
||||
value=stream_id,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_set_realm_user_default_setting(
|
||||
realm_user_default: RealmUserDefault,
|
||||
name: str,
|
||||
value: Any,
|
||||
*,
|
||||
acting_user: Optional[UserProfile],
|
||||
) -> None:
|
||||
old_value = getattr(realm_user_default, name)
|
||||
realm = realm_user_default.realm
|
||||
event_time = timezone_now()
|
||||
|
||||
with transaction.atomic(savepoint=False):
|
||||
setattr(realm_user_default, name, value)
|
||||
realm_user_default.save(update_fields=[name])
|
||||
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_DEFAULT_USER_SETTINGS_CHANGED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.OLD_VALUE: old_value,
|
||||
RealmAuditLog.NEW_VALUE: value,
|
||||
"property": name,
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
event = dict(
|
||||
type="realm_user_settings_defaults",
|
||||
op="update",
|
||||
property=name,
|
||||
value=value,
|
||||
)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_deactivate_realm(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||
"""
|
||||
Deactivate this realm. Do NOT deactivate the users -- we need to be able to
|
||||
tell the difference between users that were intentionally deactivated,
|
||||
e.g. by a realm admin, and users who can't currently use Zulip because their
|
||||
realm has been deactivated.
|
||||
"""
|
||||
if realm.deactivated:
|
||||
return
|
||||
|
||||
realm.deactivated = True
|
||||
realm.save(update_fields=["deactivated"])
|
||||
|
||||
if settings.BILLING_ENABLED:
|
||||
downgrade_now_without_creating_additional_invoices(realm)
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_DEACTIVATED,
|
||||
event_time=event_time,
|
||||
acting_user=acting_user,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.ROLE_COUNT: realm_user_count_by_role(realm),
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
ScheduledEmail.objects.filter(realm=realm).delete()
|
||||
for user in active_humans_in_realm(realm):
|
||||
# Don't deactivate the users, but do delete their sessions so they get
|
||||
# bumped to the login screen, where they'll get a realm deactivation
|
||||
# notice when they try to log in.
|
||||
delete_user_sessions(user)
|
||||
|
||||
# This event will only ever be received by clients with an active
|
||||
# longpoll connection, because by this point clients will be
|
||||
# unable to authenticate again to their event queue (triggering an
|
||||
# immediate reload into the page explaining the realm was
|
||||
# deactivated). So the purpose of sending this is to flush all
|
||||
# active longpoll connections for the realm.
|
||||
event = dict(type="realm", op="deactivated", realm_id=realm.id)
|
||||
send_event(realm, event, active_user_ids(realm.id))
|
||||
|
||||
|
||||
def do_reactivate_realm(realm: Realm) -> None:
|
||||
realm.deactivated = False
|
||||
with transaction.atomic():
|
||||
realm.save(update_fields=["deactivated"])
|
||||
|
||||
event_time = timezone_now()
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_type=RealmAuditLog.REALM_REACTIVATED,
|
||||
event_time=event_time,
|
||||
extra_data=orjson.dumps(
|
||||
{
|
||||
RealmAuditLog.ROLE_COUNT: realm_user_count_by_role(realm),
|
||||
}
|
||||
).decode(),
|
||||
)
|
||||
|
||||
|
||||
def do_change_realm_subdomain(
|
||||
realm: Realm, new_subdomain: str, *, acting_user: Optional[UserProfile]
|
||||
|
@ -412,107 +83,6 @@ def do_change_realm_subdomain(
|
|||
do_add_deactivated_redirect(placeholder_realm, realm.uri)
|
||||
|
||||
|
||||
def do_add_deactivated_redirect(realm: Realm, redirect_url: str) -> None:
|
||||
realm.deactivated_redirect = redirect_url
|
||||
realm.save(update_fields=["deactivated_redirect"])
|
||||
|
||||
|
||||
def do_scrub_realm(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||
if settings.BILLING_ENABLED:
|
||||
downgrade_now_without_creating_additional_invoices(realm)
|
||||
|
||||
users = UserProfile.objects.filter(realm=realm)
|
||||
for user in users:
|
||||
do_delete_messages_by_sender(user)
|
||||
do_delete_avatar_image(user, acting_user=acting_user)
|
||||
user.full_name = f"Scrubbed {generate_key()[:15]}"
|
||||
scrubbed_email = f"scrubbed-{generate_key()[:15]}@{realm.host}"
|
||||
user.email = scrubbed_email
|
||||
user.delivery_email = scrubbed_email
|
||||
user.save(update_fields=["full_name", "email", "delivery_email"])
|
||||
|
||||
do_remove_realm_custom_profile_fields(realm)
|
||||
Attachment.objects.filter(realm=realm).delete()
|
||||
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
event_type=RealmAuditLog.REALM_SCRUBBED,
|
||||
)
|
||||
|
||||
|
||||
@transaction.atomic(durable=True)
|
||||
def do_change_realm_org_type(
|
||||
realm: Realm,
|
||||
org_type: int,
|
||||
acting_user: Optional[UserProfile],
|
||||
) -> None:
|
||||
old_value = realm.org_type
|
||||
realm.org_type = org_type
|
||||
realm.save(update_fields=["org_type"])
|
||||
|
||||
RealmAuditLog.objects.create(
|
||||
event_type=RealmAuditLog.REALM_ORG_TYPE_CHANGED,
|
||||
realm=realm,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
extra_data={"old_value": old_value, "new_value": org_type},
|
||||
)
|
||||
|
||||
|
||||
@transaction.atomic(savepoint=False)
|
||||
def do_change_realm_plan_type(
|
||||
realm: Realm, plan_type: int, *, acting_user: Optional[UserProfile]
|
||||
) -> None:
|
||||
old_value = realm.plan_type
|
||||
realm.plan_type = plan_type
|
||||
realm.save(update_fields=["plan_type"])
|
||||
RealmAuditLog.objects.create(
|
||||
event_type=RealmAuditLog.REALM_PLAN_TYPE_CHANGED,
|
||||
realm=realm,
|
||||
event_time=timezone_now(),
|
||||
acting_user=acting_user,
|
||||
extra_data={"old_value": old_value, "new_value": plan_type},
|
||||
)
|
||||
|
||||
if plan_type == Realm.PLAN_TYPE_PLUS:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_STANDARD
|
||||
elif plan_type == Realm.PLAN_TYPE_STANDARD:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_STANDARD
|
||||
elif plan_type == Realm.PLAN_TYPE_SELF_HOSTED:
|
||||
realm.max_invites = None # type: ignore[assignment] # Apparent mypy bug with Optional[int] setter.
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = None
|
||||
elif plan_type == Realm.PLAN_TYPE_STANDARD_FREE:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = None
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_STANDARD
|
||||
elif plan_type == Realm.PLAN_TYPE_LIMITED:
|
||||
realm.max_invites = settings.INVITES_DEFAULT_REALM_DAILY_MAX
|
||||
realm.message_visibility_limit = Realm.MESSAGE_VISIBILITY_LIMITED
|
||||
realm.upload_quota_gb = Realm.UPLOAD_QUOTA_LIMITED
|
||||
else:
|
||||
raise AssertionError("Invalid plan type")
|
||||
|
||||
update_first_visible_message_id(realm)
|
||||
|
||||
realm.save(update_fields=["_max_invites", "message_visibility_limit", "upload_quota_gb"])
|
||||
|
||||
event = {
|
||||
"type": "realm",
|
||||
"op": "update",
|
||||
"property": "plan_type",
|
||||
"value": plan_type,
|
||||
"extra_data": {"upload_quota": realm.upload_quota_bytes()},
|
||||
}
|
||||
transaction.on_commit(lambda: send_event(realm, event, active_user_ids(realm.id)))
|
||||
|
||||
|
||||
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
|
||||
|
@ -779,26 +349,6 @@ def do_remove_realm_domain(
|
|||
transaction.on_commit(lambda: send_event(realm, event, active_user_ids(realm.id)))
|
||||
|
||||
|
||||
def do_send_realm_reactivation_email(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||
url = create_confirmation_link(realm, Confirmation.REALM_REACTIVATION)
|
||||
RealmAuditLog.objects.create(
|
||||
realm=realm,
|
||||
acting_user=acting_user,
|
||||
event_type=RealmAuditLog.REALM_REACTIVATION_EMAIL_SENT,
|
||||
event_time=timezone_now(),
|
||||
)
|
||||
context = {"confirmation_url": url, "realm_uri": realm.uri, "realm_name": realm.name}
|
||||
language = realm.default_language
|
||||
send_email_to_admins(
|
||||
"zerver/emails/realm_reactivation",
|
||||
realm,
|
||||
from_address=FromAddress.tokenized_no_reply_address(),
|
||||
from_name=FromAddress.security_email_from_name(language=language),
|
||||
language=language,
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
||||
def get_topic_messages(user_profile: UserProfile, stream: Stream, topic_name: str) -> List[Message]:
|
||||
query = UserMessage.objects.filter(
|
||||
user_profile=user_profile,
|
||||
|
|
|
@ -16,8 +16,8 @@ from psycopg2.extras import execute_values
|
|||
from psycopg2.sql import SQL, Identifier
|
||||
|
||||
from analytics.models import RealmCount, StreamCount, UserCount
|
||||
from zerver.actions.realm_settings import do_change_realm_plan_type
|
||||
from zerver.actions.user_settings import do_change_avatar_fields
|
||||
from zerver.lib.actions import do_change_realm_plan_type
|
||||
from zerver.lib.avatar_hash import user_avatar_path_from_ids
|
||||
from zerver.lib.bulk_create import bulk_create_users, bulk_set_users_or_streams_recipient_fields
|
||||
from zerver.lib.export import DATE_FIELDS, Field, Path, Record, TableData, TableName
|
||||
|
|
|
@ -48,9 +48,9 @@ from two_factor.models import PhoneDevice
|
|||
|
||||
from corporate.models import Customer, CustomerPlan, LicenseLedger
|
||||
from zerver.actions.message_send import check_send_message, check_send_stream_message
|
||||
from zerver.actions.realm_settings import do_set_realm_property
|
||||
from zerver.actions.streams import bulk_add_subscriptions, bulk_remove_subscriptions
|
||||
from zerver.decorator import do_two_factor_login
|
||||
from zerver.lib.actions import do_set_realm_property
|
||||
from zerver.lib.cache import bounce_key_prefix_for_testing
|
||||
from zerver.lib.initial_password import initial_password
|
||||
from zerver.lib.notification_data import UserMessageNotificationsData
|
||||
|
|
|
@ -39,8 +39,8 @@ from moto import mock_s3
|
|||
from mypy_boto3_s3.service_resource import Bucket
|
||||
|
||||
import zerver.lib.upload
|
||||
from zerver.actions.realm_settings import do_set_realm_property
|
||||
from zerver.lib import cache
|
||||
from zerver.lib.actions import do_set_realm_property
|
||||
from zerver.lib.avatar import avatar_url
|
||||
from zerver.lib.cache import get_cache_backend
|
||||
from zerver.lib.db import Params, ParamsT, Query, TimeTrackingCursor
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from argparse import ArgumentParser
|
||||
from typing import Any
|
||||
|
||||
from zerver.lib.actions import do_add_deactivated_redirect, do_deactivate_realm
|
||||
from zerver.actions.realm_settings import do_add_deactivated_redirect, do_deactivate_realm
|
||||
from zerver.lib.management import ZulipBaseCommand
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ from typing import Any
|
|||
from django.conf import settings
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
from zerver.lib.actions import do_deactivate_realm
|
||||
from zerver.actions.realm_settings import do_deactivate_realm
|
||||
from zerver.lib.export import export_realm_wrapper
|
||||
from zerver.lib.management import ZulipBaseCommand
|
||||
from zerver.models import Message, Reaction, UserProfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from argparse import ArgumentParser
|
||||
from typing import Any
|
||||
|
||||
from zerver.lib.actions import do_reactivate_realm
|
||||
from zerver.actions.realm_settings import do_reactivate_realm
|
||||
from zerver.lib.management import ZulipBaseCommand
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from argparse import ArgumentParser
|
||||
from typing import Any
|
||||
|
||||
from zerver.lib.actions import do_scrub_realm
|
||||
from zerver.actions.realm_settings import do_scrub_realm
|
||||
from zerver.lib.management import ZulipBaseCommand
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any
|
|||
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
from zerver.lib.actions import do_send_realm_reactivation_email
|
||||
from zerver.actions.realm_settings import do_send_realm_reactivation_email
|
||||
from zerver.lib.management import ZulipBaseCommand
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,14 @@ from zerver.actions.create_user import (
|
|||
)
|
||||
from zerver.actions.realm_icon import do_change_icon_source
|
||||
from zerver.actions.realm_playgrounds import do_add_realm_playground, do_remove_realm_playground
|
||||
from zerver.actions.realm_settings import (
|
||||
do_deactivate_realm,
|
||||
do_reactivate_realm,
|
||||
do_set_realm_authentication_methods,
|
||||
do_set_realm_message_editing,
|
||||
do_set_realm_notifications_stream,
|
||||
do_set_realm_signup_notifications_stream,
|
||||
)
|
||||
from zerver.actions.streams import (
|
||||
bulk_add_subscriptions,
|
||||
bulk_remove_subscriptions,
|
||||
|
@ -35,17 +43,7 @@ from zerver.actions.user_settings import (
|
|||
do_regenerate_api_key,
|
||||
)
|
||||
from zerver.actions.users import do_change_user_role, do_deactivate_user
|
||||
from zerver.lib.actions import (
|
||||
do_add_realm_domain,
|
||||
do_change_realm_domain,
|
||||
do_deactivate_realm,
|
||||
do_reactivate_realm,
|
||||
do_remove_realm_domain,
|
||||
do_set_realm_authentication_methods,
|
||||
do_set_realm_message_editing,
|
||||
do_set_realm_notifications_stream,
|
||||
do_set_realm_signup_notifications_stream,
|
||||
)
|
||||
from zerver.lib.actions import do_add_realm_domain, do_change_realm_domain, do_remove_realm_domain
|
||||
from zerver.lib.message import get_last_message_id
|
||||
from zerver.lib.stream_traffic import get_streams_traffic
|
||||
from zerver.lib.streams import create_stream_if_needed
|
||||
|
|
|
@ -42,14 +42,14 @@ from social_django.strategy import DjangoStrategy
|
|||
from confirmation.models import Confirmation, create_confirmation_link
|
||||
from zerver.actions.create_user import do_create_user, do_reactivate_user
|
||||
from zerver.actions.invites import do_invite_users
|
||||
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.actions.realm_settings import (
|
||||
do_deactivate_realm,
|
||||
do_reactivate_realm,
|
||||
do_set_realm_property,
|
||||
)
|
||||
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
|
||||
|
|
|
@ -8,9 +8,9 @@ from django.core import mail
|
|||
from django.test import override_settings
|
||||
from zulip_bots.custom_exceptions import ConfigValidationError
|
||||
|
||||
from zerver.actions.realm_settings import do_set_realm_property
|
||||
from zerver.actions.streams import do_change_stream_permission
|
||||
from zerver.actions.users import do_change_can_create_users, do_deactivate_user
|
||||
from zerver.lib.actions import do_set_realm_property
|
||||
from zerver.lib.bot_config import ConfigError, get_bot_config
|
||||
from zerver.lib.bot_lib import get_bot_handler
|
||||
from zerver.lib.integrations import EMBEDDED_BOTS, WebhookIntegration
|
||||
|
|
|
@ -15,6 +15,11 @@ from django.http import HttpRequest, HttpResponse
|
|||
from django.utils.timezone import now as timezone_now
|
||||
|
||||
from zerver.actions.create_user import do_reactivate_user
|
||||
from zerver.actions.realm_settings import (
|
||||
do_deactivate_realm,
|
||||
do_reactivate_realm,
|
||||
do_set_realm_property,
|
||||
)
|
||||
from zerver.actions.users import change_user_is_active, do_deactivate_user
|
||||
from zerver.decorator import (
|
||||
authenticate_notify,
|
||||
|
@ -30,12 +35,7 @@ from zerver.decorator import (
|
|||
zulip_login_required,
|
||||
)
|
||||
from zerver.forms import OurAuthenticationForm
|
||||
from zerver.lib.actions import (
|
||||
do_create_realm,
|
||||
do_deactivate_realm,
|
||||
do_reactivate_realm,
|
||||
do_set_realm_property,
|
||||
)
|
||||
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,
|
||||
|
|
|
@ -11,9 +11,9 @@ from confirmation.models import (
|
|||
create_confirmation_link,
|
||||
generate_key,
|
||||
)
|
||||
from zerver.actions.realm_settings import do_deactivate_realm, do_set_realm_property
|
||||
from zerver.actions.user_settings import do_start_email_change_process
|
||||
from zerver.actions.users import do_deactivate_user
|
||||
from zerver.lib.actions import do_deactivate_realm, do_set_realm_property
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.models import (
|
||||
EmailChangeStatus,
|
||||
|
|
|
@ -11,9 +11,9 @@ import orjson
|
|||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
|
||||
from zerver.actions.realm_settings import do_deactivate_realm
|
||||
from zerver.actions.streams import do_change_stream_post_policy
|
||||
from zerver.actions.users import do_deactivate_user
|
||||
from zerver.lib.actions import do_deactivate_realm
|
||||
from zerver.lib.email_mirror import (
|
||||
create_missed_message_address,
|
||||
filter_footer,
|
||||
|
|
|
@ -10,8 +10,8 @@ from django.utils.timezone import now as timezone_now
|
|||
from version import API_FEATURE_LEVEL, ZULIP_MERGE_BASE, ZULIP_VERSION
|
||||
from zerver.actions.message_send import check_send_message
|
||||
from zerver.actions.presence import do_update_user_presence
|
||||
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_set_realm_property
|
||||
from zerver.lib.event_schema import check_restart_event
|
||||
from zerver.lib.events import fetch_initial_state_data
|
||||
from zerver.lib.exceptions import AccessDeniedError
|
||||
|
|
|
@ -63,6 +63,16 @@ from zerver.actions.realm_linkifiers import (
|
|||
)
|
||||
from zerver.actions.realm_logo import do_change_logo_source
|
||||
from zerver.actions.realm_playgrounds import do_add_realm_playground, do_remove_realm_playground
|
||||
from zerver.actions.realm_settings import (
|
||||
do_change_realm_plan_type,
|
||||
do_deactivate_realm,
|
||||
do_set_realm_authentication_methods,
|
||||
do_set_realm_message_editing,
|
||||
do_set_realm_notifications_stream,
|
||||
do_set_realm_property,
|
||||
do_set_realm_signup_notifications_stream,
|
||||
do_set_realm_user_default_setting,
|
||||
)
|
||||
from zerver.actions.streams import (
|
||||
bulk_add_subscriptions,
|
||||
bulk_remove_subscriptions,
|
||||
|
@ -99,19 +109,7 @@ from zerver.actions.users import (
|
|||
do_update_outgoing_webhook_service,
|
||||
)
|
||||
from zerver.actions.video_calls import do_set_zoom_token
|
||||
from zerver.lib.actions import (
|
||||
do_add_realm_domain,
|
||||
do_change_realm_domain,
|
||||
do_change_realm_plan_type,
|
||||
do_deactivate_realm,
|
||||
do_remove_realm_domain,
|
||||
do_set_realm_authentication_methods,
|
||||
do_set_realm_message_editing,
|
||||
do_set_realm_notifications_stream,
|
||||
do_set_realm_property,
|
||||
do_set_realm_signup_notifications_stream,
|
||||
do_set_realm_user_default_setting,
|
||||
)
|
||||
from zerver.lib.actions import do_add_realm_domain, do_change_realm_domain, do_remove_realm_domain
|
||||
from zerver.lib.drafts import do_create_drafts, do_delete_draft, do_edit_draft
|
||||
from zerver.lib.event_schema import (
|
||||
check_alert_words,
|
||||
|
|
|
@ -14,8 +14,8 @@ from django.utils.timezone import now as timezone_now
|
|||
|
||||
from corporate.models import Customer, CustomerPlan
|
||||
from zerver.actions.create_user import do_create_user
|
||||
from zerver.actions.realm_settings import do_change_realm_plan_type
|
||||
from zerver.actions.users import change_user_is_active
|
||||
from zerver.lib.actions import do_change_realm_plan_type
|
||||
from zerver.lib.compatibility import LAST_SERVER_UPGRADE_TIME, is_outdated_server
|
||||
from zerver.lib.home import (
|
||||
get_billing_info,
|
||||
|
|
|
@ -22,11 +22,11 @@ from zerver.actions.reactions import check_add_reaction, do_add_reaction
|
|||
from zerver.actions.realm_emoji import check_add_realm_emoji
|
||||
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
|
||||
from zerver.actions.user_activity import do_update_user_activity, do_update_user_activity_interval
|
||||
from zerver.actions.user_topics import do_mute_topic
|
||||
from zerver.actions.users import do_deactivate_user
|
||||
from zerver.lib import upload
|
||||
from zerver.lib.actions import do_change_realm_plan_type
|
||||
from zerver.lib.avatar_hash import user_avatar_path
|
||||
from zerver.lib.bot_config import set_bot_config
|
||||
from zerver.lib.bot_lib import StateHandler
|
||||
|
|
|
@ -12,9 +12,10 @@ from markdown import Markdown
|
|||
|
||||
from zerver.actions.alert_words import do_add_alert_words
|
||||
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, do_set_realm_property
|
||||
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
|
||||
|
|
|
@ -15,9 +15,10 @@ from zerver.actions.message_edit import (
|
|||
get_user_info_for_message_updates,
|
||||
)
|
||||
from zerver.actions.reactions import do_add_reaction
|
||||
from zerver.actions.realm_settings import do_change_realm_plan_type, do_set_realm_property
|
||||
from zerver.actions.streams import do_change_stream_post_policy, do_deactivate_stream
|
||||
from zerver.actions.users import do_change_user_role
|
||||
from zerver.lib.actions import do_change_realm_plan_type, do_set_realm_property, get_topic_messages
|
||||
from zerver.lib.actions import get_topic_messages
|
||||
from zerver.lib.message import MessageDict, has_message_access, messages_for_ids
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.lib.test_helpers import cache_tries_captured, queries_captured
|
||||
|
|
|
@ -14,9 +14,9 @@ from sqlalchemy.types import Integer
|
|||
from analytics.lib.counts import COUNT_STATS
|
||||
from analytics.models import RealmCount
|
||||
from zerver.actions.message_edit import do_update_message
|
||||
from zerver.actions.realm_settings import do_set_realm_property
|
||||
from zerver.actions.uploads import do_claim_attachments
|
||||
from zerver.actions.users import do_deactivate_user
|
||||
from zerver.lib.actions import do_set_realm_property
|
||||
from zerver.lib.avatar import avatar_url
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
from zerver.lib.mention import MentionBackend, MentionData
|
||||
|
|
|
@ -26,9 +26,10 @@ from zerver.actions.message_send import (
|
|||
internal_send_stream_message_by_name,
|
||||
send_rate_limited_pm_notification_to_bot_owner,
|
||||
)
|
||||
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_add_realm_domain, do_create_realm, do_set_realm_property
|
||||
from zerver.lib.actions import do_add_realm_domain, 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
|
||||
|
|
|
@ -9,19 +9,18 @@ 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.streams import do_deactivate_stream
|
||||
from zerver.lib.actions import (
|
||||
from zerver.actions.realm_settings import (
|
||||
do_add_deactivated_redirect,
|
||||
do_change_realm_org_type,
|
||||
do_change_realm_plan_type,
|
||||
do_change_realm_subdomain,
|
||||
do_create_realm,
|
||||
do_deactivate_realm,
|
||||
do_scrub_realm,
|
||||
do_send_realm_reactivation_email,
|
||||
do_set_realm_property,
|
||||
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
|
||||
|
|
|
@ -2,13 +2,9 @@ import orjson
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.db.utils import IntegrityError
|
||||
|
||||
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_change_realm_domain,
|
||||
do_create_realm,
|
||||
do_remove_realm_domain,
|
||||
do_set_realm_property,
|
||||
)
|
||||
from zerver.lib.actions import do_change_realm_domain, do_create_realm, do_remove_realm_domain
|
||||
from zerver.lib.domains import validate_domain
|
||||
from zerver.lib.email_validation import email_allowed_for_realm
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
|
|
|
@ -2,8 +2,9 @@ from unittest import mock
|
|||
|
||||
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, do_set_realm_property
|
||||
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
|
||||
|
|
|
@ -7,8 +7,9 @@ from django.utils.timezone import now as timezone_now
|
|||
|
||||
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, do_set_realm_property
|
||||
from zerver.lib.actions import do_create_realm
|
||||
from zerver.lib.retention import (
|
||||
archive_messages,
|
||||
clean_archived_data,
|
||||
|
|
|
@ -36,18 +36,17 @@ from zerver.actions.invites import (
|
|||
do_get_invites_controlled_by_user,
|
||||
do_invite_users,
|
||||
)
|
||||
from zerver.actions.realm_settings import (
|
||||
do_deactivate_realm,
|
||||
do_set_realm_property,
|
||||
do_set_realm_user_default_setting,
|
||||
)
|
||||
from zerver.actions.user_settings import do_change_full_name
|
||||
from zerver.actions.users import change_user_is_active, do_change_user_role, do_deactivate_user
|
||||
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,
|
||||
do_deactivate_realm,
|
||||
do_set_realm_property,
|
||||
do_set_realm_user_default_setting,
|
||||
)
|
||||
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 (
|
||||
|
|
|
@ -23,6 +23,7 @@ from zerver.actions.default_streams import (
|
|||
get_default_streams_for_realm,
|
||||
lookup_default_stream_groups,
|
||||
)
|
||||
from zerver.actions.realm_settings import do_change_realm_plan_type, do_set_realm_property
|
||||
from zerver.actions.streams import (
|
||||
bulk_add_subscriptions,
|
||||
bulk_remove_subscriptions,
|
||||
|
@ -31,12 +32,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_change_realm_plan_type,
|
||||
do_create_realm,
|
||||
do_set_realm_property,
|
||||
get_topic_messages,
|
||||
)
|
||||
from zerver.lib.actions import do_create_realm, 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
|
||||
|
|
|
@ -22,9 +22,10 @@ import zerver.lib.upload
|
|||
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_change_realm_plan_type, do_create_realm, do_set_realm_property
|
||||
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
|
||||
|
|
|
@ -5,8 +5,8 @@ from unittest import mock
|
|||
import orjson
|
||||
from django.utils.timezone import now as timezone_now
|
||||
|
||||
from zerver.actions.realm_settings import do_set_realm_property
|
||||
from zerver.actions.user_groups import promote_new_full_members
|
||||
from zerver.lib.actions import do_set_realm_property
|
||||
from zerver.lib.streams import ensure_stream
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.lib.test_helpers import most_recent_usermessage
|
||||
|
|
|
@ -16,6 +16,7 @@ from zerver.actions.create_user import do_create_user, do_reactivate_user
|
|||
from zerver.actions.invites import do_create_multiuse_invite_link, do_invite_users
|
||||
from zerver.actions.message_send import get_recipient_info
|
||||
from zerver.actions.muted_users import do_mute_user
|
||||
from zerver.actions.realm_settings import do_set_realm_property
|
||||
from zerver.actions.users import (
|
||||
change_user_is_active,
|
||||
do_change_can_create_users,
|
||||
|
@ -23,7 +24,6 @@ from zerver.actions.users import (
|
|||
do_deactivate_user,
|
||||
do_delete_user,
|
||||
)
|
||||
from zerver.lib.actions import do_set_realm_property
|
||||
from zerver.lib.avatar import avatar_url, get_gravatar_url
|
||||
from zerver.lib.bulk_create import create_users
|
||||
from zerver.lib.create_user import copy_default_settings
|
||||
|
|
|
@ -9,9 +9,9 @@ from django.shortcuts import redirect, render
|
|||
from django.views.decorators.http import require_safe
|
||||
|
||||
from confirmation.models import Confirmation, confirmation_url
|
||||
from zerver.actions.realm_settings import do_send_realm_reactivation_email
|
||||
from zerver.actions.user_settings import do_change_user_delivery_email
|
||||
from zerver.actions.users import change_user_is_active
|
||||
from zerver.lib.actions import do_send_realm_reactivation_email
|
||||
from zerver.lib.email_notifications import enqueue_welcome_emails
|
||||
from zerver.lib.response import json_success
|
||||
from zerver.models import Realm, get_realm, get_realm_stream, get_user_by_delivery_email
|
||||
|
|
|
@ -7,10 +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.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.actions.realm_settings import (
|
||||
do_deactivate_realm,
|
||||
do_reactivate_realm,
|
||||
do_set_realm_authentication_methods,
|
||||
|
@ -20,6 +17,9 @@ from zerver.lib.actions import (
|
|||
do_set_realm_signup_notifications_stream,
|
||||
do_set_realm_user_default_setting,
|
||||
)
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue