mirror of https://github.com/zulip/zulip.git
settings: Add `can_move_messages_between_channels_group` realm setting.
Added `can_move_messages_between_channels_group` realm setting to replace `move_messages_between_streams_policy`.
This commit is contained in:
parent
c1ec39f3ba
commit
1be0cb1b75
|
@ -20,6 +20,14 @@ format used by the Zulip server that they are interacting with.
|
||||||
|
|
||||||
## Changes in Zulip 10.0
|
## Changes in Zulip 10.0
|
||||||
|
|
||||||
|
**Feature level 310**
|
||||||
|
|
||||||
|
* `PATCH /realm`, [`GET /events`](/api/get-events),
|
||||||
|
[`POST /register`](/api/register-queue):
|
||||||
|
Added `can_move_messages_between_channels_group` realm setting which is a
|
||||||
|
[group-setting value](/api/group-setting-values) describing the set of users
|
||||||
|
with permission to move messages from one channel to another in the organization.
|
||||||
|
|
||||||
**Feature level 309**
|
**Feature level 309**
|
||||||
|
|
||||||
* [Group-setting values](/api/group-setting-values): Starting with
|
* [Group-setting values](/api/group-setting-values): Starting with
|
||||||
|
|
|
@ -34,7 +34,7 @@ DESKTOP_WARNING_VERSION = "5.9.3"
|
||||||
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
||||||
# entries in the endpoint's documentation in `zulip.yaml`.
|
# entries in the endpoint's documentation in `zulip.yaml`.
|
||||||
|
|
||||||
API_FEATURE_LEVEL = 309 # Last bumped for group values in settings.
|
API_FEATURE_LEVEL = 310 # Last bumped for adding `can_move_messages_between_channels_group`.
|
||||||
|
|
||||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||||
# only when going from an old version of the code to a newer version. Bump
|
# only when going from an old version of the code to a newer version. Bump
|
||||||
|
|
|
@ -248,8 +248,8 @@ export function is_stream_editable(message: Message, edit_limit_seconds_buffer =
|
||||||
}
|
}
|
||||||
|
|
||||||
// Organization admins and moderators can edit stream indefinitely,
|
// Organization admins and moderators can edit stream indefinitely,
|
||||||
// irrespective of the stream editing deadline, if
|
// irrespective of the stream editing deadline, if they are in the
|
||||||
// move_messages_between_streams_policy allows them to do so.
|
// can_move_messages_between_channels_group.
|
||||||
if (current_user.is_admin || current_user.is_moderator) {
|
if (current_user.is_admin || current_user.is_moderator) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,6 +212,7 @@ export function dispatch_normal_event(event) {
|
||||||
bot_creation_policy: settings_bots.update_bot_permissions_ui,
|
bot_creation_policy: settings_bots.update_bot_permissions_ui,
|
||||||
can_delete_any_message_group: noop,
|
can_delete_any_message_group: noop,
|
||||||
can_delete_own_message_group: noop,
|
can_delete_own_message_group: noop,
|
||||||
|
can_move_messages_between_channels_group: noop,
|
||||||
create_multiuse_invite_group: noop,
|
create_multiuse_invite_group: noop,
|
||||||
invite_to_stream_policy: noop,
|
invite_to_stream_policy: noop,
|
||||||
default_code_block_language: noop,
|
default_code_block_language: noop,
|
||||||
|
@ -233,7 +234,6 @@ export function dispatch_normal_event(event) {
|
||||||
move_messages_between_streams_limit_seconds: noop,
|
move_messages_between_streams_limit_seconds: noop,
|
||||||
move_messages_within_stream_limit_seconds: message_edit.update_inline_topic_edit_ui,
|
move_messages_within_stream_limit_seconds: message_edit.update_inline_topic_edit_ui,
|
||||||
message_retention_days: noop,
|
message_retention_days: noop,
|
||||||
move_messages_between_streams_policy: noop,
|
|
||||||
name: narrow_title.redraw_title,
|
name: narrow_title.redraw_title,
|
||||||
name_changes_disabled: settings_account.update_name_change_display,
|
name_changes_disabled: settings_account.update_name_change_display,
|
||||||
new_stream_announcements_stream_id: stream_ui_updates.update_announce_stream_option,
|
new_stream_announcements_stream_id: stream_ui_updates.update_announce_stream_option,
|
||||||
|
|
|
@ -238,7 +238,6 @@ export const simple_dropdown_realm_settings_schema = realm_schema.pick({
|
||||||
realm_invite_to_stream_policy: true,
|
realm_invite_to_stream_policy: true,
|
||||||
realm_invite_to_realm_policy: true,
|
realm_invite_to_realm_policy: true,
|
||||||
realm_wildcard_mention_policy: true,
|
realm_wildcard_mention_policy: true,
|
||||||
realm_move_messages_between_streams_policy: true,
|
|
||||||
realm_edit_topic_policy: true,
|
realm_edit_topic_policy: true,
|
||||||
realm_org_type: true,
|
realm_org_type: true,
|
||||||
});
|
});
|
||||||
|
@ -505,6 +504,7 @@ const dropdown_widget_map = new Map<string, DropdownWidget | null>([
|
||||||
["realm_can_delete_any_message_group", null],
|
["realm_can_delete_any_message_group", null],
|
||||||
["realm_can_delete_own_message_group", null],
|
["realm_can_delete_own_message_group", null],
|
||||||
["realm_can_manage_all_groups", null],
|
["realm_can_manage_all_groups", null],
|
||||||
|
["realm_can_move_messages_between_channels_group", null],
|
||||||
["realm_direct_message_initiator_group", null],
|
["realm_direct_message_initiator_group", null],
|
||||||
["realm_direct_message_permission_group", null],
|
["realm_direct_message_permission_group", null],
|
||||||
]);
|
]);
|
||||||
|
@ -827,6 +827,7 @@ export function check_realm_settings_property_changed(elem: HTMLElement): boolea
|
||||||
case "realm_can_delete_any_message_group":
|
case "realm_can_delete_any_message_group":
|
||||||
case "realm_can_delete_own_message_group":
|
case "realm_can_delete_own_message_group":
|
||||||
case "realm_can_manage_all_groups":
|
case "realm_can_manage_all_groups":
|
||||||
|
case "realm_can_move_messages_between_channels_group":
|
||||||
case "realm_direct_message_initiator_group":
|
case "realm_direct_message_initiator_group":
|
||||||
case "realm_direct_message_permission_group":
|
case "realm_direct_message_permission_group":
|
||||||
proposed_val = get_dropdown_list_widget_setting_value($elem);
|
proposed_val = get_dropdown_list_widget_setting_value($elem);
|
||||||
|
@ -1067,6 +1068,7 @@ export function populate_data_for_realm_settings_request(
|
||||||
"can_manage_all_groups",
|
"can_manage_all_groups",
|
||||||
"can_delete_any_message_group",
|
"can_delete_any_message_group",
|
||||||
"can_delete_own_message_group",
|
"can_delete_own_message_group",
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
"direct_message_initiator_group",
|
"direct_message_initiator_group",
|
||||||
"direct_message_permission_group",
|
"direct_message_permission_group",
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -348,8 +348,6 @@ export const edit_topic_policy_values = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const move_messages_between_streams_policy_values = email_invite_to_realm_policy_values;
|
|
||||||
|
|
||||||
export const time_limit_dropdown_values = [
|
export const time_limit_dropdown_values = [
|
||||||
{
|
{
|
||||||
text: $t({defaultMessage: "Any time"}),
|
text: $t({defaultMessage: "Any time"}),
|
||||||
|
|
|
@ -176,7 +176,11 @@ export function user_can_create_web_public_streams(): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function user_can_move_messages_between_streams(): boolean {
|
export function user_can_move_messages_between_streams(): boolean {
|
||||||
return user_has_permission(realm.realm_move_messages_between_streams_policy);
|
return user_has_permission_for_group_setting(
|
||||||
|
realm.realm_can_move_messages_between_channels_group,
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
"realm",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function user_can_manage_all_groups(): boolean {
|
export function user_can_manage_all_groups(): boolean {
|
||||||
|
|
|
@ -111,7 +111,6 @@ type OrganizationSettingsOptions = {
|
||||||
common_message_policy_values: SettingOptionValueWithKey[];
|
common_message_policy_values: SettingOptionValueWithKey[];
|
||||||
invite_to_realm_policy_values: SettingOptionValueWithKey[];
|
invite_to_realm_policy_values: SettingOptionValueWithKey[];
|
||||||
edit_topic_policy_values: SettingOptionValueWithKey[];
|
edit_topic_policy_values: SettingOptionValueWithKey[];
|
||||||
move_messages_between_streams_policy_values: SettingOptionValueWithKey[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function get_organization_settings_options(): OrganizationSettingsOptions {
|
export function get_organization_settings_options(): OrganizationSettingsOptions {
|
||||||
|
@ -131,9 +130,6 @@ export function get_organization_settings_options(): OrganizationSettingsOptions
|
||||||
edit_topic_policy_values: settings_components.get_sorted_options_list(
|
edit_topic_policy_values: settings_components.get_sorted_options_list(
|
||||||
settings_config.edit_topic_policy_values,
|
settings_config.edit_topic_policy_values,
|
||||||
),
|
),
|
||||||
move_messages_between_streams_policy_values: settings_components.get_sorted_options_list(
|
|
||||||
settings_config.move_messages_between_streams_policy_values,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,30 +227,38 @@ function set_msg_edit_limit_dropdown(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function message_move_limit_setting_enabled(
|
function message_move_limit_setting_enabled(
|
||||||
related_setting_name: "realm_edit_topic_policy" | "realm_move_messages_between_streams_policy",
|
related_setting_name:
|
||||||
|
| "realm_edit_topic_policy"
|
||||||
|
| "realm_can_move_messages_between_channels_group",
|
||||||
): boolean {
|
): boolean {
|
||||||
const setting_value_string = $<HTMLSelectOneElement>(
|
|
||||||
`select:not(multiple)#id_${CSS.escape(related_setting_name)}`,
|
|
||||||
).val();
|
|
||||||
assert(setting_value_string !== undefined);
|
|
||||||
const setting_value = Number.parseInt(setting_value_string, 10);
|
|
||||||
|
|
||||||
let settings_options;
|
|
||||||
if (related_setting_name === "realm_edit_topic_policy") {
|
if (related_setting_name === "realm_edit_topic_policy") {
|
||||||
settings_options = settings_config.edit_topic_policy_values;
|
const setting_value_string = $<HTMLSelectOneElement>(
|
||||||
} else {
|
`select:not(multiple)#id_${CSS.escape(related_setting_name)}`,
|
||||||
settings_options = settings_config.move_messages_between_streams_policy_values;
|
).val();
|
||||||
}
|
assert(setting_value_string !== undefined);
|
||||||
|
const setting_value = Number.parseInt(setting_value_string, 10);
|
||||||
|
const settings_options = settings_config.edit_topic_policy_values;
|
||||||
|
|
||||||
if (setting_value === settings_options.by_admins_only.code) {
|
if (
|
||||||
return false;
|
setting_value === settings_options.by_admins_only.code ||
|
||||||
}
|
setting_value === settings_options.by_moderators_only.code ||
|
||||||
|
setting_value === settings_options.nobody.code
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (setting_value === settings_options.by_moderators_only.code) {
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
const user_group_id = settings_components.get_dropdown_list_widget_setting_value(
|
||||||
if (setting_value === settings_options.nobody.code) {
|
$(`#id_${related_setting_name}`),
|
||||||
|
);
|
||||||
|
assert(typeof user_group_id === "number");
|
||||||
|
const user_group_name = user_groups.get_user_group_from_id(user_group_id).name;
|
||||||
|
if (
|
||||||
|
user_group_name === "role:administrators" ||
|
||||||
|
user_group_name === "role:moderators" ||
|
||||||
|
user_group_name === "role:nobody"
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +284,7 @@ function set_msg_move_limit_setting(property_name: MessageMoveTimeLimitSetting):
|
||||||
disable_setting = message_move_limit_setting_enabled("realm_edit_topic_policy");
|
disable_setting = message_move_limit_setting_enabled("realm_edit_topic_policy");
|
||||||
} else {
|
} else {
|
||||||
disable_setting = message_move_limit_setting_enabled(
|
disable_setting = message_move_limit_setting_enabled(
|
||||||
"realm_move_messages_between_streams_policy",
|
"realm_can_move_messages_between_channels_group",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
enable_or_disable_related_message_move_time_limit_setting(property_name, disable_setting);
|
enable_or_disable_related_message_move_time_limit_setting(property_name, disable_setting);
|
||||||
|
@ -499,6 +503,9 @@ function update_dependent_subsettings(property_name: string): void {
|
||||||
case "realm_can_delete_own_message_group":
|
case "realm_can_delete_own_message_group":
|
||||||
check_disable_message_delete_limit_setting_dropdown();
|
check_disable_message_delete_limit_setting_dropdown();
|
||||||
break;
|
break;
|
||||||
|
case "realm_can_move_messages_between_channels_group":
|
||||||
|
set_msg_move_limit_setting("realm_move_messages_between_streams_limit_seconds");
|
||||||
|
break;
|
||||||
case "realm_org_join_restrictions":
|
case "realm_org_join_restrictions":
|
||||||
set_org_join_restrictions_dropdown();
|
set_org_join_restrictions_dropdown();
|
||||||
break;
|
break;
|
||||||
|
@ -556,6 +563,7 @@ export function discard_realm_property_element_changes(elem: HTMLElement): void
|
||||||
case "realm_can_delete_any_message_group":
|
case "realm_can_delete_any_message_group":
|
||||||
case "realm_can_delete_own_message_group":
|
case "realm_can_delete_own_message_group":
|
||||||
case "realm_can_manage_all_groups":
|
case "realm_can_manage_all_groups":
|
||||||
|
case "realm_can_move_messages_between_channels_group":
|
||||||
assert(typeof property_value === "string" || typeof property_value === "number");
|
assert(typeof property_value === "string" || typeof property_value === "number");
|
||||||
settings_components.set_dropdown_list_widget_setting_value(
|
settings_components.set_dropdown_list_widget_setting_value(
|
||||||
property_name,
|
property_name,
|
||||||
|
@ -914,18 +922,32 @@ export function set_up_dropdown_widget_for_realm_group_settings(): void {
|
||||||
let dropdown_list_item_click_callback:
|
let dropdown_list_item_click_callback:
|
||||||
| ((current_value: string | number | undefined) => void)
|
| ((current_value: string | number | undefined) => void)
|
||||||
| undefined;
|
| undefined;
|
||||||
if (setting_name === "direct_message_permission_group") {
|
switch (setting_name) {
|
||||||
dropdown_list_item_click_callback = (
|
case "direct_message_permission_group": {
|
||||||
current_value: string | number | undefined,
|
dropdown_list_item_click_callback = (
|
||||||
): void => {
|
current_value: string | number | undefined,
|
||||||
assert(typeof current_value === "number");
|
): void => {
|
||||||
check_disable_direct_message_initiator_group_dropdown(current_value);
|
assert(typeof current_value === "number");
|
||||||
};
|
check_disable_direct_message_initiator_group_dropdown(current_value);
|
||||||
} else if (
|
};
|
||||||
setting_name === "can_delete_any_message_group" ||
|
|
||||||
setting_name === "can_delete_own_message_group"
|
break;
|
||||||
) {
|
}
|
||||||
dropdown_list_item_click_callback = check_disable_message_delete_limit_setting_dropdown;
|
case "can_delete_any_message_group":
|
||||||
|
case "can_delete_own_message_group": {
|
||||||
|
dropdown_list_item_click_callback =
|
||||||
|
check_disable_message_delete_limit_setting_dropdown;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "can_move_messages_between_channels_group": {
|
||||||
|
dropdown_list_item_click_callback = () => {
|
||||||
|
set_msg_move_limit_setting("realm_move_messages_between_streams_limit_seconds");
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// No default
|
||||||
}
|
}
|
||||||
|
|
||||||
set_up_dropdown_widget(
|
set_up_dropdown_widget(
|
||||||
|
@ -1224,7 +1246,7 @@ export function build_page(): void {
|
||||||
function (this: HTMLElement) {
|
function (this: HTMLElement) {
|
||||||
const $policy_dropdown_elem = $(this);
|
const $policy_dropdown_elem = $(this);
|
||||||
const property_name = z
|
const property_name = z
|
||||||
.enum(["realm_edit_topic_policy", "realm_move_messages_between_streams_policy"])
|
.enum(["realm_edit_topic_policy", "realm_can_move_messages_between_channels_group"])
|
||||||
.parse(settings_components.extract_property_name($policy_dropdown_elem));
|
.parse(settings_components.extract_property_name($policy_dropdown_elem));
|
||||||
const disable_time_limit_setting = message_move_limit_setting_enabled(property_name);
|
const disable_time_limit_setting = message_move_limit_setting_enabled(property_name);
|
||||||
|
|
||||||
|
|
|
@ -295,6 +295,7 @@ export const realm_schema = z.object({
|
||||||
realm_can_delete_any_message_group: z.number(),
|
realm_can_delete_any_message_group: z.number(),
|
||||||
realm_can_delete_own_message_group: z.number(),
|
realm_can_delete_own_message_group: z.number(),
|
||||||
realm_can_manage_all_groups: z.number(),
|
realm_can_manage_all_groups: z.number(),
|
||||||
|
realm_can_move_messages_between_channels_group: z.number(),
|
||||||
realm_create_multiuse_invite_group: z.number(),
|
realm_create_multiuse_invite_group: z.number(),
|
||||||
realm_date_created: z.number(),
|
realm_date_created: z.number(),
|
||||||
realm_default_code_block_language: z.string(),
|
realm_default_code_block_language: z.string(),
|
||||||
|
@ -366,7 +367,6 @@ export const realm_schema = z.object({
|
||||||
realm_message_content_delete_limit_seconds: z.number().nullable(),
|
realm_message_content_delete_limit_seconds: z.number().nullable(),
|
||||||
realm_message_retention_days: z.number(),
|
realm_message_retention_days: z.number(),
|
||||||
realm_move_messages_between_streams_limit_seconds: z.number().nullable(),
|
realm_move_messages_between_streams_limit_seconds: z.number().nullable(),
|
||||||
realm_move_messages_between_streams_policy: z.number(),
|
|
||||||
realm_move_messages_within_stream_limit_seconds: z.number().nullable(),
|
realm_move_messages_within_stream_limit_seconds: z.number().nullable(),
|
||||||
realm_name_changes_disabled: z.boolean(),
|
realm_name_changes_disabled: z.boolean(),
|
||||||
realm_name: z.string(),
|
realm_name: z.string(),
|
||||||
|
|
|
@ -354,7 +354,7 @@ export async function build_move_topic_to_stream_popover(
|
||||||
|
|
||||||
// When the modal is opened for moving the whole topic from left sidebar,
|
// When the modal is opened for moving the whole topic from left sidebar,
|
||||||
// we do not have any message object and so we disable the stream input
|
// we do not have any message object and so we disable the stream input
|
||||||
// based on the move_messages_between_streams_policy setting and topic
|
// based on the can_move_messages_between_channels_group setting and topic
|
||||||
// input based on edit_topic_policy. In other cases, message object is
|
// input based on edit_topic_policy. In other cases, message object is
|
||||||
// available and thus we check the time-based permissions as well in the
|
// available and thus we check the time-based permissions as well in the
|
||||||
// below if block to enable or disable the stream and topic input.
|
// below if block to enable or disable the stream and topic input.
|
||||||
|
|
|
@ -201,13 +201,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group">
|
{{> ../dropdown_widget_with_label
|
||||||
<label for="realm_move_messages_between_streams_policy" class="settings-field-label">{{t "Who can move messages to another channel" }}
|
widget_name="realm_can_move_messages_between_channels_group"
|
||||||
</label>
|
label=(t 'Who can move messages to another channel')
|
||||||
<select name="realm_move_messages_between_streams_policy" class="setting-widget prop-element bootstrap-focus-style move-message-policy-setting settings_select" id="id_realm_move_messages_between_streams_policy" data-setting-widget-type="number">
|
value_type="number" }}
|
||||||
{{> dropdown_options_widget option_values=move_messages_between_streams_policy_values}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group time-limit-setting">
|
<div class="input-group time-limit-setting">
|
||||||
<label for="realm_move_messages_between_streams_limit_seconds" class="settings-field-label">{{t "Time limit for moving messages between channels" }} <i>({{t "does not apply to moderators and administrators" }})</i></label>
|
<label for="realm_move_messages_between_streams_limit_seconds" class="settings-field-label">{{t "Time limit for moving messages between channels" }} <i>({{t "does not apply to moderators and administrators" }})</i></label>
|
||||||
|
|
|
@ -162,11 +162,6 @@ test_policy(
|
||||||
"realm_invite_to_realm_policy",
|
"realm_invite_to_realm_policy",
|
||||||
settings_data.user_can_invite_users_by_email,
|
settings_data.user_can_invite_users_by_email,
|
||||||
);
|
);
|
||||||
test_policy(
|
|
||||||
"user_can_move_messages_between_streams",
|
|
||||||
"realm_move_messages_between_streams_policy",
|
|
||||||
settings_data.user_can_move_messages_between_streams,
|
|
||||||
);
|
|
||||||
|
|
||||||
function test_message_policy(label, policy, validation_func) {
|
function test_message_policy(label, policy, validation_func) {
|
||||||
run_test(label, ({override}) => {
|
run_test(label, ({override}) => {
|
||||||
|
@ -228,17 +223,6 @@ run_test("user_can_move_messages_to_another_topic_nobody_case", ({override}) =>
|
||||||
assert.equal(settings_data.user_can_move_messages_to_another_topic(), false);
|
assert.equal(settings_data.user_can_move_messages_to_another_topic(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test("user_can_move_messages_between_streams_nobody_case", ({override}) => {
|
|
||||||
override(current_user, "is_admin", true);
|
|
||||||
override(current_user, "is_guest", false);
|
|
||||||
override(
|
|
||||||
realm,
|
|
||||||
"realm_move_messages_between_streams_policy",
|
|
||||||
settings_config.move_messages_between_streams_policy_values.nobody.code,
|
|
||||||
);
|
|
||||||
assert.equal(settings_data.user_can_move_messages_between_streams(), false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test_realm_group_settings(
|
test_realm_group_settings(
|
||||||
"realm_can_add_custom_emoji_group",
|
"realm_can_add_custom_emoji_group",
|
||||||
settings_data.user_can_add_custom_emoji,
|
settings_data.user_can_add_custom_emoji,
|
||||||
|
@ -254,6 +238,11 @@ test_realm_group_settings(
|
||||||
settings_data.user_can_delete_own_message,
|
settings_data.user_can_delete_own_message,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_realm_group_settings(
|
||||||
|
"realm_can_move_messages_between_channels_group",
|
||||||
|
settings_data.user_can_move_messages_between_streams,
|
||||||
|
);
|
||||||
|
|
||||||
run_test("using_dark_theme", ({override}) => {
|
run_test("using_dark_theme", ({override}) => {
|
||||||
override(user_settings, "color_scheme", settings_config.color_scheme_values.dark.code);
|
override(user_settings, "color_scheme", settings_config.color_scheme_values.dark.code);
|
||||||
assert.equal(settings_data.using_dark_theme(), true);
|
assert.equal(settings_data.using_dark_theme(), true);
|
||||||
|
|
|
@ -506,6 +506,7 @@ function test_discard_changes_button({override}, discard_changes) {
|
||||||
|
|
||||||
test("set_up", ({override, override_rewire}) => {
|
test("set_up", ({override, override_rewire}) => {
|
||||||
override_rewire(settings_org, "check_disable_message_delete_limit_setting_dropdown", noop);
|
override_rewire(settings_org, "check_disable_message_delete_limit_setting_dropdown", noop);
|
||||||
|
override_rewire(settings_org, "message_move_limit_setting_enabled", noop);
|
||||||
override(realm, "realm_available_video_chat_providers", {
|
override(realm, "realm_available_video_chat_providers", {
|
||||||
jitsi_meet: {
|
jitsi_meet: {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
|
@ -41,7 +41,6 @@ from zerver.models.realm_audit_logs import AuditLogEventType
|
||||||
from zerver.models.realms import (
|
from zerver.models.realms import (
|
||||||
CommonPolicyEnum,
|
CommonPolicyEnum,
|
||||||
InviteToRealmPolicyEnum,
|
InviteToRealmPolicyEnum,
|
||||||
MoveMessagesBetweenStreamsPolicyEnum,
|
|
||||||
get_org_type_display_name,
|
get_org_type_display_name,
|
||||||
get_realm,
|
get_realm,
|
||||||
)
|
)
|
||||||
|
@ -125,10 +124,6 @@ def set_realm_permissions_based_on_org_type(realm: Realm) -> None:
|
||||||
# Don't allow members (students) to manage user groups or
|
# Don't allow members (students) to manage user groups or
|
||||||
# stream subscriptions.
|
# stream subscriptions.
|
||||||
realm.invite_to_stream_policy = CommonPolicyEnum.MODERATORS_ONLY
|
realm.invite_to_stream_policy = CommonPolicyEnum.MODERATORS_ONLY
|
||||||
# Allow moderators (TAs?) to move topics between streams.
|
|
||||||
realm.move_messages_between_streams_policy = (
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MODERATORS_ONLY
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic(savepoint=False)
|
@transaction.atomic(savepoint=False)
|
||||||
|
@ -299,6 +294,10 @@ def do_create_realm(
|
||||||
Realm.ORG_TYPES["education_nonprofit"]["id"]: SystemGroups.MODERATORS,
|
Realm.ORG_TYPES["education_nonprofit"]["id"]: SystemGroups.MODERATORS,
|
||||||
Realm.ORG_TYPES["education"]["id"]: SystemGroups.MODERATORS,
|
Realm.ORG_TYPES["education"]["id"]: SystemGroups.MODERATORS,
|
||||||
},
|
},
|
||||||
|
"can_move_messages_between_channels_group": {
|
||||||
|
Realm.ORG_TYPES["education_nonprofit"]["id"]: SystemGroups.MODERATORS,
|
||||||
|
Realm.ORG_TYPES["education"]["id"]: SystemGroups.MODERATORS,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
set_default_for_realm_permission_group_settings(
|
set_default_for_realm_permission_group_settings(
|
||||||
realm, group_settings_defaults_for_org_types
|
realm, group_settings_defaults_for_org_types
|
||||||
|
|
|
@ -1067,6 +1067,7 @@ group_setting_update_data_type = DictType(
|
||||||
("can_delete_any_message_group", group_setting_type),
|
("can_delete_any_message_group", group_setting_type),
|
||||||
("can_delete_own_message_group", group_setting_type),
|
("can_delete_own_message_group", group_setting_type),
|
||||||
("can_manage_all_groups", group_setting_type),
|
("can_manage_all_groups", group_setting_type),
|
||||||
|
("can_move_messages_between_channels_group", group_setting_type),
|
||||||
("direct_message_initiator_group", group_setting_type),
|
("direct_message_initiator_group", group_setting_type),
|
||||||
("direct_message_permission_group", group_setting_type),
|
("direct_message_permission_group", group_setting_type),
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 5.0.9 on 2024-10-12 13:48
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("zerver", "0610_mark_introduce_resolve_topic_modal_as_read"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="realm",
|
||||||
|
name="can_move_messages_between_channels_group",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.RESTRICT,
|
||||||
|
related_name="+",
|
||||||
|
to="zerver.usergroup",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Generated by Django 4.2.1 on 2023-06-12 10:47
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||||
|
from django.db.migrations.state import StateApps
|
||||||
|
from django.db.models import OuterRef
|
||||||
|
|
||||||
|
|
||||||
|
def set_default_value_for_can_move_messages_between_channels_group(
|
||||||
|
apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
|
||||||
|
) -> None:
|
||||||
|
Realm = apps.get_model("zerver", "Realm")
|
||||||
|
NamedUserGroup = apps.get_model("zerver", "NamedUserGroup")
|
||||||
|
|
||||||
|
move_messages_between_streams_policy_to_group_name = {
|
||||||
|
1: "role:members",
|
||||||
|
2: "role:administrators",
|
||||||
|
3: "role:fullmembers",
|
||||||
|
4: "role:moderators",
|
||||||
|
6: "role:nobody",
|
||||||
|
}
|
||||||
|
|
||||||
|
for id, group_name in move_messages_between_streams_policy_to_group_name.items():
|
||||||
|
Realm.objects.filter(
|
||||||
|
can_move_messages_between_channels_group=None, move_messages_between_streams_policy=id
|
||||||
|
).update(
|
||||||
|
can_move_messages_between_channels_group=NamedUserGroup.objects.filter(
|
||||||
|
name=group_name, realm=OuterRef("id"), is_system_group=True
|
||||||
|
).values("pk")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
atomic = False
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("zerver", "0611_realm_can_move_messages_between_channels_group"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(
|
||||||
|
set_default_value_for_can_move_messages_between_channels_group,
|
||||||
|
elidable=True,
|
||||||
|
reverse_code=migrations.RunPython.noop,
|
||||||
|
)
|
||||||
|
]
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 5.0.9 on 2024-10-12 13:54
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("zerver", "0612_set_default_value_for_can_move_messages_between_channels_group"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="realm",
|
||||||
|
name="can_move_messages_between_channels_group",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.RESTRICT,
|
||||||
|
related_name="+",
|
||||||
|
to="zerver.usergroup",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -359,6 +359,11 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub
|
||||||
default=POLICY_MEMBERS_ONLY
|
default=POLICY_MEMBERS_ONLY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# UserGroup which is allowed to move messages between streams.
|
||||||
|
can_move_messages_between_channels_group = models.ForeignKey(
|
||||||
|
"UserGroup", on_delete=models.RESTRICT, related_name="+"
|
||||||
|
)
|
||||||
|
|
||||||
# Global policy for who is allowed to use wildcard mentions in
|
# Global policy for who is allowed to use wildcard mentions in
|
||||||
# streams with a large number of subscribers. Anyone can use
|
# streams with a large number of subscribers. Anyone can use
|
||||||
# wildcard mentions in small streams regardless of this setting.
|
# wildcard mentions in small streams regardless of this setting.
|
||||||
|
@ -781,6 +786,15 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub
|
||||||
default_group_name=SystemGroups.OWNERS,
|
default_group_name=SystemGroups.OWNERS,
|
||||||
id_field_name="can_manage_all_groups_id",
|
id_field_name="can_manage_all_groups_id",
|
||||||
),
|
),
|
||||||
|
can_move_messages_between_channels_group=GroupPermissionSetting(
|
||||||
|
require_system_group=not settings.ALLOW_GROUP_VALUED_SETTINGS,
|
||||||
|
allow_internet_group=False,
|
||||||
|
allow_owners_group=False,
|
||||||
|
allow_nobody_group=True,
|
||||||
|
allow_everyone_group=False,
|
||||||
|
default_group_name=SystemGroups.MEMBERS,
|
||||||
|
id_field_name="can_move_messages_between_channels_group_id",
|
||||||
|
),
|
||||||
direct_message_initiator_group=GroupPermissionSetting(
|
direct_message_initiator_group=GroupPermissionSetting(
|
||||||
require_system_group=not settings.ALLOW_GROUP_VALUED_SETTINGS,
|
require_system_group=not settings.ALLOW_GROUP_VALUED_SETTINGS,
|
||||||
allow_internet_group=False,
|
allow_internet_group=False,
|
||||||
|
@ -810,6 +824,7 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub
|
||||||
"can_delete_any_message_group",
|
"can_delete_any_message_group",
|
||||||
"can_delete_own_message_group",
|
"can_delete_own_message_group",
|
||||||
"can_manage_all_groups",
|
"can_manage_all_groups",
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
"direct_message_initiator_group",
|
"direct_message_initiator_group",
|
||||||
"direct_message_permission_group",
|
"direct_message_permission_group",
|
||||||
]
|
]
|
||||||
|
@ -1206,6 +1221,8 @@ def get_realm_with_settings(realm_id: int) -> Realm:
|
||||||
"can_delete_own_message_group__named_user_group",
|
"can_delete_own_message_group__named_user_group",
|
||||||
"can_manage_all_groups",
|
"can_manage_all_groups",
|
||||||
"can_manage_all_groups__named_user_group",
|
"can_manage_all_groups__named_user_group",
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
"can_move_messages_between_channels_group__named_user_group",
|
||||||
"direct_message_initiator_group",
|
"direct_message_initiator_group",
|
||||||
"direct_message_initiator_group__named_user_group",
|
"direct_message_initiator_group__named_user_group",
|
||||||
"direct_message_permission_group",
|
"direct_message_permission_group",
|
||||||
|
|
|
@ -823,6 +823,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin, UserBaseSettings):
|
||||||
"can_delete_any_message_group",
|
"can_delete_any_message_group",
|
||||||
"can_delete_own_message_group",
|
"can_delete_own_message_group",
|
||||||
"can_manage_all_groups",
|
"can_manage_all_groups",
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
"create_multiuse_invite_group",
|
"create_multiuse_invite_group",
|
||||||
"direct_message_initiator_group",
|
"direct_message_initiator_group",
|
||||||
"direct_message_permission_group",
|
"direct_message_permission_group",
|
||||||
|
@ -898,7 +899,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin, UserBaseSettings):
|
||||||
return self.has_permission("create_multiuse_invite_group")
|
return self.has_permission("create_multiuse_invite_group")
|
||||||
|
|
||||||
def can_move_messages_between_streams(self) -> bool:
|
def can_move_messages_between_streams(self) -> bool:
|
||||||
return self.has_permission("move_messages_between_streams_policy")
|
return self.has_permission("can_move_messages_between_channels_group")
|
||||||
|
|
||||||
def can_create_user_groups(self) -> bool:
|
def can_create_user_groups(self) -> bool:
|
||||||
return self.has_permission("can_create_groups")
|
return self.has_permission("can_create_groups")
|
||||||
|
|
|
@ -4457,6 +4457,20 @@ paths:
|
||||||
setting controlled this permission; `true` corresponded to `Everyone`, and
|
setting controlled this permission; `true` corresponded to `Everyone`, and
|
||||||
`false` to `Admins`.
|
`false` to `Admins`.
|
||||||
- $ref: "#/components/schemas/GroupSettingValue"
|
- $ref: "#/components/schemas/GroupSettingValue"
|
||||||
|
can_move_messages_between_channels_group:
|
||||||
|
allOf:
|
||||||
|
- description: |
|
||||||
|
A [group-setting value](/api/group-setting-values) defining the set of
|
||||||
|
users who have permission to move messages from one channel to another
|
||||||
|
in the organization.
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 10.0 (feature level 310). Previously, this
|
||||||
|
permission was controlled by the enum `move_messages_between_streams_policy`.
|
||||||
|
Values were 1=Members, 2=Admins, 3=Full members, 4=Moderators, 6=Nobody.
|
||||||
|
|
||||||
|
In Zulip 7.0 (feature level 159), `Nobody` was added as an option to
|
||||||
|
`move_messages_between_streams_policy` enum.
|
||||||
|
- $ref: "#/components/schemas/GroupSettingValue"
|
||||||
can_manage_all_groups:
|
can_manage_all_groups:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: "#/components/schemas/GroupSettingValue"
|
- $ref: "#/components/schemas/GroupSettingValue"
|
||||||
|
@ -8265,8 +8279,8 @@ paths:
|
||||||
linked documentation on when users are allowed to update messages are:
|
linked documentation on when users are allowed to update messages are:
|
||||||
|
|
||||||
- `allow_message_editing`
|
- `allow_message_editing`
|
||||||
|
- `can_move_messages_between_channels_group`
|
||||||
- `edit_topic_policy`
|
- `edit_topic_policy`
|
||||||
- `move_messages_between_streams_policy`
|
|
||||||
- `message_content_edit_limit_seconds`
|
- `message_content_edit_limit_seconds`
|
||||||
- `move_messages_within_stream_limit_seconds`
|
- `move_messages_within_stream_limit_seconds`
|
||||||
- `move_messages_between_streams_limit_seconds`
|
- `move_messages_between_streams_limit_seconds`
|
||||||
|
@ -8276,7 +8290,11 @@ paths:
|
||||||
of the [`realm op: update_dict`](/api/get-events#realm-update_dict)
|
of the [`realm op: update_dict`](/api/get-events#realm-update_dict)
|
||||||
event in [`GET /events`](/api/get-events).
|
event in [`GET /events`](/api/get-events).
|
||||||
|
|
||||||
**Changes**: Prior to Zulip 7.0 (feature level 172), anyone could add a
|
**Changes**: In Zulip 10.0 (feature level 310), `move_messages_between_streams_policy`
|
||||||
|
was removed and replaced by `can_move_messages_between_channels_group`
|
||||||
|
realm setting.
|
||||||
|
|
||||||
|
Prior to Zulip 7.0 (feature level 172), anyone could add a
|
||||||
topic to channel messages without a topic, regardless of the organization's
|
topic to channel messages without a topic, regardless of the organization's
|
||||||
[topic editing permissions](/help/restrict-moving-messages). As of this
|
[topic editing permissions](/help/restrict-moving-messages). As of this
|
||||||
feature level, messages without topics have the same restrictions for
|
feature level, messages without topics have the same restrictions for
|
||||||
|
@ -16281,6 +16299,22 @@ paths:
|
||||||
setting controlled this permission; `true` corresponded to `Everyone`, and
|
setting controlled this permission; `true` corresponded to `Everyone`, and
|
||||||
`false` to `Admins`.
|
`false` to `Admins`.
|
||||||
- $ref: "#/components/schemas/GroupSettingValue"
|
- $ref: "#/components/schemas/GroupSettingValue"
|
||||||
|
realm_can_move_messages_between_channels_group:
|
||||||
|
allOf:
|
||||||
|
- description: |
|
||||||
|
Present if `realm` is present in `fetch_event_types`.
|
||||||
|
|
||||||
|
A [group-setting value](/api/group-setting-values) defining the set of
|
||||||
|
users who have permission to move messages from one channel to another
|
||||||
|
in the organization.
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 10.0 (feature level 310). Previously, this
|
||||||
|
permission was controlled by the enum `move_messages_between_streams_policy`.
|
||||||
|
Values were 1=Members, 2=Admins, 3=Full members, 4=Moderators, 6=Nobody.
|
||||||
|
|
||||||
|
In Zulip 7.0 (feature level 159), `Nobody` was added as an option to
|
||||||
|
`move_messages_between_streams_policy` enum.
|
||||||
|
- $ref: "#/components/schemas/GroupSettingValue"
|
||||||
realm_bot_creation_policy:
|
realm_bot_creation_policy:
|
||||||
type: integer
|
type: integer
|
||||||
description: |
|
description: |
|
||||||
|
|
|
@ -137,6 +137,7 @@ class HomeTest(ZulipTestCase):
|
||||||
"realm_can_delete_any_message_group",
|
"realm_can_delete_any_message_group",
|
||||||
"realm_can_delete_own_message_group",
|
"realm_can_delete_own_message_group",
|
||||||
"realm_can_manage_all_groups",
|
"realm_can_manage_all_groups",
|
||||||
|
"realm_can_move_messages_between_channels_group",
|
||||||
"realm_create_multiuse_invite_group",
|
"realm_create_multiuse_invite_group",
|
||||||
"realm_create_private_stream_policy",
|
"realm_create_private_stream_policy",
|
||||||
"realm_create_public_stream_policy",
|
"realm_create_public_stream_policy",
|
||||||
|
|
|
@ -2,19 +2,21 @@ from datetime import timedelta
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
|
|
||||||
from zerver.actions.realm_settings import do_set_realm_property
|
from zerver.actions.message_delete import do_delete_messages
|
||||||
|
from zerver.actions.realm_settings import (
|
||||||
|
do_change_realm_permission_group_setting,
|
||||||
|
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.user_groups import check_add_user_group
|
||||||
from zerver.actions.users import do_change_user_role
|
from zerver.actions.users import do_change_user_role
|
||||||
from zerver.lib.message import has_message_access
|
from zerver.lib.message import has_message_access
|
||||||
from zerver.lib.test_classes import ZulipTestCase, get_topic_messages
|
from zerver.lib.test_classes import ZulipTestCase, get_topic_messages
|
||||||
from zerver.lib.test_helpers import queries_captured
|
from zerver.lib.test_helpers import queries_captured
|
||||||
from zerver.lib.url_encoding import near_stream_message_url
|
from zerver.lib.url_encoding import near_stream_message_url
|
||||||
from zerver.models import Message, Stream, UserMessage, UserProfile
|
from zerver.models import Message, NamedUserGroup, Stream, UserMessage, UserProfile
|
||||||
from zerver.models.realms import (
|
from zerver.models.groups import SystemGroups
|
||||||
EditTopicPolicyEnum,
|
from zerver.models.realms import EditTopicPolicyEnum, get_realm
|
||||||
MoveMessagesBetweenStreamsPolicyEnum,
|
|
||||||
get_realm,
|
|
||||||
)
|
|
||||||
from zerver.models.streams import get_stream
|
from zerver.models.streams import get_stream
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,8 +51,18 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
user_profile.save(update_fields=["default_language"])
|
user_profile.save(update_fields=["default_language"])
|
||||||
|
|
||||||
self.login(user_email)
|
self.login(user_email)
|
||||||
stream = self.make_stream(old_stream)
|
try:
|
||||||
stream_to = self.make_stream(new_stream)
|
stream = get_stream(old_stream, user_profile.realm)
|
||||||
|
messages = get_topic_messages(user_profile, stream, "test")
|
||||||
|
do_delete_messages(user_profile.realm, messages, acting_user=None)
|
||||||
|
except Stream.DoesNotExist:
|
||||||
|
stream = self.make_stream(old_stream)
|
||||||
|
try:
|
||||||
|
stream_to = get_stream(new_stream, user_profile.realm)
|
||||||
|
messages = get_topic_messages(user_profile, stream_to, "test")
|
||||||
|
do_delete_messages(user_profile.realm, messages, acting_user=None)
|
||||||
|
except Stream.DoesNotExist:
|
||||||
|
stream_to = self.make_stream(new_stream)
|
||||||
self.subscribe(user_profile, stream.name)
|
self.subscribe(user_profile, stream.name)
|
||||||
self.subscribe(user_profile, stream_to.name)
|
self.subscribe(user_profile, stream_to.name)
|
||||||
msg_id = self.send_stream_message(
|
msg_id = self.send_stream_message(
|
||||||
|
@ -104,16 +116,21 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
|
|
||||||
def test_change_all_propagate_mode_for_moving_old_messages(self) -> None:
|
def test_change_all_propagate_mode_for_moving_old_messages(self) -> None:
|
||||||
user_profile = self.example_user("hamlet")
|
user_profile = self.example_user("hamlet")
|
||||||
|
realm = user_profile.realm
|
||||||
id1 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
id1 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
||||||
id2 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
id2 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
||||||
id3 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
id3 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
||||||
id4 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
id4 = self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
||||||
self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
self.send_stream_message(user_profile, "Denmark", topic_name="topic1")
|
||||||
|
|
||||||
do_set_realm_property(
|
members_system_group = NamedUserGroup.objects.get(
|
||||||
user_profile.realm,
|
name=SystemGroups.MEMBERS, realm=realm, is_system_group=True
|
||||||
"move_messages_between_streams_policy",
|
)
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MEMBERS_ONLY,
|
|
||||||
|
do_change_realm_permission_group_setting(
|
||||||
|
realm,
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
members_system_group,
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -784,13 +801,16 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_move_message_between_streams_policy_setting(self) -> None:
|
def test_move_message_between_streams_policy_setting(self) -> None:
|
||||||
(user_profile, old_stream, new_stream, msg_id, msg_id_later) = self.prepare_move_topics(
|
othello = self.example_user("othello")
|
||||||
"othello", "old_stream_1", "new_stream_1", "test"
|
cordelia = self.example_user("cordelia")
|
||||||
)
|
realm = othello.realm
|
||||||
|
|
||||||
def check_move_message_according_to_policy(role: int, expect_fail: bool = False) -> None:
|
|
||||||
do_change_user_role(user_profile, role, acting_user=None)
|
|
||||||
|
|
||||||
|
def check_move_message_according_to_permission(
|
||||||
|
username: str, expect_fail: bool = False
|
||||||
|
) -> None:
|
||||||
|
(user_profile, old_stream, new_stream, msg_id, msg_id_later) = self.prepare_move_topics(
|
||||||
|
username, "old_stream", "new_stream", "test"
|
||||||
|
)
|
||||||
result = self.client_patch(
|
result = self.client_patch(
|
||||||
"/json/messages/" + str(msg_id),
|
"/json/messages/" + str(msg_id),
|
||||||
{
|
{
|
||||||
|
@ -812,77 +832,117 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
messages = get_topic_messages(user_profile, new_stream, "test")
|
messages = get_topic_messages(user_profile, new_stream, "test")
|
||||||
self.assert_length(messages, 4)
|
self.assert_length(messages, 4)
|
||||||
|
|
||||||
# Check sending messages when policy is MoveMessagesBetweenStreamsPolicyEnum.NOBODY.
|
administrators_system_group = NamedUserGroup.objects.get(
|
||||||
do_set_realm_property(
|
name=SystemGroups.ADMINISTRATORS, realm=realm, is_system_group=True
|
||||||
user_profile.realm,
|
|
||||||
"move_messages_between_streams_policy",
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.NOBODY,
|
|
||||||
acting_user=None,
|
|
||||||
)
|
)
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_REALM_OWNER, expect_fail=True)
|
full_members_system_group = NamedUserGroup.objects.get(
|
||||||
check_move_message_according_to_policy(
|
name=SystemGroups.FULL_MEMBERS, realm=realm, is_system_group=True
|
||||||
UserProfile.ROLE_REALM_ADMINISTRATOR, expect_fail=True
|
)
|
||||||
|
members_system_group = NamedUserGroup.objects.get(
|
||||||
|
name=SystemGroups.MEMBERS, realm=realm, is_system_group=True
|
||||||
|
)
|
||||||
|
moderators_system_group = NamedUserGroup.objects.get(
|
||||||
|
name=SystemGroups.MODERATORS, realm=realm, is_system_group=True
|
||||||
|
)
|
||||||
|
nobody_system_group = NamedUserGroup.objects.get(
|
||||||
|
name=SystemGroups.NOBODY, realm=realm, is_system_group=True
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check sending messages when policy is MoveMessagesBetweenStreamsPolicyEnum.ADMINS_ONLY.
|
# Check sending messages when nobody is allowed to move messages.
|
||||||
do_set_realm_property(
|
do_change_realm_permission_group_setting(
|
||||||
user_profile.realm,
|
realm,
|
||||||
"move_messages_between_streams_policy",
|
"can_move_messages_between_channels_group",
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.ADMINS_ONLY,
|
nobody_system_group,
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_MODERATOR, expect_fail=True)
|
check_move_message_according_to_permission("desdemona", expect_fail=True)
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_REALM_ADMINISTRATOR)
|
check_move_message_according_to_permission("iago", expect_fail=True)
|
||||||
|
|
||||||
(user_profile, old_stream, new_stream, msg_id, msg_id_later) = self.prepare_move_topics(
|
# Check sending messages when only administrators are allowed.
|
||||||
"othello", "old_stream_2", "new_stream_2", "test"
|
do_change_realm_permission_group_setting(
|
||||||
)
|
realm,
|
||||||
# Check sending messages when policy is MoveMessagesBetweenStreamsPolicyEnum.MODERATORS_ONLY.
|
"can_move_messages_between_channels_group",
|
||||||
do_set_realm_property(
|
administrators_system_group,
|
||||||
user_profile.realm,
|
|
||||||
"move_messages_between_streams_policy",
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MODERATORS_ONLY,
|
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_MEMBER, expect_fail=True)
|
check_move_message_according_to_permission("shiva", expect_fail=True)
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_MODERATOR)
|
check_move_message_according_to_permission("iago")
|
||||||
|
|
||||||
(user_profile, old_stream, new_stream, msg_id, msg_id_later) = self.prepare_move_topics(
|
# Check sending messages when only moderators are allowed.
|
||||||
"othello", "old_stream_3", "new_stream_3", "test"
|
do_change_realm_permission_group_setting(
|
||||||
)
|
realm,
|
||||||
# Check sending messages when policy is MoveMessagesBetweenStreamsPolicyEnum.FULL_MEMBERS_ONLY.
|
"can_move_messages_between_channels_group",
|
||||||
do_set_realm_property(
|
moderators_system_group,
|
||||||
user_profile.realm,
|
|
||||||
"move_messages_between_streams_policy",
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.FULL_MEMBERS_ONLY,
|
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
do_set_realm_property(
|
check_move_message_according_to_permission("cordelia", expect_fail=True)
|
||||||
user_profile.realm, "waiting_period_threshold", 100000, acting_user=None
|
check_move_message_according_to_permission("shiva")
|
||||||
)
|
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_MEMBER, expect_fail=True)
|
|
||||||
|
|
||||||
do_set_realm_property(user_profile.realm, "waiting_period_threshold", 0, acting_user=None)
|
# Check sending messages when full members are allowed.
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_MEMBER)
|
do_change_realm_permission_group_setting(
|
||||||
|
realm,
|
||||||
(user_profile, old_stream, new_stream, msg_id, msg_id_later) = self.prepare_move_topics(
|
"can_move_messages_between_channels_group",
|
||||||
"othello", "old_stream_4", "new_stream_4", "test"
|
full_members_system_group,
|
||||||
)
|
|
||||||
# Check sending messages when policy is MoveMessagesBetweenStreamsPolicyEnum.MEMBERS_ONLY.
|
|
||||||
do_set_realm_property(
|
|
||||||
user_profile.realm,
|
|
||||||
"move_messages_between_streams_policy",
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MEMBERS_ONLY,
|
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_GUEST, expect_fail=True)
|
do_set_realm_property(othello.realm, "waiting_period_threshold", 100000, acting_user=None)
|
||||||
check_move_message_according_to_policy(UserProfile.ROLE_MEMBER)
|
check_move_message_according_to_permission("othello", expect_fail=True)
|
||||||
|
|
||||||
|
do_set_realm_property(realm, "waiting_period_threshold", 0, acting_user=None)
|
||||||
|
check_move_message_according_to_permission("cordelia")
|
||||||
|
|
||||||
|
# Check sending messages when members are allowed.
|
||||||
|
do_change_realm_permission_group_setting(
|
||||||
|
realm,
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
members_system_group,
|
||||||
|
acting_user=None,
|
||||||
|
)
|
||||||
|
check_move_message_according_to_permission("polonius", expect_fail=True)
|
||||||
|
check_move_message_according_to_permission("cordelia")
|
||||||
|
|
||||||
|
# Test for checking setting for non-system user group.
|
||||||
|
user_group = check_add_user_group(
|
||||||
|
realm, "new_group", [othello, cordelia], acting_user=othello
|
||||||
|
)
|
||||||
|
do_change_realm_permission_group_setting(
|
||||||
|
realm, "can_move_messages_between_channels_group", user_group, acting_user=None
|
||||||
|
)
|
||||||
|
|
||||||
|
# Othello and Cordelia are in the allowed user group, so can move messages.
|
||||||
|
check_move_message_according_to_permission("othello")
|
||||||
|
check_move_message_according_to_permission("cordelia")
|
||||||
|
|
||||||
|
# Iago is not in the allowed user group, so cannot move messages.
|
||||||
|
check_move_message_according_to_permission("iago", expect_fail=True)
|
||||||
|
|
||||||
|
# Test for checking the setting for anonymous user group.
|
||||||
|
anonymous_user_group = self.create_or_update_anonymous_group_for_setting(
|
||||||
|
[othello],
|
||||||
|
[administrators_system_group],
|
||||||
|
)
|
||||||
|
do_change_realm_permission_group_setting(
|
||||||
|
realm,
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
anonymous_user_group,
|
||||||
|
acting_user=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Othello is the direct member of the anonymous user group, so can move messages.
|
||||||
|
check_move_message_according_to_permission("othello")
|
||||||
|
# Iago is in the `administrators_system_group` subgroup, so can move messages.
|
||||||
|
check_move_message_according_to_permission("iago")
|
||||||
|
|
||||||
|
# Shiva is not in the anonymous user group, so cannot move messages.
|
||||||
|
check_move_message_according_to_permission("shiva", expect_fail=True)
|
||||||
|
|
||||||
def test_move_message_to_stream_time_limit(self) -> None:
|
def test_move_message_to_stream_time_limit(self) -> None:
|
||||||
shiva = self.example_user("shiva")
|
shiva = self.example_user("shiva")
|
||||||
iago = self.example_user("iago")
|
iago = self.example_user("iago")
|
||||||
cordelia = self.example_user("cordelia")
|
cordelia = self.example_user("cordelia")
|
||||||
|
|
||||||
|
realm = cordelia.realm
|
||||||
|
|
||||||
test_stream_1 = self.make_stream("test_stream_1")
|
test_stream_1 = self.make_stream("test_stream_1")
|
||||||
test_stream_2 = self.make_stream("test_stream_2")
|
test_stream_2 = self.make_stream("test_stream_2")
|
||||||
|
|
||||||
|
@ -900,10 +960,14 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
|
|
||||||
self.send_stream_message(cordelia, test_stream_1.name, topic_name="test", content="third")
|
self.send_stream_message(cordelia, test_stream_1.name, topic_name="test", content="third")
|
||||||
|
|
||||||
do_set_realm_property(
|
members_system_group = NamedUserGroup.objects.get(
|
||||||
cordelia.realm,
|
name=SystemGroups.MEMBERS, realm=realm, is_system_group=True
|
||||||
"move_messages_between_streams_policy",
|
)
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MEMBERS_ONLY,
|
|
||||||
|
do_change_realm_permission_group_setting(
|
||||||
|
realm,
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
members_system_group,
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -968,10 +1032,16 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
(user_profile, old_stream, new_stream, msg_id, msg_id_later) = self.prepare_move_topics(
|
(user_profile, old_stream, new_stream, msg_id, msg_id_later) = self.prepare_move_topics(
|
||||||
"othello", "old_stream_1", "new_stream_1", "test"
|
"othello", "old_stream_1", "new_stream_1", "test"
|
||||||
)
|
)
|
||||||
do_set_realm_property(
|
realm = user_profile.realm
|
||||||
user_profile.realm,
|
|
||||||
"move_messages_between_streams_policy",
|
members_system_group = NamedUserGroup.objects.get(
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MEMBERS_ONLY,
|
name=SystemGroups.MEMBERS, realm=realm, is_system_group=True
|
||||||
|
)
|
||||||
|
|
||||||
|
do_change_realm_permission_group_setting(
|
||||||
|
realm,
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
members_system_group,
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1066,10 +1136,14 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
realm.save()
|
realm.save()
|
||||||
self.login("cordelia")
|
self.login("cordelia")
|
||||||
|
|
||||||
do_set_realm_property(
|
members_system_group = NamedUserGroup.objects.get(
|
||||||
user_profile.realm,
|
name=SystemGroups.MEMBERS, realm=realm, is_system_group=True
|
||||||
"move_messages_between_streams_policy",
|
)
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MEMBERS_ONLY,
|
|
||||||
|
do_change_realm_permission_group_setting(
|
||||||
|
realm,
|
||||||
|
"can_move_messages_between_channels_group",
|
||||||
|
members_system_group,
|
||||||
acting_user=None,
|
acting_user=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1101,7 +1175,7 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
"iago", "test move stream", "new stream", "test"
|
"iago", "test move stream", "new stream", "test"
|
||||||
)
|
)
|
||||||
|
|
||||||
with self.assert_database_query_count(51), self.assert_memcached_count(14):
|
with self.assert_database_query_count(53), self.assert_memcached_count(14):
|
||||||
result = self.client_patch(
|
result = self.client_patch(
|
||||||
f"/json/messages/{msg_id}",
|
f"/json/messages/{msg_id}",
|
||||||
{
|
{
|
||||||
|
@ -1579,12 +1653,6 @@ class MessageMoveStreamTest(ZulipTestCase):
|
||||||
to_invite_only=False,
|
to_invite_only=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_can_move_messages_between_streams(self) -> None:
|
|
||||||
def validation_func(user_profile: UserProfile) -> bool:
|
|
||||||
return user_profile.can_move_messages_between_streams()
|
|
||||||
|
|
||||||
self.check_has_permission_policies("move_messages_between_streams_policy", validation_func)
|
|
||||||
|
|
||||||
def test_move_message_from_private_to_private_with_old_member(self) -> None:
|
def test_move_message_from_private_to_private_with_old_member(self) -> None:
|
||||||
admin_user = self.example_user("iago")
|
admin_user = self.example_user("iago")
|
||||||
user_losing_access = self.example_user("cordelia")
|
user_losing_access = self.example_user("cordelia")
|
||||||
|
|
|
@ -363,7 +363,7 @@ class MessageMoveTopicTest(ZulipTestCase):
|
||||||
set_topic_visibility_policy(desdemona, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
set_topic_visibility_policy(desdemona, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
||||||
set_topic_visibility_policy(cordelia, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
set_topic_visibility_policy(cordelia, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
||||||
|
|
||||||
with self.assert_database_query_count(27):
|
with self.assert_database_query_count(29):
|
||||||
check_update_message(
|
check_update_message(
|
||||||
user_profile=desdemona,
|
user_profile=desdemona,
|
||||||
message_id=message_id,
|
message_id=message_id,
|
||||||
|
@ -393,7 +393,7 @@ class MessageMoveTopicTest(ZulipTestCase):
|
||||||
]
|
]
|
||||||
set_topic_visibility_policy(desdemona, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
set_topic_visibility_policy(desdemona, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
||||||
set_topic_visibility_policy(cordelia, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
set_topic_visibility_policy(cordelia, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
||||||
with self.assert_database_query_count(33):
|
with self.assert_database_query_count(34):
|
||||||
check_update_message(
|
check_update_message(
|
||||||
user_profile=desdemona,
|
user_profile=desdemona,
|
||||||
message_id=message_id,
|
message_id=message_id,
|
||||||
|
@ -426,7 +426,7 @@ class MessageMoveTopicTest(ZulipTestCase):
|
||||||
set_topic_visibility_policy(desdemona, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
set_topic_visibility_policy(desdemona, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
||||||
set_topic_visibility_policy(cordelia, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
set_topic_visibility_policy(cordelia, muted_topics, UserTopic.VisibilityPolicy.MUTED)
|
||||||
|
|
||||||
with self.assert_database_query_count(27):
|
with self.assert_database_query_count(29):
|
||||||
check_update_message(
|
check_update_message(
|
||||||
user_profile=desdemona,
|
user_profile=desdemona,
|
||||||
message_id=message_id,
|
message_id=message_id,
|
||||||
|
@ -449,7 +449,7 @@ class MessageMoveTopicTest(ZulipTestCase):
|
||||||
second_message_id = self.send_stream_message(
|
second_message_id = self.send_stream_message(
|
||||||
hamlet, stream_name, topic_name="changed topic name", content="Second message"
|
hamlet, stream_name, topic_name="changed topic name", content="Second message"
|
||||||
)
|
)
|
||||||
with self.assert_database_query_count(22):
|
with self.assert_database_query_count(23):
|
||||||
check_update_message(
|
check_update_message(
|
||||||
user_profile=desdemona,
|
user_profile=desdemona,
|
||||||
message_id=second_message_id,
|
message_id=second_message_id,
|
||||||
|
|
|
@ -62,12 +62,7 @@ from zerver.models import (
|
||||||
)
|
)
|
||||||
from zerver.models.groups import SystemGroups
|
from zerver.models.groups import SystemGroups
|
||||||
from zerver.models.realm_audit_logs import AuditLogEventType
|
from zerver.models.realm_audit_logs import AuditLogEventType
|
||||||
from zerver.models.realms import (
|
from zerver.models.realms import CommonPolicyEnum, InviteToRealmPolicyEnum, get_realm
|
||||||
CommonPolicyEnum,
|
|
||||||
InviteToRealmPolicyEnum,
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum,
|
|
||||||
get_realm,
|
|
||||||
)
|
|
||||||
from zerver.models.streams import get_stream
|
from zerver.models.streams import get_stream
|
||||||
from zerver.models.users import get_system_bot, get_user_profile_by_id
|
from zerver.models.users import get_system_bot, get_user_profile_by_id
|
||||||
|
|
||||||
|
@ -119,16 +114,13 @@ class RealmTest(ZulipTestCase):
|
||||||
self.assertEqual(realm.can_create_public_channel_group_id, admins_group.id)
|
self.assertEqual(realm.can_create_public_channel_group_id, admins_group.id)
|
||||||
|
|
||||||
self.assertEqual(realm.invite_to_realm_policy, InviteToRealmPolicyEnum.ADMINS_ONLY)
|
self.assertEqual(realm.invite_to_realm_policy, InviteToRealmPolicyEnum.ADMINS_ONLY)
|
||||||
self.assertEqual(
|
|
||||||
realm.move_messages_between_streams_policy,
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MODERATORS_ONLY,
|
|
||||||
)
|
|
||||||
self.assertEqual(realm.invite_to_stream_policy, CommonPolicyEnum.MODERATORS_ONLY)
|
self.assertEqual(realm.invite_to_stream_policy, CommonPolicyEnum.MODERATORS_ONLY)
|
||||||
realm = get_realm("test_education_non_profit")
|
realm = get_realm("test_education_non_profit")
|
||||||
moderators_group = NamedUserGroup.objects.get(
|
moderators_group = NamedUserGroup.objects.get(
|
||||||
name=SystemGroups.MODERATORS, realm=realm, is_system_group=True
|
name=SystemGroups.MODERATORS, realm=realm, is_system_group=True
|
||||||
)
|
)
|
||||||
self.assertEqual(realm.can_create_groups.id, moderators_group.id)
|
self.assertEqual(realm.can_create_groups.id, moderators_group.id)
|
||||||
|
self.assertEqual(realm.can_move_messages_between_channels_group.id, moderators_group.id)
|
||||||
|
|
||||||
def test_permission_for_education_for_profit_organization(self) -> None:
|
def test_permission_for_education_for_profit_organization(self) -> None:
|
||||||
realm = do_create_realm(
|
realm = do_create_realm(
|
||||||
|
@ -143,16 +135,13 @@ class RealmTest(ZulipTestCase):
|
||||||
self.assertEqual(realm.can_create_public_channel_group_id, admins_group.id)
|
self.assertEqual(realm.can_create_public_channel_group_id, admins_group.id)
|
||||||
|
|
||||||
self.assertEqual(realm.invite_to_realm_policy, InviteToRealmPolicyEnum.ADMINS_ONLY)
|
self.assertEqual(realm.invite_to_realm_policy, InviteToRealmPolicyEnum.ADMINS_ONLY)
|
||||||
self.assertEqual(
|
|
||||||
realm.move_messages_between_streams_policy,
|
|
||||||
MoveMessagesBetweenStreamsPolicyEnum.MODERATORS_ONLY,
|
|
||||||
)
|
|
||||||
self.assertEqual(realm.invite_to_stream_policy, CommonPolicyEnum.MODERATORS_ONLY)
|
self.assertEqual(realm.invite_to_stream_policy, CommonPolicyEnum.MODERATORS_ONLY)
|
||||||
realm = get_realm("test_education_for_profit")
|
realm = get_realm("test_education_for_profit")
|
||||||
moderators_group = NamedUserGroup.objects.get(
|
moderators_group = NamedUserGroup.objects.get(
|
||||||
name=SystemGroups.MODERATORS, realm=realm, is_system_group=True
|
name=SystemGroups.MODERATORS, realm=realm, is_system_group=True
|
||||||
)
|
)
|
||||||
self.assertEqual(realm.can_create_groups.id, moderators_group.id)
|
self.assertEqual(realm.can_create_groups.id, moderators_group.id)
|
||||||
|
self.assertEqual(realm.can_move_messages_between_channels_group.id, moderators_group.id)
|
||||||
|
|
||||||
def test_realm_enable_spectator_access(self) -> None:
|
def test_realm_enable_spectator_access(self) -> None:
|
||||||
realm = do_create_realm(
|
realm = do_create_realm(
|
||||||
|
|
|
@ -145,6 +145,7 @@ def update_realm(
|
||||||
can_create_private_channel_group: Json[GroupSettingChangeRequest] | None = None,
|
can_create_private_channel_group: Json[GroupSettingChangeRequest] | None = None,
|
||||||
can_create_web_public_channel_group: Json[GroupSettingChangeRequest] | None = None,
|
can_create_web_public_channel_group: Json[GroupSettingChangeRequest] | None = None,
|
||||||
can_manage_all_groups: Json[GroupSettingChangeRequest] | None = None,
|
can_manage_all_groups: Json[GroupSettingChangeRequest] | None = None,
|
||||||
|
can_move_messages_between_channels_group: Json[GroupSettingChangeRequest] | None = None,
|
||||||
direct_message_initiator_group: Json[GroupSettingChangeRequest] | None = None,
|
direct_message_initiator_group: Json[GroupSettingChangeRequest] | None = None,
|
||||||
direct_message_permission_group: Json[GroupSettingChangeRequest] | None = None,
|
direct_message_permission_group: Json[GroupSettingChangeRequest] | None = None,
|
||||||
invite_to_stream_policy: Json[CommonPolicyEnum] | None = None,
|
invite_to_stream_policy: Json[CommonPolicyEnum] | None = None,
|
||||||
|
|
Loading…
Reference in New Issue