diff --git a/analytics/management/commands/populate_analytics_db.py b/analytics/management/commands/populate_analytics_db.py index 4032842ae2..385e9677b8 100644 --- a/analytics/management/commands/populate_analytics_db.py +++ b/analytics/management/commands/populate_analytics_db.py @@ -23,19 +23,10 @@ from zerver.lib.create_user import create_user from zerver.lib.management import ZulipBaseCommand from zerver.lib.storage import static_path from zerver.lib.stream_color import STREAM_ASSIGNMENT_COLORS +from zerver.lib.streams import get_default_group_setting_values from zerver.lib.timestamp import floor_to_day from zerver.lib.upload import upload_message_attachment_from_request -from zerver.models import ( - Client, - NamedUserGroup, - Realm, - RealmAuditLog, - Recipient, - Stream, - Subscription, - UserProfile, -) -from zerver.models.groups import SystemGroups +from zerver.models import Client, Realm, RealmAuditLog, Recipient, Stream, Subscription, UserProfile from zerver.models.realm_audit_logs import AuditLogEventType @@ -115,14 +106,11 @@ class Command(ZulipBaseCommand): force_date_joined=installation_time, ) - administrators_user_group = NamedUserGroup.objects.get( - name=SystemGroups.ADMINISTRATORS, realm=realm, is_system_group=True - ) stream = Stream.objects.create( name="all", realm=realm, date_created=installation_time, - can_remove_subscribers_group=administrators_user_group, + **get_default_group_setting_values(realm), ) recipient = Recipient.objects.create(type_id=stream.id, type=Recipient.STREAM) stream.recipient = recipient diff --git a/analytics/tests/test_counts.py b/analytics/tests/test_counts.py index 3c74f0daca..2afa9cc82b 100644 --- a/analytics/tests/test_counts.py +++ b/analytics/tests/test_counts.py @@ -55,6 +55,7 @@ from zerver.lib.push_notifications import ( get_message_payload_gcm, hex_to_b64, ) +from zerver.lib.streams import get_default_group_setting_values from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_helpers import activate_push_notification_service from zerver.lib.timestamp import TimeZoneNotUTCError, ceiling_to_day, floor_to_day @@ -164,7 +165,7 @@ class AnalyticsTestCase(ZulipTestCase): "name": f"stream name {self.name_counter}", "realm": self.default_realm, "date_created": self.TIME_LAST_HOUR, - "can_remove_subscribers_group": self.administrators_user_group, + **get_default_group_setting_values(self.default_realm), } for key, value in defaults.items(): kwargs[key] = kwargs.get(key, value) diff --git a/zerver/lib/bulk_create.py b/zerver/lib/bulk_create.py index 480a798c7d..ce6e821dba 100644 --- a/zerver/lib/bulk_create.py +++ b/zerver/lib/bulk_create.py @@ -6,7 +6,7 @@ from django.utils.timezone import now as timezone_now from zerver.lib.create_user import create_user_profile, get_display_email_address from zerver.lib.initial_password import initial_password -from zerver.lib.streams import render_stream_description +from zerver.lib.streams import get_default_group_setting_values, render_stream_description from zerver.models import ( NamedUserGroup, Realm, @@ -200,9 +200,6 @@ def bulk_create_streams(realm: Realm, stream_dict: dict[str, dict[str, Any]]) -> existing_streams = { name.lower() for name in Stream.objects.filter(realm=realm).values_list("name", flat=True) } - administrators_user_group = NamedUserGroup.objects.get( - name=SystemGroups.ADMINISTRATORS, is_system_group=True, realm=realm - ) streams_to_create: list[Stream] = [] for name, options in stream_dict.items(): if "history_public_to_subscribers" not in options: @@ -223,8 +220,8 @@ def bulk_create_streams(realm: Realm, stream_dict: dict[str, dict[str, Any]]) -> history_public_to_subscribers=options["history_public_to_subscribers"], is_web_public=options.get("is_web_public", False), is_in_zephyr_realm=realm.is_zephyr_mirror_realm, - can_remove_subscribers_group=administrators_user_group, creator=options.get("creator", None), + **get_default_group_setting_values(realm), ), ) # Sort streams by name before creating them so that we can have a diff --git a/zerver/lib/import_realm.py b/zerver/lib/import_realm.py index a6b77036fd..e42271183e 100644 --- a/zerver/lib/import_realm.py +++ b/zerver/lib/import_realm.py @@ -46,7 +46,11 @@ from zerver.lib.partial import partial from zerver.lib.push_notifications import sends_notifications_directly from zerver.lib.remote_server import maybe_enqueue_audit_log_upload from zerver.lib.server_initialization import create_internal_realm, server_initialized -from zerver.lib.streams import render_stream_description, update_stream_active_status_for_realm +from zerver.lib.streams import ( + get_stream_permission_default_group, + render_stream_description, + update_stream_active_status_for_realm, +) from zerver.lib.thumbnail import THUMBNAIL_ACCEPT_IMAGE_TYPES, BadImageError, maybe_thumbnail from zerver.lib.timestamp import datetime_to_timestamp from zerver.lib.upload import ensure_avatar_image, sanitize_name, upload_backend, upload_emoji_image @@ -243,13 +247,11 @@ def fix_upload_links(data: TableData, message_table: TableName) -> None: ) -def fix_streams_can_remove_subscribers_group_column(data: TableData, realm: Realm) -> None: +def fix_stream_permission_group_settings(data: TableData, realm: Realm) -> None: table = get_db_table(Stream) - admins_group = NamedUserGroup.objects.get( - name=SystemGroups.ADMINISTRATORS, realm=realm, is_system_group=True - ) for stream in data[table]: - stream["can_remove_subscribers_group"] = admins_group + for setting_name in Stream.stream_permission_group_settings: + stream[setting_name] = get_stream_permission_default_group(setting_name, realm) def create_subscription_events(data: TableData, realm_id: int) -> None: @@ -1289,13 +1291,12 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea if role_system_groups_dict is not None: # Because the system user groups are missing, we manually set up - # the defaults for can_remove_subscribers_group for all the + # the defaults for stream permission settings for all the # streams. - fix_streams_can_remove_subscribers_group_column(data, realm) + fix_stream_permission_group_settings(data, realm) else: - re_map_foreign_keys( - data, "zerver_stream", "can_remove_subscribers_group", related_table="usergroup" - ) + for setting_name in Stream.stream_permission_group_settings: + re_map_foreign_keys(data, "zerver_stream", setting_name, related_table="usergroup") # Handle rendering of stream descriptions for import from non-Zulip for stream in data["zerver_stream"]: stream["rendered_description"] = render_stream_description(stream["description"], realm) diff --git a/zerver/lib/streams.py b/zerver/lib/streams.py index e691942b3a..3ebb4ba9b6 100644 --- a/zerver/lib/streams.py +++ b/zerver/lib/streams.py @@ -41,7 +41,6 @@ from zerver.models import ( UserGroupMembership, UserProfile, ) -from zerver.models.groups import SystemGroups from zerver.models.realm_audit_logs import AuditLogEventType from zerver.models.streams import ( bulk_get_streams, @@ -140,6 +139,25 @@ def send_stream_creation_event( send_event_on_commit(realm, event, user_ids) +def get_stream_permission_default_group(setting_name: str, realm: Realm) -> UserGroup: + setting_default_name = Stream.stream_permission_group_settings[setting_name].default_group_name + return NamedUserGroup.objects.get( + name=setting_default_name, + realm=realm, + is_system_group=True, + ) + + +def get_default_group_setting_values(realm: Realm) -> dict[str, UserGroup]: + group_setting_values = {} + for setting_name in Stream.stream_permission_group_settings: + group_setting_values[setting_name] = get_stream_permission_default_group( + setting_name, realm + ) + + return group_setting_values + + @transaction.atomic(savepoint=False) def create_stream_if_needed( realm: Realm, @@ -159,14 +177,21 @@ def create_stream_if_needed( realm, invite_only, history_public_to_subscribers ) - if can_remove_subscribers_group is None: - can_remove_subscribers_group = NamedUserGroup.objects.get( - name=SystemGroups.ADMINISTRATORS, is_system_group=True, realm=realm - ) + group_setting_values = {} + request_settings_dict = locals() + for setting_name in Stream.stream_permission_group_settings: + if setting_name not in request_settings_dict: # nocoverage + continue + + if request_settings_dict[setting_name] is None: + group_setting_values[setting_name] = get_stream_permission_default_group( + setting_name, realm + ) + else: + group_setting_values[setting_name] = request_settings_dict[setting_name] stream_name = stream_name.strip() - assert can_remove_subscribers_group is not None (stream, created) = Stream.objects.get_or_create( realm=realm, name__iexact=stream_name, @@ -180,7 +205,7 @@ def create_stream_if_needed( history_public_to_subscribers=history_public_to_subscribers, is_in_zephyr_realm=realm.is_zephyr_mirror_realm, message_retention_days=message_retention_days, - can_remove_subscribers_group=can_remove_subscribers_group, + **group_setting_values, ), ) diff --git a/zerver/lib/test_classes.py b/zerver/lib/test_classes.py index 55d620140c..808251b782 100644 --- a/zerver/lib/test_classes.py +++ b/zerver/lib/test_classes.py @@ -60,6 +60,7 @@ from zerver.lib.soft_deactivation import do_soft_deactivate_users from zerver.lib.stream_subscription import get_subscribed_stream_ids_for_user from zerver.lib.streams import ( create_stream_if_needed, + get_default_group_setting_values, get_default_value_for_history_public_to_subscribers, ) from zerver.lib.subscription_info import gather_subscriptions @@ -103,7 +104,6 @@ from zerver.models import ( UserProfile, UserStatus, ) -from zerver.models.groups import SystemGroups from zerver.models.realms import clear_supported_auth_backends_cache, get_realm from zerver.models.streams import get_realm_stream, get_stream from zerver.models.users import get_system_bot, get_user, get_user_by_delivery_email @@ -1377,9 +1377,6 @@ Output: history_public_to_subscribers = get_default_value_for_history_public_to_subscribers( realm, invite_only, history_public_to_subscribers ) - administrators_user_group = NamedUserGroup.objects.get( - name=SystemGroups.ADMINISTRATORS, realm=realm, is_system_group=True - ) try: stream = Stream.objects.create( @@ -1388,7 +1385,7 @@ Output: invite_only=invite_only, is_web_public=is_web_public, history_public_to_subscribers=history_public_to_subscribers, - can_remove_subscribers_group=administrators_user_group, + **get_default_group_setting_values(realm), ) except IntegrityError: # nocoverage -- this is for bugs in the tests raise Exception(