mirror of https://github.com/zulip/zulip.git
user_groups: Add API endpoint to get subgroups of a user group.
This commit is contained in:
parent
1b3c972d9b
commit
37793434f7
|
@ -36,6 +36,8 @@ format used by the Zulip server that they are interacting with.
|
||||||
given user group.
|
given user group.
|
||||||
* [`GET /user_groups/{user_group_id}/members`](/api/get-user-group-members):
|
* [`GET /user_groups/{user_group_id}/members`](/api/get-user-group-members):
|
||||||
Added new endpoint to get members of a user group.
|
Added new endpoint to get members of a user group.
|
||||||
|
* [`GET /user_groups/{user_group_id}/members`](/api/get-user-group-subgroups):
|
||||||
|
Added new endpoint to get subgroups of a user group.
|
||||||
|
|
||||||
**Feature level 126**
|
**Feature level 126**
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
* [Update user group subgroups](/api/update-user-group-subgroups)
|
* [Update user group subgroups](/api/update-user-group-subgroups)
|
||||||
* [Get user group membership status](/api/get-is-user-group-member)
|
* [Get user group membership status](/api/get-is-user-group-member)
|
||||||
* [Get user group members](/api/get-user-group-members)
|
* [Get user group members](/api/get-user-group-members)
|
||||||
|
* [Get subgroups of user group](/api/get-user-group-subgroups)
|
||||||
* [Mute a user](/api/mute-user)
|
* [Mute a user](/api/mute-user)
|
||||||
* [Unmute a user](/api/unmute-user)
|
* [Unmute a user](/api/unmute-user)
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.4.3"
|
||||||
# Changes should be accompanied by documentation explaining what the
|
# Changes should be accompanied by documentation explaining what the
|
||||||
# new level means in templates/zerver/api/changelog.md, as well as
|
# new level means in templates/zerver/api/changelog.md, as well as
|
||||||
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
|
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
|
||||||
API_FEATURE_LEVEL = 126
|
API_FEATURE_LEVEL = 127
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
@ -179,6 +179,19 @@ def get_user_group_member_ids(
|
||||||
return list(member_ids)
|
return list(member_ids)
|
||||||
|
|
||||||
|
|
||||||
|
def get_subgroup_ids(user_group: UserGroup, *, direct_subgroup_only: bool = False) -> List[int]:
|
||||||
|
if direct_subgroup_only:
|
||||||
|
subgroup_ids = user_group.direct_subgroups.all().values_list("id", flat=True)
|
||||||
|
else:
|
||||||
|
subgroup_ids = (
|
||||||
|
get_recursive_subgroups(user_group)
|
||||||
|
.exclude(id=user_group.id)
|
||||||
|
.values_list("id", flat=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
return list(subgroup_ids)
|
||||||
|
|
||||||
|
|
||||||
def create_system_user_groups_for_realm(realm: Realm) -> Dict[int, UserGroup]:
|
def create_system_user_groups_for_realm(realm: Realm) -> Dict[int, UserGroup]:
|
||||||
"""Any changes to this function likely require a migration to adjust
|
"""Any changes to this function likely require a migration to adjust
|
||||||
existing realms. See e.g. migration 0375_create_role_based_system_groups.py,
|
existing realms. See e.g. migration 0375_create_role_based_system_groups.py,
|
||||||
|
|
|
@ -14009,6 +14009,49 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
$ref: "#/components/responses/SimpleSuccess"
|
$ref: "#/components/responses/SimpleSuccess"
|
||||||
|
get:
|
||||||
|
operationId: get-user-group-subgroups
|
||||||
|
summary: Get subgroups of the user group
|
||||||
|
tags: ["users"]
|
||||||
|
description: |
|
||||||
|
Get the subgroups of a [user group](/help/user-groups).
|
||||||
|
|
||||||
|
`GET {{ api_url }}/v1/user_groups/{user_group_id}/subgroups`
|
||||||
|
|
||||||
|
**Changes**: New in Zulip 6.0 (feature level 127).
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/UserGroupId"
|
||||||
|
- name: direct_subgroup_only
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
Whether to consider only direct subgroups of the user group
|
||||||
|
or subgroups of subgroups also.
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
example: true
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Success
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/JsonSuccessBase"
|
||||||
|
- $ref: "#/components/schemas/SuccessDescription"
|
||||||
|
- additionalProperties: false
|
||||||
|
properties:
|
||||||
|
result: {}
|
||||||
|
msg: {}
|
||||||
|
subgroups:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
description: |
|
||||||
|
A list containing the IDs of subgroups of the user group.
|
||||||
|
example:
|
||||||
|
{"msg": "", "result": "success", "subgroups": [2, 3]}
|
||||||
/user_groups/{user_group_id}/members/{user_id}:
|
/user_groups/{user_group_id}/members/{user_id}:
|
||||||
get:
|
get:
|
||||||
operationId: get-is-user-group-member
|
operationId: get-is-user-group-member
|
||||||
|
|
|
@ -979,3 +979,46 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||||
self.client_get(f"/json/user_groups/{moderators_group.id}/members", info=params).content
|
self.client_get(f"/json/user_groups/{moderators_group.id}/members", info=params).content
|
||||||
)
|
)
|
||||||
self.assertCountEqual(result_dict["members"], [shiva.id])
|
self.assertCountEqual(result_dict["members"], [shiva.id])
|
||||||
|
|
||||||
|
def test_get_subgroups_of_user_group(self) -> None:
|
||||||
|
realm = get_realm("zulip")
|
||||||
|
owners_group = UserGroup.objects.get(name="@role:owners", realm=realm, is_system_group=True)
|
||||||
|
admins_group = UserGroup.objects.get(
|
||||||
|
name="@role:administrators", realm=realm, is_system_group=True
|
||||||
|
)
|
||||||
|
moderators_group = UserGroup.objects.get(
|
||||||
|
name="@role:moderators", realm=realm, is_system_group=True
|
||||||
|
)
|
||||||
|
self.login("iago")
|
||||||
|
|
||||||
|
# Test invalid user group id
|
||||||
|
result = self.client_get("/json/user_groups/25/subgroups")
|
||||||
|
self.assert_json_error(result, "Invalid user group")
|
||||||
|
|
||||||
|
result_dict = orjson.loads(
|
||||||
|
self.client_get(f"/json/user_groups/{moderators_group.id}/subgroups").content
|
||||||
|
)
|
||||||
|
self.assertEqual(result_dict["subgroups"], [admins_group.id, owners_group.id])
|
||||||
|
|
||||||
|
params = {"direct_subgroup_only": orjson.dumps(True).decode()}
|
||||||
|
result_dict = orjson.loads(
|
||||||
|
self.client_get(
|
||||||
|
f"/json/user_groups/{moderators_group.id}/subgroups", info=params
|
||||||
|
).content
|
||||||
|
)
|
||||||
|
self.assertCountEqual(result_dict["subgroups"], [admins_group.id])
|
||||||
|
|
||||||
|
# User not part of a group can also get its subgroups.
|
||||||
|
self.login("hamlet")
|
||||||
|
result_dict = orjson.loads(
|
||||||
|
self.client_get(f"/json/user_groups/{moderators_group.id}/subgroups").content
|
||||||
|
)
|
||||||
|
self.assertEqual(result_dict["subgroups"], [admins_group.id, owners_group.id])
|
||||||
|
|
||||||
|
params = {"direct_subgroup_only": orjson.dumps(True).decode()}
|
||||||
|
result_dict = orjson.loads(
|
||||||
|
self.client_get(
|
||||||
|
f"/json/user_groups/{moderators_group.id}/subgroups", info=params
|
||||||
|
).content
|
||||||
|
)
|
||||||
|
self.assertCountEqual(result_dict["subgroups"], [admins_group.id])
|
||||||
|
|
|
@ -21,6 +21,7 @@ from zerver.lib.user_groups import (
|
||||||
access_user_group_by_id,
|
access_user_group_by_id,
|
||||||
access_user_groups_as_potential_subgroups,
|
access_user_groups_as_potential_subgroups,
|
||||||
get_direct_memberships_of_users,
|
get_direct_memberships_of_users,
|
||||||
|
get_subgroup_ids,
|
||||||
get_user_group_direct_members,
|
get_user_group_direct_members,
|
||||||
get_user_group_member_ids,
|
get_user_group_member_ids,
|
||||||
is_user_in_group,
|
is_user_in_group,
|
||||||
|
@ -259,3 +260,19 @@ def get_user_group_members(
|
||||||
"members": get_user_group_member_ids(user_group, direct_member_only=direct_member_only)
|
"members": get_user_group_member_ids(user_group, direct_member_only=direct_member_only)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@require_member_or_admin
|
||||||
|
@has_request_variables
|
||||||
|
def get_subgroups_of_user_group(
|
||||||
|
request: HttpRequest,
|
||||||
|
user_profile: UserProfile,
|
||||||
|
user_group_id: int = REQ(json_validator=check_int, path_only=True),
|
||||||
|
direct_subgroup_only: bool = REQ(json_validator=check_bool, default=False),
|
||||||
|
) -> HttpResponse:
|
||||||
|
user_group = access_user_group_by_id(user_group_id, user_profile, for_read=True)
|
||||||
|
|
||||||
|
return json_success(
|
||||||
|
request,
|
||||||
|
data={"subgroups": get_subgroup_ids(user_group, direct_subgroup_only=direct_subgroup_only)},
|
||||||
|
)
|
||||||
|
|
|
@ -177,6 +177,7 @@ from zerver.views.user_groups import (
|
||||||
delete_user_group,
|
delete_user_group,
|
||||||
edit_user_group,
|
edit_user_group,
|
||||||
get_is_user_group_member,
|
get_is_user_group_member,
|
||||||
|
get_subgroups_of_user_group,
|
||||||
get_user_group,
|
get_user_group,
|
||||||
get_user_group_members,
|
get_user_group_members,
|
||||||
update_subgroups_of_user_group,
|
update_subgroups_of_user_group,
|
||||||
|
@ -379,7 +380,11 @@ v1_api_and_json_patterns = [
|
||||||
GET=get_user_group_members,
|
GET=get_user_group_members,
|
||||||
POST=update_user_group_backend,
|
POST=update_user_group_backend,
|
||||||
),
|
),
|
||||||
rest_path("user_groups/<int:user_group_id>/subgroups", POST=update_subgroups_of_user_group),
|
rest_path(
|
||||||
|
"user_groups/<int:user_group_id>/subgroups",
|
||||||
|
POST=update_subgroups_of_user_group,
|
||||||
|
GET=get_subgroups_of_user_group,
|
||||||
|
),
|
||||||
rest_path(
|
rest_path(
|
||||||
"user_groups/<int:user_group_id>/members/<int:user_id>", GET=get_is_user_group_member
|
"user_groups/<int:user_group_id>/members/<int:user_id>", GET=get_is_user_group_member
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue