From 7cfa110934242c7e57f305a55b64175e115dad07 Mon Sep 17 00:00:00 2001 From: Shubham Padia Date: Mon, 11 Nov 2024 09:44:13 +0000 Subject: [PATCH] settings: Realms with limited plans cannot change can_create_groups. We do not allow realms on a limited plan to create groups. This commit adds a banner to upgrade to the can_create_groups org setting and disables editing it on the backend. This commit also adds a new method called `disable_group_permission_setting` to easily disable similar settings. --- web/src/settings_components.ts | 6 +++++ web/src/settings_org.ts | 27 +++++++++---------- web/src/user_group_edit.js | 5 +--- .../organization_permissions_admin.hbs | 2 +- web/tests/settings_org.test.cjs | 4 +++ zerver/tests/test_realm.py | 10 +++++++ zerver/views/realm.py | 3 +++ 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/web/src/settings_components.ts b/web/src/settings_components.ts index 961ffb3799..b990372213 100644 --- a/web/src/settings_components.ts +++ b/web/src/settings_components.ts @@ -1490,6 +1490,12 @@ export function disable_opening_typeahead_on_clicking_label($container: JQuery): $group_setting_labels.off("click"); } +export function disable_group_permission_setting($container: JQuery): void { + $container.find(".input").prop("contenteditable", false); + $container.closest(".input-group").addClass("group_setting_disabled"); + disable_opening_typeahead_on_clicking_label($container.closest(".input-group")); +} + export const group_setting_widget_map = new Map([ ["can_add_members_group", null], ["can_join_group", null], diff --git a/web/src/settings_org.ts b/web/src/settings_org.ts index 38c1cda5b2..2579c0acf3 100644 --- a/web/src/settings_org.ts +++ b/web/src/settings_org.ts @@ -144,11 +144,7 @@ export function enable_or_disable_group_permission_settings(): void { ]; for (const setting_name of owner_editable_settings) { const $permission_pill_container = $(`#id_${CSS.escape(setting_name)}`); - $permission_pill_container.find(".input").prop("contenteditable", false); - $permission_pill_container.closest(".input-group").addClass("group_setting_disabled"); - settings_components.disable_opening_typeahead_on_clicking_label( - $permission_pill_container.closest(".input-group"), - ); + settings_components.disable_group_permission_setting($permission_pill_container); } return; } @@ -156,9 +152,7 @@ export function enable_or_disable_group_permission_settings(): void { const $permission_pill_container_elements = $("#organization-permissions").find( ".pill-container", ); - $permission_pill_container_elements.find(".input").prop("contenteditable", false); - $permission_pill_container_elements.closest(".input-group").addClass("group_setting_disabled"); - settings_components.disable_opening_typeahead_on_clicking_label($("#organization-permissions")); + settings_components.disable_group_permission_setting($permission_pill_container_elements); } type OrganizationSettingsOptions = { @@ -355,6 +349,14 @@ function set_create_web_public_stream_dropdown_visibility(): void { ); } +function disable_create_user_groups_if_on_limited_plan(): void { + if (!realm.zulip_plan_is_not_limited) { + settings_components.disable_group_permission_setting( + $("#id_realm_can_create_groups").closest(".input-group"), + ); + } +} + export function check_disable_direct_message_initiator_group_widget(): void { const direct_message_permission_group_widget = settings_components.get_group_setting_widget( "realm_direct_message_permission_group", @@ -369,12 +371,8 @@ export function check_disable_direct_message_initiator_group_widget(): void { direct_message_permission_group_widget, ); if (user_groups.is_setting_group_empty(direct_message_permission_value)) { - $("#id_realm_direct_message_initiator_group").find(".input").prop("contenteditable", false); - $("#id_realm_direct_message_initiator_group") - .closest(".input-group") - .addClass("group_setting_disabled"); - settings_components.disable_opening_typeahead_on_clicking_label( - $("#id_realm_direct_message_initiator_group").closest(".input-group"), + settings_components.disable_group_permission_setting( + $("#id_realm_direct_message_initiator_group"), ); } else if (current_user.is_admin) { $("#id_realm_direct_message_initiator_group").find(".input").prop("contenteditable", true); @@ -1124,6 +1122,7 @@ export function build_page(): void { set_message_content_in_email_notifications_visibility(); set_digest_emails_weekday_visibility(); set_create_web_public_stream_dropdown_visibility(); + disable_create_user_groups_if_on_limited_plan(); register_save_discard_widget_handlers($(".admin-realm-form"), "/json/realm", false); diff --git a/web/src/user_group_edit.js b/web/src/user_group_edit.js index b25069a087..a1e199b2ca 100644 --- a/web/src/user_group_edit.js +++ b/web/src/user_group_edit.js @@ -129,16 +129,13 @@ function update_group_permission_settings_elements(group) { }); settings_components.enable_opening_typeahead_on_clicking_label($group_permission_settings); } else { - $permission_pill_container_elements.find(".input").prop("contenteditable", false); - - $permission_input_groups.addClass("group_setting_disabled"); $permission_input_groups.each(function () { settings_components.initialize_disable_button_hint_popover( $(this), $t({defaultMessage: "You do not have permission to edit this setting."}), ); }); - settings_components.disable_opening_typeahead_on_clicking_label($group_permission_settings); + settings_components.disable_group_permission_setting($permission_input_groups); } } diff --git a/web/templates/settings/organization_permissions_admin.hbs b/web/templates/settings/organization_permissions_admin.hbs index de1d646a3b..ae598218fc 100644 --- a/web/templates/settings/organization_permissions_admin.hbs +++ b/web/templates/settings/organization_permissions_admin.hbs @@ -109,7 +109,7 @@ {{> group_setting_value_pill_input setting_name="realm_can_manage_all_groups" label=(t 'Who can administer all user groups')}} - + {{> upgrade_tip_widget . }} {{> group_setting_value_pill_input setting_name="realm_can_create_groups" label=(t 'Who can create user groups')}} diff --git a/web/tests/settings_org.test.cjs b/web/tests/settings_org.test.cjs index de5bf52f21..cdd6dfb177 100644 --- a/web/tests/settings_org.test.cjs +++ b/web/tests/settings_org.test.cjs @@ -625,6 +625,10 @@ test("set_up", ({override, override_rewire}) => { $.create(""), ); + // Make our plan not limited so we don't have to stub all the + // elements involved in disabling the can_create_groups input. + override(realm, "zulip_plan_is_not_limited", true); + override_rewire(settings_components, "get_input_element_value", (elem) => { if ($(elem).data() === "number") { return Number.parseInt($(elem).val(), 10); diff --git a/zerver/tests/test_realm.py b/zerver/tests/test_realm.py index c735a6d4dd..0ec79de51f 100644 --- a/zerver/tests/test_realm.py +++ b/zerver/tests/test_realm.py @@ -2358,6 +2358,16 @@ class RealmAPITest(ZulipTestCase): result = self.client_patch("/json/realm", req) self.assert_json_error(result, "Available on Zulip Cloud Standard. Upgrade to access.") + def test_can_create_groups_limited_plan_realms(self) -> None: + self.login("iago") + realm = get_realm("zulip") + do_change_realm_plan_type(realm, Realm.PLAN_TYPE_LIMITED, acting_user=None) + + members_group = NamedUserGroup.objects.get(name="role:members", realm=realm) + req = {"can_create_groups": orjson.dumps({"new": members_group.id}).decode()} + result = self.client_patch("/json/realm", req) + self.assert_json_error(result, "Available on Zulip Cloud Standard. Upgrade to access.") + def test_changing_can_access_all_users_group_based_on_plan_type(self) -> None: realm = get_realm("zulip") do_change_realm_plan_type(realm, Realm.PLAN_TYPE_LIMITED, acting_user=None) diff --git a/zerver/views/realm.py b/zerver/views/realm.py index 65f6a34a88..865291cdb9 100644 --- a/zerver/views/realm.py +++ b/zerver/views/realm.py @@ -217,6 +217,9 @@ def update_realm( message_retention_days_raw, Realm.MESSAGE_RETENTION_SPECIAL_VALUES_MAP ) + if can_create_groups is not None: + realm.ensure_not_on_limited_plan() + if ( invite_required is not None or create_multiuse_invite_group is not None