mirror of https://github.com/zulip/zulip.git
user_groups: Allow updating subgroups and members using same endpoint.
`POST /user_groups/{user_group_id}/members` now allows updating subgroups as well.
This commit is contained in:
parent
47a611f989
commit
1e818c4708
|
@ -20,6 +20,12 @@ format used by the Zulip server that they are interacting with.
|
||||||
|
|
||||||
## Changes in Zulip 10.0
|
## Changes in Zulip 10.0
|
||||||
|
|
||||||
|
**Feature level 311**
|
||||||
|
|
||||||
|
* [`POST /user_groups/{user_group_id}/members`](/api/update-user-group-members):
|
||||||
|
Added `add_subgroups` and `delete_subgroups` parameters to support updating
|
||||||
|
subgroups of a user group using this endpoint.
|
||||||
|
|
||||||
**Feature level 310**
|
**Feature level 310**
|
||||||
|
|
||||||
* `PATCH /realm`, [`GET /events`](/api/get-events),
|
* `PATCH /realm`, [`GET /events`](/api/get-events),
|
||||||
|
|
|
@ -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 = 310 # Last bumped for adding `can_move_messages_between_channels_group`.
|
API_FEATURE_LEVEL = 311 # Last bumped for updating subgroups.
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
@ -20430,11 +20430,33 @@ paths:
|
||||||
items:
|
items:
|
||||||
type: integer
|
type: integer
|
||||||
example: [12, 13]
|
example: [12, 13]
|
||||||
|
delete_subgroups:
|
||||||
|
description: |
|
||||||
|
The list of user group IDs to be removed from the user group.
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 10.0 (feature level 311).
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
example: [9]
|
||||||
|
add_subgroups:
|
||||||
|
description: |
|
||||||
|
The list of user group IDs to be added to the user group.
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 10.0 (feature level 311).
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
example: [9]
|
||||||
encoding:
|
encoding:
|
||||||
delete:
|
delete:
|
||||||
contentType: application/json
|
contentType: application/json
|
||||||
add:
|
add:
|
||||||
contentType: application/json
|
contentType: application/json
|
||||||
|
delete_subgroups:
|
||||||
|
contentType: application/json
|
||||||
|
add_subgroups:
|
||||||
|
contentType: application/json
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
$ref: "#/components/responses/SimpleSuccess"
|
$ref: "#/components/responses/SimpleSuccess"
|
||||||
|
@ -21004,7 +21026,7 @@ paths:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: integer
|
type: integer
|
||||||
example: [9, 10]
|
example: [10]
|
||||||
encoding:
|
encoding:
|
||||||
delete:
|
delete:
|
||||||
contentType: application/json
|
contentType: application/json
|
||||||
|
|
|
@ -1672,9 +1672,27 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||||
# No notification message is sent for removing from user group.
|
# No notification message is sent for removing from user group.
|
||||||
self.assertEqual(self.get_last_message(), initial_last_message)
|
self.assertEqual(self.get_last_message(), initial_last_message)
|
||||||
|
|
||||||
|
# Test adding and removing subgroups.
|
||||||
|
admins_group = NamedUserGroup.objects.get(
|
||||||
|
name=SystemGroups.ADMINISTRATORS, realm=hamlet.realm, is_system_group=True
|
||||||
|
)
|
||||||
|
cordelia = self.example_user("cordelia")
|
||||||
|
subgroup = check_add_user_group(
|
||||||
|
hamlet.realm, "leadership", [cordelia], acting_user=cordelia
|
||||||
|
)
|
||||||
|
params = {"add_subgroups": orjson.dumps([subgroup.id, admins_group.id]).decode()}
|
||||||
|
result = self.client_post(f"/json/user_groups/{user_group.id}/members", info=params)
|
||||||
|
self.assert_json_success(result)
|
||||||
|
self.assert_subgroup_membership(user_group, [subgroup, admins_group])
|
||||||
|
|
||||||
|
params = {"delete_subgroups": orjson.dumps([admins_group.id]).decode()}
|
||||||
|
result = self.client_post(f"/json/user_groups/{user_group.id}/members", info=params)
|
||||||
|
self.assert_json_success(result)
|
||||||
|
self.assert_subgroup_membership(user_group, [subgroup])
|
||||||
|
|
||||||
# Test when nothing is provided
|
# Test when nothing is provided
|
||||||
result = self.client_post(f"/json/user_groups/{user_group.id}/members", info={})
|
result = self.client_post(f"/json/user_groups/{user_group.id}/members", info={})
|
||||||
msg = 'Nothing to do. Specify at least one of "add" or "delete".'
|
msg = 'Nothing to do. Specify at least one of "add", "delete", "add_subgroups" or "delete_subgroups".'
|
||||||
self.assert_json_error(result, msg)
|
self.assert_json_error(result, msg)
|
||||||
self.assert_user_membership(user_group, [hamlet])
|
self.assert_user_membership(user_group, [hamlet])
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,7 @@ def deactivate_user_group(
|
||||||
|
|
||||||
@require_member_or_admin
|
@require_member_or_admin
|
||||||
@typed_endpoint
|
@typed_endpoint
|
||||||
|
@transaction.atomic(durable=True)
|
||||||
def update_user_group_backend(
|
def update_user_group_backend(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
user_profile: UserProfile,
|
user_profile: UserProfile,
|
||||||
|
@ -219,9 +220,15 @@ def update_user_group_backend(
|
||||||
user_group_id: PathOnly[Json[int]],
|
user_group_id: PathOnly[Json[int]],
|
||||||
delete: Json[list[int]] | None = None,
|
delete: Json[list[int]] | None = None,
|
||||||
add: Json[list[int]] | None = None,
|
add: Json[list[int]] | None = None,
|
||||||
|
delete_subgroups: Json[list[int]] | None = None,
|
||||||
|
add_subgroups: Json[list[int]] | None = None,
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if not add and not delete:
|
if not add and not delete and not add_subgroups and not delete_subgroups:
|
||||||
raise JsonableError(_('Nothing to do. Specify at least one of "add" or "delete".'))
|
raise JsonableError(
|
||||||
|
_(
|
||||||
|
'Nothing to do. Specify at least one of "add", "delete", "add_subgroups" or "delete_subgroups".'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
thunks = []
|
thunks = []
|
||||||
if add:
|
if add:
|
||||||
|
@ -237,6 +244,20 @@ def update_user_group_backend(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if add_subgroups:
|
||||||
|
thunks.append(
|
||||||
|
lambda: add_subgroups_to_group_backend(
|
||||||
|
request, user_profile, user_group_id=user_group_id, subgroup_ids=add_subgroups
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if delete_subgroups:
|
||||||
|
thunks.append(
|
||||||
|
lambda: remove_subgroups_from_group_backend(
|
||||||
|
request, user_profile, user_group_id=user_group_id, subgroup_ids=delete_subgroups
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
data = compose_views(thunks)
|
data = compose_views(thunks)
|
||||||
|
|
||||||
return json_success(request, data)
|
return json_success(request, data)
|
||||||
|
@ -290,7 +311,6 @@ def notify_for_user_group_subscription_changes(
|
||||||
do_send_messages(notifications)
|
do_send_messages(notifications)
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def add_members_to_group_backend(
|
def add_members_to_group_backend(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
user_profile: UserProfile,
|
user_profile: UserProfile,
|
||||||
|
@ -337,7 +357,6 @@ def add_members_to_group_backend(
|
||||||
return json_success(request)
|
return json_success(request)
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
|
||||||
def remove_members_from_group_backend(
|
def remove_members_from_group_backend(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
user_profile: UserProfile,
|
user_profile: UserProfile,
|
||||||
|
|
Loading…
Reference in New Issue