groups: Accept anonymous groups for create_multiuse_invite_group.

On the frontend, the selection is still a dropdown of system groups but
on the API level, we have started accepting anonymous groups similar to
other settings.
We've kept require system groups true for now until we switch to group
picker on the frontend.
This commit is contained in:
Shubham Padia 2024-10-22 09:48:29 +00:00 committed by Tim Abbott
parent 3310aed462
commit ceb0197c1b
8 changed files with 67 additions and 30 deletions

View File

@ -20,6 +20,14 @@ format used by the Zulip server that they are interacting with.
## Changes in Zulip 10.0
**Feature level 314**
* `PATCH /realm`, [`POST /register`](/api/register-queue),
[`GET /events`](/api/get-events): Anonymous groups are now accepted
by `create_multiuse_invite_group` realm setting, which is a now a
[group-setting value](/api/group-setting-values) instead of an
integer ID of the group.
**Feature level 313**
* [`PATCH /users/{user_id}`](/api/update-user): Added `new_email` field to

View File

@ -34,7 +34,7 @@ DESKTOP_WARNING_VERSION = "5.9.3"
# new level means in api_docs/changelog.md, as well as "**Changes**"
# entries in the endpoint's documentation in `zulip.yaml`.
API_FEATURE_LEVEL = 313 # Last bumped for adding `new_email` to /users/{user_id} and the new PATCH /users/{email} endpoint
API_FEATURE_LEVEL = 314 # Last bumped for create_multiuse_invite_group api changes.
# 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

View File

