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.lib.stripe import add_months, update_sponsorship_status
|
||||||
from corporate.models import Customer, CustomerPlan, LicenseLedger, get_customer_by_realm
|
from corporate.models import Customer, CustomerPlan, LicenseLedger, get_customer_by_realm
|
||||||
from zerver.actions.invites import do_create_multiuse_invite_link
|
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_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import reset_emails_in_zulip_realm
|
from zerver.lib.test_helpers import reset_emails_in_zulip_realm
|
||||||
from zerver.models import (
|
from zerver.models import (
|
||||||
|
|
|
@ -16,16 +16,16 @@ from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from confirmation.models import Confirmation, confirmation_url
|
from confirmation.models import Confirmation, confirmation_url
|
||||||
from confirmation.settings import STATUS_ACTIVE
|
from confirmation.settings import STATUS_ACTIVE
|
||||||
from zerver.decorator import require_server_admin
|
from zerver.actions.realm_settings import (
|
||||||
from zerver.forms import check_subdomain_available
|
|
||||||
from zerver.lib.actions import (
|
|
||||||
do_change_realm_org_type,
|
do_change_realm_org_type,
|
||||||
do_change_realm_plan_type,
|
do_change_realm_plan_type,
|
||||||
do_change_realm_subdomain,
|
|
||||||
do_deactivate_realm,
|
do_deactivate_realm,
|
||||||
do_scrub_realm,
|
do_scrub_realm,
|
||||||
do_send_realm_reactivation_email,
|
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.exceptions import JsonableError
|
||||||
from zerver.lib.realm_icon import realm_icon_url
|
from zerver.lib.realm_icon import realm_icon_url
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
|
|
|
@ -748,7 +748,7 @@ def process_initial_upgrade(
|
||||||
)
|
)
|
||||||
stripe.Invoice.finalize_invoice(stripe_invoice)
|
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)
|
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:
|
def approve_sponsorship(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||||
from zerver.actions.message_send import internal_send_private_message
|
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)
|
do_change_realm_plan_type(realm, Realm.PLAN_TYPE_STANDARD_FREE, acting_user=acting_user)
|
||||||
customer = get_customer_by_realm(realm)
|
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:
|
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
|
assert plan.customer.realm is not None
|
||||||
do_change_realm_plan_type(plan.customer.realm, Realm.PLAN_TYPE_LIMITED, acting_user=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_create_user,
|
||||||
do_reactivate_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.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.test_classes import ZulipTestCase
|
||||||
from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
|
from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
|
||||||
from zerver.lib.utils import assert_is_not_none
|
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/models.py`: Defines the database model.
|
||||||
- `zerver/views/realm.py`: The view function that implements the API endpoint
|
- `zerver/views/realm.py`: The view function that implements the API endpoint
|
||||||
for editing realm objects.
|
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
|
- `zerver/lib/events.py`: Ensures that the state Zulip sends to clients is always
|
||||||
consistent and correct.
|
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.
|
have to write much code for a new setting.
|
||||||
|
|
||||||
**Database interaction:** Add any necessary code for updating and
|
**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.
|
update the database and send an event announcing the change.
|
||||||
|
|
||||||
**Application state:** Modify the `fetch_initial_state_data` and
|
**Application state:** Modify the `fetch_initial_state_data` and
|
||||||
|
@ -290,10 +290,10 @@ gory details.
|
||||||
Anyway, getting back to implementation details...
|
Anyway, getting back to implementation details...
|
||||||
|
|
||||||
If you are working on a feature that is in the realm `property_types`
|
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:
|
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
|
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
|
have. This function updates the database and triggers an event to
|
||||||
notify clients about the change. It uses the field's type, specified
|
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.
|
active users in a realm.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# zerver/lib/actions.py
|
# zerver/actions/realm_settings.py
|
||||||
|
|
||||||
def do_set_realm_property(
|
def do_set_realm_property(
|
||||||
realm: Realm, name: str, value: Any, *, acting_user: Optional[UserProfile]
|
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:
|
field and send an event. For example:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# zerver/lib/actions.py
|
# zerver/actions/realm_settings.p
|
||||||
|
|
||||||
def do_set_realm_authentication_methods(
|
def do_set_realm_authentication_methods(
|
||||||
realm: Realm, authentication_methods: Dict[str, bool], *, acting_user: Optional[UserProfile]
|
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
|
# zerver/views/realm.py
|
||||||
|
|
||||||
# import do_set_realm_authentication_methods from actions.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_message_editing,
|
||||||
do_set_realm_authentication_methods,
|
do_set_realm_authentication_methods,
|
||||||
# ...
|
# ...
|
||||||
|
|
|
@ -32,8 +32,8 @@ with test_server_running(
|
||||||
# zerver imports should happen after `django.setup()` is run
|
# zerver imports should happen after `django.setup()` is run
|
||||||
# by the test_server_running decorator.
|
# by the test_server_running decorator.
|
||||||
from zerver.actions.create_user import do_create_user, do_reactivate_user
|
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.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.test_helpers import reset_emails_in_zulip_realm
|
||||||
from zerver.lib.users import get_api_key
|
from zerver.lib.users import get_api_key
|
||||||
from zerver.models import get_realm, get_user
|
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 datetime
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict, List, Optional, Sequence
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
from django.conf import settings
|
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.timezone import now as timezone_now
|
||||||
from django.utils.translation import gettext as _
|
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.message_send import internal_send_stream_message
|
||||||
from zerver.actions.user_groups import update_users_in_full_members_system_group
|
from zerver.actions.realm_settings import (
|
||||||
from zerver.actions.user_settings import do_delete_avatar_image, send_user_email_update_event
|
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.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.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.streams import ensure_stream, get_signups_stream
|
||||||
from zerver.lib.topic import filter_by_topic_name_via_message
|
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.lib.user_groups import create_system_user_groups_for_realm
|
||||||
from zerver.models import (
|
from zerver.models import (
|
||||||
Attachment,
|
|
||||||
DefaultStream,
|
DefaultStream,
|
||||||
Message,
|
Message,
|
||||||
Realm,
|
Realm,
|
||||||
RealmAuditLog,
|
RealmAuditLog,
|
||||||
RealmDomain,
|
RealmDomain,
|
||||||
RealmUserDefault,
|
RealmUserDefault,
|
||||||
ScheduledEmail,
|
|
||||||
Stream,
|
Stream,
|
||||||
UserMessage,
|
UserMessage,
|
||||||
UserProfile,
|
UserProfile,
|
||||||
|
@ -44,328 +37,6 @@ from zerver.models import (
|
||||||
)
|
)
|
||||||
from zerver.tornado.django_api import send_event
|
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(
|
def do_change_realm_subdomain(
|
||||||
realm: Realm, new_subdomain: str, *, acting_user: Optional[UserProfile]
|
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)
|
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:
|
def set_realm_permissions_based_on_org_type(realm: Realm) -> None:
|
||||||
"""This function implements overrides for the default configuration
|
"""This function implements overrides for the default configuration
|
||||||
for new organizations when the administrator selected specific
|
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)))
|
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]:
|
def get_topic_messages(user_profile: UserProfile, stream: Stream, topic_name: str) -> List[Message]:
|
||||||
query = UserMessage.objects.filter(
|
query = UserMessage.objects.filter(
|
||||||
user_profile=user_profile,
|
user_profile=user_profile,
|
||||||
|
|
|
@ -16,8 +16,8 @@ from psycopg2.extras import execute_values
|
||||||
from psycopg2.sql import SQL, Identifier
|
from psycopg2.sql import SQL, Identifier
|
||||||
|
|
||||||
from analytics.models import RealmCount, StreamCount, UserCount
|
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.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.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.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
|
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 corporate.models import Customer, CustomerPlan, LicenseLedger
|
||||||
from zerver.actions.message_send import check_send_message, check_send_stream_message
|
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.actions.streams import bulk_add_subscriptions, bulk_remove_subscriptions
|
||||||
from zerver.decorator import do_two_factor_login
|
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.cache import bounce_key_prefix_for_testing
|
||||||
from zerver.lib.initial_password import initial_password
|
from zerver.lib.initial_password import initial_password
|
||||||
from zerver.lib.notification_data import UserMessageNotificationsData
|
from zerver.lib.notification_data import UserMessageNotificationsData
|
||||||
|
|
|
@ -39,8 +39,8 @@ from moto import mock_s3
|
||||||
from mypy_boto3_s3.service_resource import Bucket
|
from mypy_boto3_s3.service_resource import Bucket
|
||||||
|
|
||||||
import zerver.lib.upload
|
import zerver.lib.upload
|
||||||
|
from zerver.actions.realm_settings import do_set_realm_property
|
||||||
from zerver.lib import cache
|
from zerver.lib import cache
|
||||||
from zerver.lib.actions import do_set_realm_property
|
|
||||||
from zerver.lib.avatar import avatar_url
|
from zerver.lib.avatar import avatar_url
|
||||||
from zerver.lib.cache import get_cache_backend
|
from zerver.lib.cache import get_cache_backend
|
||||||
from zerver.lib.db import Params, ParamsT, Query, TimeTrackingCursor
|
from zerver.lib.db import Params, ParamsT, Query, TimeTrackingCursor
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from typing import Any
|
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
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Any
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import CommandError
|
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.export import export_realm_wrapper
|
||||||
from zerver.lib.management import ZulipBaseCommand
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
from zerver.models import Message, Reaction, UserProfile
|
from zerver.models import Message, Reaction, UserProfile
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from typing import Any
|
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
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from typing import Any
|
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
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any
|
||||||
|
|
||||||
from django.core.management.base import CommandError
|
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
|
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_icon import do_change_icon_source
|
||||||
from zerver.actions.realm_playgrounds import do_add_realm_playground, do_remove_realm_playground
|
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 (
|
from zerver.actions.streams import (
|
||||||
bulk_add_subscriptions,
|
bulk_add_subscriptions,
|
||||||
bulk_remove_subscriptions,
|
bulk_remove_subscriptions,
|
||||||
|
@ -35,17 +43,7 @@ from zerver.actions.user_settings import (
|
||||||
do_regenerate_api_key,
|
do_regenerate_api_key,
|
||||||
)
|
)
|
||||||
from zerver.actions.users import do_change_user_role, do_deactivate_user
|
from zerver.actions.users import do_change_user_role, do_deactivate_user
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import do_add_realm_domain, do_change_realm_domain, do_remove_realm_domain
|
||||||
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.message import get_last_message_id
|
from zerver.lib.message import get_last_message_id
|
||||||
from zerver.lib.stream_traffic import get_streams_traffic
|
from zerver.lib.stream_traffic import get_streams_traffic
|
||||||
from zerver.lib.streams import create_stream_if_needed
|
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 confirmation.models import Confirmation, create_confirmation_link
|
||||||
from zerver.actions.create_user import do_create_user, do_reactivate_user
|
from zerver.actions.create_user import do_create_user, do_reactivate_user
|
||||||
from zerver.actions.invites import do_invite_users
|
from zerver.actions.invites import do_invite_users
|
||||||
from zerver.actions.user_settings import do_change_password
|
from zerver.actions.realm_settings import (
|
||||||
from zerver.actions.users import change_user_is_active, do_deactivate_user
|
|
||||||
from zerver.lib.actions import (
|
|
||||||
do_create_realm,
|
|
||||||
do_deactivate_realm,
|
do_deactivate_realm,
|
||||||
do_reactivate_realm,
|
do_reactivate_realm,
|
||||||
do_set_realm_property,
|
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 import avatar_url
|
||||||
from zerver.lib.avatar_hash import user_avatar_path
|
from zerver.lib.avatar_hash import user_avatar_path
|
||||||
from zerver.lib.dev_ldap_directory import generate_dev_ldap_dir
|
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 django.test import override_settings
|
||||||
from zulip_bots.custom_exceptions import ConfigValidationError
|
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.streams import do_change_stream_permission
|
||||||
from zerver.actions.users import do_change_can_create_users, do_deactivate_user
|
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_config import ConfigError, get_bot_config
|
||||||
from zerver.lib.bot_lib import get_bot_handler
|
from zerver.lib.bot_lib import get_bot_handler
|
||||||
from zerver.lib.integrations import EMBEDDED_BOTS, WebhookIntegration
|
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 django.utils.timezone import now as timezone_now
|
||||||
|
|
||||||
from zerver.actions.create_user import do_reactivate_user
|
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.actions.users import change_user_is_active, do_deactivate_user
|
||||||
from zerver.decorator import (
|
from zerver.decorator import (
|
||||||
authenticate_notify,
|
authenticate_notify,
|
||||||
|
@ -30,12 +35,7 @@ from zerver.decorator import (
|
||||||
zulip_login_required,
|
zulip_login_required,
|
||||||
)
|
)
|
||||||
from zerver.forms import OurAuthenticationForm
|
from zerver.forms import OurAuthenticationForm
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import do_create_realm
|
||||||
do_create_realm,
|
|
||||||
do_deactivate_realm,
|
|
||||||
do_reactivate_realm,
|
|
||||||
do_set_realm_property,
|
|
||||||
)
|
|
||||||
from zerver.lib.cache import dict_to_items_tuple, ignore_unhashable_lru_cache, items_tuple_to_dict
|
from zerver.lib.cache import dict_to_items_tuple, ignore_unhashable_lru_cache, items_tuple_to_dict
|
||||||
from zerver.lib.exceptions import (
|
from zerver.lib.exceptions import (
|
||||||
AccessDeniedError,
|
AccessDeniedError,
|
||||||
|
|
|
@ -11,9 +11,9 @@ from confirmation.models import (
|
||||||
create_confirmation_link,
|
create_confirmation_link,
|
||||||
generate_key,
|
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.user_settings import do_start_email_change_process
|
||||||
from zerver.actions.users import do_deactivate_user
|
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.lib.test_classes import ZulipTestCase
|
||||||
from zerver.models import (
|
from zerver.models import (
|
||||||
EmailChangeStatus,
|
EmailChangeStatus,
|
||||||
|
|
|
@ -11,9 +11,9 @@ import orjson
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.http import HttpResponse
|
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.streams import do_change_stream_post_policy
|
||||||
from zerver.actions.users import do_deactivate_user
|
from zerver.actions.users import do_deactivate_user
|
||||||
from zerver.lib.actions import do_deactivate_realm
|
|
||||||
from zerver.lib.email_mirror import (
|
from zerver.lib.email_mirror import (
|
||||||
create_missed_message_address,
|
create_missed_message_address,
|
||||||
filter_footer,
|
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 version import API_FEATURE_LEVEL, ZULIP_MERGE_BASE, ZULIP_VERSION
|
||||||
from zerver.actions.message_send import check_send_message
|
from zerver.actions.message_send import check_send_message
|
||||||
from zerver.actions.presence import do_update_user_presence
|
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.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.event_schema import check_restart_event
|
||||||
from zerver.lib.events import fetch_initial_state_data
|
from zerver.lib.events import fetch_initial_state_data
|
||||||
from zerver.lib.exceptions import AccessDeniedError
|
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_logo import do_change_logo_source
|
||||||
from zerver.actions.realm_playgrounds import do_add_realm_playground, do_remove_realm_playground
|
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 (
|
from zerver.actions.streams import (
|
||||||
bulk_add_subscriptions,
|
bulk_add_subscriptions,
|
||||||
bulk_remove_subscriptions,
|
bulk_remove_subscriptions,
|
||||||
|
@ -99,19 +109,7 @@ from zerver.actions.users import (
|
||||||
do_update_outgoing_webhook_service,
|
do_update_outgoing_webhook_service,
|
||||||
)
|
)
|
||||||
from zerver.actions.video_calls import do_set_zoom_token
|
from zerver.actions.video_calls import do_set_zoom_token
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import do_add_realm_domain, do_change_realm_domain, do_remove_realm_domain
|
||||||
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.drafts import do_create_drafts, do_delete_draft, do_edit_draft
|
from zerver.lib.drafts import do_create_drafts, do_delete_draft, do_edit_draft
|
||||||
from zerver.lib.event_schema import (
|
from zerver.lib.event_schema import (
|
||||||
check_alert_words,
|
check_alert_words,
|
||||||
|
|
|
@ -14,8 +14,8 @@ from django.utils.timezone import now as timezone_now
|
||||||
|
|
||||||
from corporate.models import Customer, CustomerPlan
|
from corporate.models import Customer, CustomerPlan
|
||||||
from zerver.actions.create_user import do_create_user
|
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.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.compatibility import LAST_SERVER_UPGRADE_TIME, is_outdated_server
|
||||||
from zerver.lib.home import (
|
from zerver.lib.home import (
|
||||||
get_billing_info,
|
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_emoji import check_add_realm_emoji
|
||||||
from zerver.actions.realm_icon import do_change_icon_source
|
from zerver.actions.realm_icon import do_change_icon_source
|
||||||
from zerver.actions.realm_logo import do_change_logo_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_activity import do_update_user_activity, do_update_user_activity_interval
|
||||||
from zerver.actions.user_topics import do_mute_topic
|
from zerver.actions.user_topics import do_mute_topic
|
||||||
from zerver.actions.users import do_deactivate_user
|
from zerver.actions.users import do_deactivate_user
|
||||||
from zerver.lib import upload
|
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.avatar_hash import user_avatar_path
|
||||||
from zerver.lib.bot_config import set_bot_config
|
from zerver.lib.bot_config import set_bot_config
|
||||||
from zerver.lib.bot_lib import StateHandler
|
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.alert_words import do_add_alert_words
|
||||||
from zerver.actions.realm_emoji import do_remove_realm_emoji
|
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.user_settings import do_change_user_setting
|
||||||
from zerver.actions.users import change_user_is_active
|
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.alert_words import get_alert_word_automaton
|
||||||
from zerver.lib.camo import get_camo_url
|
from zerver.lib.camo import get_camo_url
|
||||||
from zerver.lib.create_user import create_user
|
from zerver.lib.create_user import create_user
|
||||||
|
|
|
@ -15,9 +15,10 @@ from zerver.actions.message_edit import (
|
||||||
get_user_info_for_message_updates,
|
get_user_info_for_message_updates,
|
||||||
)
|
)
|
||||||
from zerver.actions.reactions import do_add_reaction
|
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.streams import do_change_stream_post_policy, do_deactivate_stream
|
||||||
from zerver.actions.users import do_change_user_role
|
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.message import MessageDict, has_message_access, messages_for_ids
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import cache_tries_captured, queries_captured
|
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.lib.counts import COUNT_STATS
|
||||||
from analytics.models import RealmCount
|
from analytics.models import RealmCount
|
||||||
from zerver.actions.message_edit import do_update_message
|
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.uploads import do_claim_attachments
|
||||||
from zerver.actions.users import do_deactivate_user
|
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.avatar import avatar_url
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.mention import MentionBackend, MentionData
|
from zerver.lib.mention import MentionBackend, MentionData
|
||||||
|
|
|
@ -26,9 +26,10 @@ from zerver.actions.message_send import (
|
||||||
internal_send_stream_message_by_name,
|
internal_send_stream_message_by_name,
|
||||||
send_rate_limited_pm_notification_to_bot_owner,
|
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.streams import do_change_stream_post_policy
|
||||||
from zerver.actions.users import do_change_can_forge_sender, do_deactivate_user
|
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.addressee import Addressee
|
||||||
from zerver.lib.cache import cache_delete, get_stream_cache_key
|
from zerver.lib.cache import cache_delete, get_stream_cache_key
|
||||||
from zerver.lib.exceptions import JsonableError
|
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 django.utils.timezone import now as timezone_now
|
||||||
|
|
||||||
from confirmation.models import Confirmation, create_confirmation_link
|
from confirmation.models import Confirmation, create_confirmation_link
|
||||||
from zerver.actions.streams import do_deactivate_stream
|
from zerver.actions.realm_settings import (
|
||||||
from zerver.lib.actions import (
|
|
||||||
do_add_deactivated_redirect,
|
do_add_deactivated_redirect,
|
||||||
do_change_realm_org_type,
|
do_change_realm_org_type,
|
||||||
do_change_realm_plan_type,
|
do_change_realm_plan_type,
|
||||||
do_change_realm_subdomain,
|
|
||||||
do_create_realm,
|
|
||||||
do_deactivate_realm,
|
do_deactivate_realm,
|
||||||
do_scrub_realm,
|
do_scrub_realm,
|
||||||
do_send_realm_reactivation_email,
|
do_send_realm_reactivation_email,
|
||||||
do_set_realm_property,
|
do_set_realm_property,
|
||||||
do_set_realm_user_default_setting,
|
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.realm_description import get_realm_rendered_description, get_realm_text_description
|
||||||
from zerver.lib.send_email import send_future_email
|
from zerver.lib.send_email import send_future_email
|
||||||
from zerver.lib.streams import create_stream_if_needed
|
from zerver.lib.streams import create_stream_if_needed
|
||||||
|
|
|
@ -2,13 +2,9 @@ import orjson
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db.utils import IntegrityError
|
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.actions.users import do_change_user_role
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import do_change_realm_domain, do_create_realm, do_remove_realm_domain
|
||||||
do_change_realm_domain,
|
|
||||||
do_create_realm,
|
|
||||||
do_remove_realm_domain,
|
|
||||||
do_set_realm_property,
|
|
||||||
)
|
|
||||||
from zerver.lib.domains import validate_domain
|
from zerver.lib.domains import validate_domain
|
||||||
from zerver.lib.email_validation import email_allowed_for_realm
|
from zerver.lib.email_validation import email_allowed_for_realm
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
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.create_user import do_create_user
|
||||||
from zerver.actions.realm_emoji import check_add_realm_emoji
|
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.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.exceptions import JsonableError
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import get_test_image_file
|
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_edit import do_delete_messages
|
||||||
from zerver.actions.message_send import internal_send_private_message
|
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.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 (
|
from zerver.lib.retention import (
|
||||||
archive_messages,
|
archive_messages,
|
||||||
clean_archived_data,
|
clean_archived_data,
|
||||||
|
|
|
@ -36,18 +36,17 @@ from zerver.actions.invites import (
|
||||||
do_get_invites_controlled_by_user,
|
do_get_invites_controlled_by_user,
|
||||||
do_invite_users,
|
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.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.actions.users import change_user_is_active, do_change_user_role, do_deactivate_user
|
||||||
from zerver.context_processors import common_context
|
from zerver.context_processors import common_context
|
||||||
from zerver.decorator import do_two_factor_login
|
from zerver.decorator import do_two_factor_login
|
||||||
from zerver.forms import HomepageForm, check_subdomain_available
|
from zerver.forms import HomepageForm, check_subdomain_available
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import do_change_realm_subdomain, do_create_realm
|
||||||
do_change_realm_subdomain,
|
|
||||||
do_create_realm,
|
|
||||||
do_deactivate_realm,
|
|
||||||
do_set_realm_property,
|
|
||||||
do_set_realm_user_default_setting,
|
|
||||||
)
|
|
||||||
from zerver.lib.email_notifications import enqueue_welcome_emails, followup_day2_email_delay
|
from zerver.lib.email_notifications import enqueue_welcome_emails, followup_day2_email_delay
|
||||||
from zerver.lib.initial_password import initial_password
|
from zerver.lib.initial_password import initial_password
|
||||||
from zerver.lib.mobile_auth_otp import (
|
from zerver.lib.mobile_auth_otp import (
|
||||||
|
|
|
@ -23,6 +23,7 @@ from zerver.actions.default_streams import (
|
||||||
get_default_streams_for_realm,
|
get_default_streams_for_realm,
|
||||||
lookup_default_stream_groups,
|
lookup_default_stream_groups,
|
||||||
)
|
)
|
||||||
|
from zerver.actions.realm_settings import do_change_realm_plan_type, do_set_realm_property
|
||||||
from zerver.actions.streams import (
|
from zerver.actions.streams import (
|
||||||
bulk_add_subscriptions,
|
bulk_add_subscriptions,
|
||||||
bulk_remove_subscriptions,
|
bulk_remove_subscriptions,
|
||||||
|
@ -31,12 +32,7 @@ from zerver.actions.streams import (
|
||||||
do_deactivate_stream,
|
do_deactivate_stream,
|
||||||
)
|
)
|
||||||
from zerver.actions.users import do_change_user_role, do_deactivate_user
|
from zerver.actions.users import do_change_user_role, do_deactivate_user
|
||||||
from zerver.lib.actions import (
|
from zerver.lib.actions import do_create_realm, get_topic_messages
|
||||||
do_change_realm_plan_type,
|
|
||||||
do_create_realm,
|
|
||||||
do_set_realm_property,
|
|
||||||
get_topic_messages,
|
|
||||||
)
|
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
from zerver.lib.message import UnreadStreamInfo, aggregate_unread_data, get_raw_unread_data
|
from zerver.lib.message import UnreadStreamInfo, aggregate_unread_data, get_raw_unread_data
|
||||||
from zerver.lib.response import json_success
|
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.message_send import internal_send_private_message
|
||||||
from zerver.actions.realm_icon import do_change_icon_source
|
from zerver.actions.realm_icon import do_change_icon_source
|
||||||
from zerver.actions.realm_logo import do_change_logo_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.uploads import do_delete_old_unclaimed_attachments
|
||||||
from zerver.actions.user_settings import do_delete_avatar_image
|
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 import avatar_url, get_avatar_field
|
||||||
from zerver.lib.avatar_hash import user_avatar_path
|
from zerver.lib.avatar_hash import user_avatar_path
|
||||||
from zerver.lib.cache import cache_get, get_realm_used_upload_space_cache_key
|
from zerver.lib.cache import cache_get, get_realm_used_upload_space_cache_key
|
||||||
|
|
|
@ -5,8 +5,8 @@ from unittest import mock
|
||||||
import orjson
|
import orjson
|
||||||
from django.utils.timezone import now as timezone_now
|
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.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.streams import ensure_stream
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import most_recent_usermessage
|
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.invites import do_create_multiuse_invite_link, do_invite_users
|
||||||
from zerver.actions.message_send import get_recipient_info
|
from zerver.actions.message_send import get_recipient_info
|
||||||
from zerver.actions.muted_users import do_mute_user
|
from zerver.actions.muted_users import do_mute_user
|
||||||
|
from zerver.actions.realm_settings import do_set_realm_property
|
||||||
from zerver.actions.users import (
|
from zerver.actions.users import (
|
||||||
change_user_is_active,
|
change_user_is_active,
|
||||||
do_change_can_create_users,
|
do_change_can_create_users,
|
||||||
|
@ -23,7 +24,6 @@ from zerver.actions.users import (
|
||||||
do_deactivate_user,
|
do_deactivate_user,
|
||||||
do_delete_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.avatar import avatar_url, get_gravatar_url
|
||||||
from zerver.lib.bulk_create import create_users
|
from zerver.lib.bulk_create import create_users
|
||||||
from zerver.lib.create_user import copy_default_settings
|
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 django.views.decorators.http import require_safe
|
||||||
|
|
||||||
from confirmation.models import Confirmation, confirmation_url
|
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.user_settings import do_change_user_delivery_email
|
||||||
from zerver.actions.users import change_user_is_active
|
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.email_notifications import enqueue_welcome_emails
|
||||||
from zerver.lib.response import json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.models import Realm, get_realm, get_realm_stream, get_user_by_delivery_email
|
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 django.views.decorators.http import require_safe
|
||||||
|
|
||||||
from confirmation.models import Confirmation, ConfirmationKeyException, get_object_from_key
|
from confirmation.models import Confirmation, ConfirmationKeyException, get_object_from_key
|
||||||
from zerver.decorator import require_realm_admin, require_realm_owner
|
from zerver.actions.realm_settings import (
|
||||||
from zerver.forms import check_subdomain_available as check_subdomain
|
|
||||||
from zerver.lib.actions import (
|
|
||||||
do_change_realm_subdomain,
|
|
||||||
do_deactivate_realm,
|
do_deactivate_realm,
|
||||||
do_reactivate_realm,
|
do_reactivate_realm,
|
||||||
do_set_realm_authentication_methods,
|
do_set_realm_authentication_methods,
|
||||||
|
@ -20,6 +17,9 @@ from zerver.lib.actions import (
|
||||||
do_set_realm_signup_notifications_stream,
|
do_set_realm_signup_notifications_stream,
|
||||||
do_set_realm_user_default_setting,
|
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.exceptions import JsonableError, OrganizationOwnerRequired
|
||||||
from zerver.lib.i18n import get_available_language_codes
|
from zerver.lib.i18n import get_available_language_codes
|
||||||
from zerver.lib.message import parse_message_content_delete_limit
|
from zerver.lib.message import parse_message_content_delete_limit
|
||||||
|
|
Loading…
Reference in New Issue