mirror of https://github.com/zulip/zulip.git
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.
This commit is contained in:
parent
6d0d1a0700
commit
701e391def
|
@ -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 {
|
export function user_can_create_user_groups(): boolean {
|
||||||
return user_has_permission_for_group_setting(
|
return user_has_permission_for_group_setting(
|
||||||
realm.realm_can_create_groups,
|
realm.realm_can_create_groups,
|
||||||
|
|
|
@ -145,6 +145,7 @@ export const user_group_schema = z.object({
|
||||||
members: z.array(z.number()),
|
members: z.array(z.number()),
|
||||||
is_system_group: z.boolean(),
|
is_system_group: z.boolean(),
|
||||||
direct_subgroup_ids: z.array(z.number()),
|
direct_subgroup_ids: z.array(z.number()),
|
||||||
|
can_join_group: group_setting_type_schema,
|
||||||
can_manage_group: group_setting_type_schema,
|
can_manage_group: group_setting_type_schema,
|
||||||
can_mention_group: z.number(),
|
can_mention_group: z.number(),
|
||||||
deactivated: z.boolean(),
|
deactivated: z.boolean(),
|
||||||
|
|
|
@ -16,6 +16,7 @@ export type UserGroupUpdateEvent = {
|
||||||
data: {
|
data: {
|
||||||
name?: string;
|
name?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
can_join_group?: number;
|
||||||
can_manage_group?: number;
|
can_manage_group?: number;
|
||||||
can_mention_group?: number;
|
can_mention_group?: number;
|
||||||
deactivated?: boolean;
|
deactivated?: boolean;
|
||||||
|
|
|
@ -258,7 +258,17 @@ function update_group_membership_button(group_id) {
|
||||||
$group_settings_button.text($t({defaultMessage: "Join group"}));
|
$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.prop("disabled", false);
|
||||||
$group_settings_button.css("pointer-events", "");
|
$group_settings_button.css("pointer-events", "");
|
||||||
const $group_settings_button_wrapper = $group_settings_button.closest(
|
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
|
// is added to it. The whole list is redrawed to
|
||||||
// maintain the sorted order of groups.
|
// maintain the sorted order of groups.
|
||||||
redraw_user_group_list();
|
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
|
// We remove the group row immediately only if the
|
||||||
// user cannot join the group again themselves.
|
// user cannot join the group again themselves.
|
||||||
const group_row = row_for_group_id(group_id);
|
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;
|
const item = group;
|
||||||
item.is_member = user_groups.is_user_in_group(group_id, people.my_current_user_id());
|
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 html = render_browse_user_groups_list_item(item);
|
||||||
const $new_row = $(html);
|
const $new_row = $(html);
|
||||||
|
|
||||||
|
@ -634,6 +645,9 @@ export function update_group(event) {
|
||||||
if (event.data.can_manage_group !== undefined) {
|
if (event.data.can_manage_group !== undefined) {
|
||||||
update_group_management_ui();
|
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(),
|
people.my_current_user_id(),
|
||||||
item.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);
|
return render_browse_user_groups_list_item(item);
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
|
|
|
@ -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({
|
const html_body = render_leave_user_group_modal({
|
||||||
message: $t({
|
message: $t({
|
||||||
defaultMessage: "Once you leave this group, you will not be able to rejoin.",
|
defaultMessage: "Once you leave this group, you will not be able to rejoin.",
|
||||||
|
|
|
@ -55,6 +55,7 @@ export function add(user_group_raw: UserGroupRaw): UserGroup {
|
||||||
members: new Set(user_group_raw.members),
|
members: new Set(user_group_raw.members),
|
||||||
is_system_group: user_group_raw.is_system_group,
|
is_system_group: user_group_raw.is_system_group,
|
||||||
direct_subgroup_ids: new Set(user_group_raw.direct_subgroup_ids),
|
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_manage_group: user_group_raw.can_manage_group,
|
||||||
can_mention_group: user_group_raw.can_mention_group,
|
can_mention_group: user_group_raw.can_mention_group,
|
||||||
deactivated: user_group_raw.deactivated,
|
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.delete(group.name);
|
||||||
user_group_name_dict.set(group.name, group);
|
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 {
|
export function get_user_group_from_name(name: string): UserGroup | undefined {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="group-row" data-group-id="{{id}}" data-group-name="{{name}}">
|
<div class="group-row" data-group-id="{{id}}" data-group-name="{{name}}">
|
||||||
{{#if is_member}}
|
{{#if is_member}}
|
||||||
<div class="check checked join_leave_button tippy-zulip-tooltip {{#unless can_edit}}disabled{{/unless}}" data-tooltip-template-id="{{#if can_edit}}leave-{{name}}-group-tooltip-template{{else}}cannot-leave-{{name}}-group-tooltip-template{{/if}}">
|
<div class="check checked join_leave_button tippy-zulip-tooltip {{#unless can_leave}}disabled{{/unless}}" data-tooltip-template-id="{{#if can_leave}}leave-{{name}}-group-tooltip-template{{else}}cannot-leave-{{name}}-group-tooltip-template{{/if}}">
|
||||||
<template id="leave-{{name}}-group-tooltip-template">
|
<template id="leave-{{name}}-group-tooltip-template">
|
||||||
<span>
|
<span>
|
||||||
{{#tr}}
|
{{#tr}}
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
<div class='join_leave_status'></div>
|
<div class='join_leave_status'></div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="check join_leave_button {{#unless can_edit}}disabled{{/unless}} tippy-zulip-tooltip" data-tooltip-template-id="{{#if can_edit}}join-{{name}}-group-tooltip-template{{else}}cannot-join-{{name}}-group-tooltip-template{{/if}}">
|
<div class="check join_leave_button {{#unless can_join}}disabled{{/unless}} tippy-zulip-tooltip" data-tooltip-template-id="{{#if can_join}}join-{{name}}-group-tooltip-template{{else}}cannot-join-{{name}}-group-tooltip-template{{/if}}">
|
||||||
<template id="join-{{name}}-group-tooltip-template">
|
<template id="join-{{name}}-group-tooltip-template">
|
||||||
<span>
|
<span>
|
||||||
{{#tr}}
|
{{#tr}}
|
||||||
|
|
|
@ -440,6 +440,7 @@ const hamletcharacters = user_group_item({
|
||||||
members: new Set([100, 104]),
|
members: new Set([100, 104]),
|
||||||
is_system_group: false,
|
is_system_group: false,
|
||||||
direct_subgroup_ids: new Set([]),
|
direct_subgroup_ids: new Set([]),
|
||||||
|
can_join_group: 2,
|
||||||
can_manage_group: 2,
|
can_manage_group: 2,
|
||||||
can_mention_group: 2,
|
can_mention_group: 2,
|
||||||
deactivated: false,
|
deactivated: false,
|
||||||
|
@ -454,6 +455,7 @@ const backend = user_group_item({
|
||||||
members: new Set([101]),
|
members: new Set([101]),
|
||||||
is_system_group: false,
|
is_system_group: false,
|
||||||
direct_subgroup_ids: new Set([1]),
|
direct_subgroup_ids: new Set([1]),
|
||||||
|
can_join_group: 1,
|
||||||
can_manage_group: 1,
|
can_manage_group: 1,
|
||||||
can_mention_group: 1,
|
can_mention_group: 1,
|
||||||
deactivated: false,
|
deactivated: false,
|
||||||
|
@ -468,6 +470,7 @@ const call_center = user_group_item({
|
||||||
members: new Set([102]),
|
members: new Set([102]),
|
||||||
is_system_group: false,
|
is_system_group: false,
|
||||||
direct_subgroup_ids: new Set([]),
|
direct_subgroup_ids: new Set([]),
|
||||||
|
can_join_group: 2,
|
||||||
can_manage_group: 2,
|
can_manage_group: 2,
|
||||||
can_mention_group: 2,
|
can_mention_group: 2,
|
||||||
deactivated: false,
|
deactivated: false,
|
||||||
|
|
|
@ -442,6 +442,124 @@ run_test("can_manage_user_group", () => {
|
||||||
assert.ok(settings_data.can_manage_user_group(students.id));
|
assert.ok(settings_data.can_manage_user_group(students.id));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
run_test("can_join_user_group", () => {
|
||||||
|
const admins = {
|
||||||
|
description: "Administrators",
|
||||||
|
name: "role:administrators",
|
||||||
|
id: 1,
|
||||||
|
members: new Set([1]),
|
||||||
|
is_system_group: true,
|
||||||
|
direct_subgroup_ids: new Set([]),
|
||||||
|
can_join_group: 4,
|
||||||
|
can_manage_group: 4,
|
||||||
|
can_mention_group: 1,
|
||||||
|
};
|
||||||
|
const moderators = {
|
||||||
|
description: "Moderators",
|
||||||
|
name: "role:moderators",
|
||||||
|
id: 2,
|
||||||
|
members: new Set([2]),
|
||||||
|
is_system_group: true,
|
||||||
|
direct_subgroup_ids: new Set([1]),
|
||||||
|
can_join_group: 4,
|
||||||
|
can_manage_group: 4,
|
||||||
|
can_mention_group: 1,
|
||||||
|
};
|
||||||
|
const members = {
|
||||||
|
description: "Members",
|
||||||
|
name: "role:members",
|
||||||
|
id: 3,
|
||||||
|
members: new Set([3, 4]),
|
||||||
|
is_system_group: true,
|
||||||
|
direct_subgroup_ids: new Set([1, 2]),
|
||||||
|
can_join_group: 4,
|
||||||
|
can_manage_group: 4,
|
||||||
|
can_mention_group: 4,
|
||||||
|
};
|
||||||
|
const nobody = {
|
||||||
|
description: "Nobody",
|
||||||
|
name: "role:nobody",
|
||||||
|
id: 4,
|
||||||
|
members: new Set([]),
|
||||||
|
is_system_group: true,
|
||||||
|
direct_subgroup_ids: new Set([]),
|
||||||
|
can_join_group: 4,
|
||||||
|
can_manage_group: 4,
|
||||||
|
can_mention_group: 2,
|
||||||
|
};
|
||||||
|
const students = {
|
||||||
|
description: "Students group",
|
||||||
|
name: "Students",
|
||||||
|
id: 5,
|
||||||
|
members: new Set([1, 2]),
|
||||||
|
is_system_group: false,
|
||||||
|
direct_subgroup_ids: new Set([4, 5]),
|
||||||
|
can_join_group: 1,
|
||||||
|
can_manage_group: {
|
||||||
|
direct_members: [4],
|
||||||
|
direct_subgroups: [],
|
||||||
|
},
|
||||||
|
can_mention_group: 3,
|
||||||
|
creator_id: 4,
|
||||||
|
};
|
||||||
|
user_groups.initialize({
|
||||||
|
realm_user_groups: [admins, moderators, members, nobody, students],
|
||||||
|
});
|
||||||
|
realm.realm_can_manage_all_groups = nobody.id;
|
||||||
|
|
||||||
|
page_params.is_spectator = true;
|
||||||
|
assert.ok(!settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
page_params.is_spectator = false;
|
||||||
|
// admin user
|
||||||
|
current_user.user_id = 1;
|
||||||
|
assert.ok(settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
// moderator user
|
||||||
|
current_user.user_id = 2;
|
||||||
|
assert.ok(!settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
let event = {
|
||||||
|
group_id: students.id,
|
||||||
|
data: {
|
||||||
|
can_join_group: moderators.id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
user_groups.update(event);
|
||||||
|
assert.ok(settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
current_user.user_id = 1;
|
||||||
|
assert.ok(settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
// Some other user.
|
||||||
|
current_user.user_id = 5;
|
||||||
|
assert.ok(!settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
event = {
|
||||||
|
group_id: students.id,
|
||||||
|
data: {
|
||||||
|
can_join_group: {
|
||||||
|
direct_members: [5],
|
||||||
|
direct_subgroups: [admins.id],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
user_groups.update(event);
|
||||||
|
assert.ok(settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
current_user.user_id = 2;
|
||||||
|
assert.ok(!settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
// User can join the group if they can add anyone in the group which
|
||||||
|
// depends on can_manage_group and realm.can_manage_all_groups settings.
|
||||||
|
current_user.user_id = 4;
|
||||||
|
assert.ok(settings_data.can_join_user_group(students.id));
|
||||||
|
|
||||||
|
realm.realm_can_manage_all_groups = moderators.id;
|
||||||
|
current_user.user_id = 2;
|
||||||
|
assert.ok(settings_data.can_join_user_group(students.id));
|
||||||
|
});
|
||||||
|
|
||||||
run_test("type_id_to_string", () => {
|
run_test("type_id_to_string", () => {
|
||||||
page_params.bot_types = [
|
page_params.bot_types = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@ run_test("user_groups", () => {
|
||||||
members: new Set([1, 2]),
|
members: new Set([1, 2]),
|
||||||
is_system_group: false,
|
is_system_group: false,
|
||||||
direct_subgroup_ids: new Set([4, 5]),
|
direct_subgroup_ids: new Set([4, 5]),
|
||||||
|
can_join_group: 1,
|
||||||
can_manage_group: 1,
|
can_manage_group: 1,
|
||||||
can_mention_group: 2,
|
can_mention_group: 2,
|
||||||
deactivated: false,
|
deactivated: false,
|
||||||
|
@ -41,6 +42,7 @@ run_test("user_groups", () => {
|
||||||
members: new Set([3]),
|
members: new Set([3]),
|
||||||
is_system_group: false,
|
is_system_group: false,
|
||||||
direct_subgroup_ids: new Set([]),
|
direct_subgroup_ids: new Set([]),
|
||||||
|
can_join_group: 1,
|
||||||
can_manage_group: 1,
|
can_manage_group: 1,
|
||||||
can_mention_group: 2,
|
can_mention_group: 2,
|
||||||
deactivated: false,
|
deactivated: false,
|
||||||
|
@ -51,6 +53,7 @@ run_test("user_groups", () => {
|
||||||
members: new Set([1, 2, 3]),
|
members: new Set([1, 2, 3]),
|
||||||
is_system_group: false,
|
is_system_group: false,
|
||||||
direct_subgroup_ids: new Set([4, 5, 6]),
|
direct_subgroup_ids: new Set([4, 5, 6]),
|
||||||
|
can_join_group: 1,
|
||||||
can_manage_group: 1,
|
can_manage_group: 1,
|
||||||
can_mention_group: 1,
|
can_mention_group: 1,
|
||||||
deactivated: false,
|
deactivated: false,
|
||||||
|
@ -61,6 +64,7 @@ run_test("user_groups", () => {
|
||||||
members: new Set([1, 2, 3]),
|
members: new Set([1, 2, 3]),
|
||||||
is_system_group: false,
|
is_system_group: false,
|
||||||
direct_subgroup_ids: new Set([4, 5, 6]),
|
direct_subgroup_ids: new Set([4, 5, 6]),
|
||||||
|
can_join_group: 1,
|
||||||
can_manage_group: 1,
|
can_manage_group: 1,
|
||||||
can_mention_group: 1,
|
can_mention_group: 1,
|
||||||
deactivated: true,
|
deactivated: true,
|
||||||
|
|
Loading…
Reference in New Issue