@ -477,7 +477,6 @@ const dropdown_widget_map = new Map<string, DropdownWidget | null>([
["realm_signup_announcements_stream_id", null],
["realm_zulip_update_announcements_stream_id", null],
["realm_default_code_block_language", null],
["realm_create_multiuse_invite_group", null],
["can_remove_subscribers_group", null],
["realm_can_access_all_users_group", null],
["realm_can_add_custom_emoji_group", null],
@ -489,6 +488,7 @@ const dropdown_widget_map = new Map<string, DropdownWidget | null>([
["realm_can_delete_own_message_group", null],
["realm_can_manage_all_groups", null],
["realm_can_move_messages_between_channels_group", null],
["realm_create_multiuse_invite_group", null],
["realm_direct_message_initiator_group", null],
["realm_direct_message_permission_group", null],
]);
@ -1053,6 +1053,7 @@ export function populate_data_for_realm_settings_request(
"can_delete_any_message_group",
"can_delete_own_message_group",
"can_move_messages_between_channels_group",
"create_multiuse_invite_group",
"direct_message_initiator_group",
"direct_message_permission_group",
]);

View File

@ -1066,7 +1066,7 @@ group_setting_type = UnionType(
group_setting_update_data_type = DictType(
required_keys=[],
optional_keys=[
("create_multiuse_invite_group", int),
("create_multiuse_invite_group", group_setting_type),
("can_access_all_users_group", int),
("can_add_custom_emoji_group", group_setting_type),
("can_create_groups", group_setting_type),

View File

@ -682,7 +682,7 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub
REALM_PERMISSION_GROUP_SETTINGS: dict[str, GroupPermissionSetting] = dict(
create_multiuse_invite_group=GroupPermissionSetting(
require_system_group=True,
require_system_group=not settings.ALLOW_GROUP_VALUED_SETTINGS,
allow_internet_group=False,
allow_owners_group=False,
allow_nobody_group=True,
@ -808,6 +808,7 @@ class Realm(models.Model): # type: ignore[django-manager-missing] # django-stub
)
REALM_PERMISSION_GROUP_SETTINGS_WITH_NEW_API_FORMAT = [
"create_multiuse_invite_group",
"can_add_custom_emoji_group",
"can_create_groups",
"can_create_private_channel_group",
@ -1195,6 +1196,8 @@ def get_realm_with_settings(realm_id: int) -> Realm:
# the setting is used when fetching users in the realm.
# * Announcements streams.
return Realm.objects.select_related(
"create_multiuse_invite_group",
"create_multiuse_invite_group__named_user_group",
"can_access_all_users_group",
"can_access_all_users_group__named_user_group",
"can_add_custom_emoji_group",

View File

@ -4532,18 +4532,18 @@ paths:
[calc-full-member]: /api/roles-and-permissions#determining-if-a-user-is-a-full-member
create_multiuse_invite_group:
type: integer
description: |
The ID of the [user group](/api/get-user-groups) whose members are
allowed to create [reusable invitation
links](/help/invite-new-users#create-a-reusable-invitation-link)
to the organization.
allOf:
- $ref: "#/components/schemas/GroupSettingValue"
- description: |
A [group-setting value](/api/group-setting-values) defining the
set of users who are allowed to create [reusable invitation
links](/help/invite-new-users#create-a-reusable-invitation-link)
to the organization.
This setting can currently only be set to user groups that are
system groups, except for the system groups named
`"role:internet"` and `"role:owners"`.
**Changes**: Prior to Zulip 10.0 (feature level 314), this value used
to be of type integer and did not accept anonymous user groups.
**Changes**: New in Zulip 8.0 (feature level 209).
New in Zulip 8.0 (feature level 209).
default_code_block_language:
type: string
description: |
@ -16591,18 +16591,18 @@ paths:
[permission-level]: /api/roles-and-permissions#permission-levels
[calc-full-member]: /api/roles-and-permissions#determining-if-a-user-is-a-full-member
realm_create_multiuse_invite_group:
type: integer
description: |
The ID of the [user group](/api/get-user-groups) whose members are
allowed to create [reusable invitation
links](/help/invite-new-users#create-a-reusable-invitation-link)
to the organization.
allOf:
- $ref: "#/components/schemas/GroupSettingValue"
- description: |
A [group-setting value](/api/group-setting-values) defining the
set of users who are allowed to create [reusable invitation
links](/help/invite-new-users#create-a-reusable-invitation-link)
to the organization.
This setting can currently only be set to user groups that are
system groups, except for the system groups named
`"role:internet"` and `"role:owners"`.
**Changes**: Prior to Zulip 10.0 (feature level 314), this value used
to be of type integer and did not accept anonymous user groups.
**Changes**: New in Zulip 8.0 (feature level 209).
New in Zulip 8.0 (feature level 209).
realm_inline_image_preview:
type: boolean
description: |

View File

@ -2834,19 +2834,46 @@ class MultiuseInviteTest(ZulipTestCase):
self.login("iago")
result = self.client_patch(
"/json/realm",
{"create_multiuse_invite_group": orjson.dumps(full_members_system_group.id).decode()},
{
"create_multiuse_invite_group": orjson.dumps(
{"new": full_members_system_group.id}
).decode()
},
)
self.assert_json_error(result, "Must be an organization owner")
self.login("desdemona")
result = self.client_patch(
"/json/realm",
{"create_multiuse_invite_group": orjson.dumps(full_members_system_group.id).decode()},
{
"create_multiuse_invite_group": orjson.dumps(
{"new": full_members_system_group.id}
).decode()
},
)
self.assert_json_success(result)
realm = get_realm("zulip")
self.assertEqual(realm.create_multiuse_invite_group_id, full_members_system_group.id)
# Test setting the value to an anonymous group.
iago = self.example_user("iago")
result = self.client_patch(
"/json/realm",
{
"create_multiuse_invite_group": orjson.dumps(
{
"new": {
"direct_members": [iago.id],
"direct_subgroups": [],
}
}
).decode()
},
)
self.assert_json_success(result)
realm = get_realm("zulip")
self.assertCountEqual(realm.create_multiuse_invite_group.direct_members.all(), [iago])
def test_multiuse_link_for_inviting_as_owner(self) -> None:
self.login("iago")
result = self.client_post(

View File

@ -101,9 +101,7 @@ def update_realm(
disallow_disposable_email_addresses: Json[bool] | None = None,
invite_required: Json[bool] | None = None,
invite_to_realm_policy: Json[InviteToRealmPolicyEnum] | None = None,
create_multiuse_invite_group_id: Annotated[
Json[int] | None, ApiParamConfig(whence="create_multiuse_invite_group")
] = None,
create_multiuse_invite_group: Json[GroupSettingChangeRequest] | None = None,
require_unique_names: Json[bool] | None = None,
name_changes_disabled: Json[bool] | None = None,
email_changes_disabled: Json[bool] | None = None,
@ -226,7 +224,7 @@ def update_realm(
if (
invite_to_realm_policy is not None
or invite_required is not None
or create_multiuse_invite_group_id is not None
or create_multiuse_invite_group is not None
or can_create_groups is not None
or can_manage_all_groups is not None
) and not user_profile.is_realm_owner: