From 701e391defa3c4c39e354e081d44f29018695986 Mon Sep 17 00:00:00 2001 From: Sahil Batra Date: Wed, 2 Oct 2024 16:43:47 +0530 Subject: [PATCH] user_groups: Use can_join_group setting to check permisison. This commit adds code to use can_join_group setting when checking permission to join group in webapp. Fixes part of #25938. --- web/src/settings_data.ts | 10 ++ web/src/state_data.ts | 1 + web/src/types.ts | 1 + web/src/user_group_edit.js | 23 +++- web/src/user_group_edit_members.ts | 2 +- web/src/user_groups.ts | 7 ++ .../browse_user_groups_list_item.hbs | 4 +- web/tests/composebox_typeahead.test.js | 3 + web/tests/settings_data.test.js | 118 ++++++++++++++++++ web/tests/user_groups.test.js | 4 + 10 files changed, 166 insertions(+), 7 deletions(-) diff --git a/web/src/settings_data.ts b/web/src/settings_data.ts index b57785543a..220fb9a48c 100644 --- a/web/src/settings_data.ts +++ b/web/src/settings_data.ts @@ -215,6 +215,16 @@ export function can_manage_user_group(group_id: number): boolean { ); } +export function can_join_user_group(group_id: number): boolean { + const group = user_groups.get_user_group_from_id(group_id); + + if (user_has_permission_for_group_setting(group.can_join_group, "can_join_group", "group")) { + return true; + } + + return can_manage_user_group(group_id); +} + export function user_can_create_user_groups(): boolean { return user_has_permission_for_group_setting( realm.realm_can_create_groups, diff --git a/web/src/state_data.ts b/web/src/state_data.ts index e5d2ea6e0f..4e5bee748d 100644 --- a/web/src/state_data.ts +++ b/web/src/state_data.ts @@ -145,6 +145,7 @@ export const user_group_schema = z.object({ members: z.array(z.number()), is_system_group: z.boolean(), direct_subgroup_ids: z.array(z.number()), + can_join_group: group_setting_type_schema, can_manage_group: group_setting_type_schema, can_mention_group: z.number(), deactivated: z.boolean(), diff --git a/web/src/types.ts b/web/src/types.ts index 6b967e7028..d12577f831 100644 --- a/web/src/types.ts +++ b/web/src/types.ts @@ -16,6 +16,7 @@ export type UserGroupUpdateEvent = { data: { name?: string; description?: string; + can_join_group?: number; can_manage_group?: number; can_mention_group?: number; deactivated?: boolean; diff --git a/web/src/user_group_edit.js b/web/src/user_group_edit.js index fa23d50b4f..73e42b2713 100644 --- a/web/src/user_group_edit.js +++ b/web/src/user_group_edit.js @@ -258,7 +258,17 @@ function update_group_membership_button(group_id) { $group_settings_button.text($t({defaultMessage: "Join group"})); } - if (settings_data.can_manage_user_group(group_id)) { + const can_join_group = settings_data.can_join_user_group(group_id); + const can_leave_group = settings_data.can_manage_user_group(group_id); + + let can_update_membership = true; + if (!is_member && !can_join_group) { + can_update_membership = false; + } else if (is_member && !can_leave_group) { + can_update_membership = false; + } + + if (can_update_membership) { $group_settings_button.prop("disabled", false); $group_settings_button.css("pointer-events", ""); const $group_settings_button_wrapper = $group_settings_button.closest( @@ -298,7 +308,7 @@ export function handle_member_edit_event(group_id, user_ids) { // is added to it. The whole list is redrawed to // maintain the sorted order of groups. redraw_user_group_list(); - } else if (!settings_data.can_manage_user_group(group_id)) { + } else if (!settings_data.can_join_user_group(group_id)) { // We remove the group row immediately only if the // user cannot join the group again themselves. const group_row = row_for_group_id(group_id); @@ -315,7 +325,8 @@ export function handle_member_edit_event(group_id, user_ids) { const item = group; item.is_member = user_groups.is_user_in_group(group_id, people.my_current_user_id()); - item.can_edit = settings_data.can_manage_user_group(item.id); + item.can_join = settings_data.can_join_user_group(item.id); + item.can_leave = settings_data.can_manage_user_group(item.id); const html = render_browse_user_groups_list_item(item); const $new_row = $(html); @@ -634,6 +645,9 @@ export function update_group(event) { if (event.data.can_manage_group !== undefined) { update_group_management_ui(); } + if (event.data.can_join_group !== undefined) { + update_group_membership_button(group.id); + } } } @@ -831,7 +845,8 @@ export function setup_page(callback) { people.my_current_user_id(), item.id, ); - item.can_edit = settings_data.can_manage_user_group(item.id); + item.can_join = settings_data.can_join_user_group(item.id); + item.can_leave = settings_data.can_manage_user_group(item.id); return render_browse_user_groups_list_item(item); }, filter: { diff --git a/web/src/user_group_edit_members.ts b/web/src/user_group_edit_members.ts index 1ce995cc64..7f123fa2d4 100644 --- a/web/src/user_group_edit_members.ts +++ b/web/src/user_group_edit_members.ts @@ -356,7 +356,7 @@ function remove_member({ }); } - if (people.is_my_user_id(target_user_id) && !settings_data.can_manage_user_group(group_id)) { + if (people.is_my_user_id(target_user_id) && !settings_data.can_join_user_group(group_id)) { const html_body = render_leave_user_group_modal({ message: $t({ defaultMessage: "Once you leave this group, you will not be able to rejoin.", diff --git a/web/src/user_groups.ts b/web/src/user_groups.ts index 21bd79ae23..4e573a49b1 100644 --- a/web/src/user_groups.ts +++ b/web/src/user_groups.ts @@ -55,6 +55,7 @@ export function add(user_group_raw: UserGroupRaw): UserGroup { members: new Set(user_group_raw.members), is_system_group: user_group_raw.is_system_group, direct_subgroup_ids: new Set(user_group_raw.direct_subgroup_ids), + can_join_group: user_group_raw.can_join_group, can_manage_group: user_group_raw.can_manage_group, can_mention_group: user_group_raw.can_mention_group, deactivated: user_group_raw.deactivated, @@ -112,6 +113,12 @@ export function update(event: UserGroupUpdateEvent): void { user_group_name_dict.delete(group.name); user_group_name_dict.set(group.name, group); } + + if (event.data.can_join_group !== undefined) { + group.can_join_group = event.data.can_join_group; + user_group_name_dict.delete(group.name); + user_group_name_dict.set(group.name, group); + } } export function get_user_group_from_name(name: string): UserGroup | undefined { diff --git a/web/templates/user_group_settings/browse_user_groups_list_item.hbs b/web/templates/user_group_settings/browse_user_groups_list_item.hbs index 26bd733125..861fbd6604 100644 --- a/web/templates/user_group_settings/browse_user_groups_list_item.hbs +++ b/web/templates/user_group_settings/browse_user_groups_list_item.hbs @@ -1,6 +1,6 @@
{{#if is_member}} -
+