Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add room members admin endpoint #7842

Merged
merged 8 commits into from
Jul 16, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/7842.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add an admin API to list the users in a room. Contributed by Awesome Technologies Innovationslabor GmbH.
34 changes: 33 additions & 1 deletion docs/admin_api/rooms.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,11 +319,43 @@ Response:
}
```

# Room Members API

The Room Members admin API allows server admins to get a list of all members of a room.
clokep marked this conversation as resolved.
Show resolved Hide resolved

The response includes the following fields:

* `members` - A list of all the members that are present in the room, represented by their ids.
* `total` - Total number of members in the room.

## Usage

A standard request:

```
GET /_synapse/admin/v1/rooms/<room_id>/members

{}
```

Response:

```
{
"members": [
"@foo:matrix.org",
"@bar:matrix.org",
"@foobar:matrix.org
],
"total": 3
}
```

# Delete Room API

The Delete Room admin API allows server admins to remove rooms from server
and block these rooms.
It is a combination and improvement of "[Shutdown room](shutdown_room.md)"
It is a combination and improvement of "[Shutdown room](shutdown_room.md)"
and "[Purge room](purge_room.md)" API.

Shuts down a room. Moves all local users and room aliases automatically to a
Expand Down
2 changes: 2 additions & 0 deletions synapse/rest/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
DeleteRoomRestServlet,
JoinRoomAliasServlet,
ListRoomRestServlet,
RoomMembersRestServlet,
RoomRestServlet,
ShutdownRoomRestServlet,
)
Expand Down Expand Up @@ -201,6 +202,7 @@ def register_servlets(hs, http_server):
register_servlets_for_client_rest_resource(hs, http_server)
ListRoomRestServlet(hs).register(http_server)
RoomRestServlet(hs).register(http_server)
RoomMembersRestServlet(hs).register(http_server)
DeleteRoomRestServlet(hs).register(http_server)
JoinRoomAliasServlet(hs).register(http_server)
PurgeRoomServlet(hs).register(http_server)
Expand Down
24 changes: 24 additions & 0 deletions synapse/rest/admin/rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,30 @@ async def on_GET(self, request, room_id):
return 200, ret


class RoomMembersRestServlet(RestServlet):
"""
Get members list of a room.
"""

PATTERNS = admin_patterns("/rooms/(?P<room_id>[^/]+)/members")

def __init__(self, hs):
self.hs = hs
self.auth = hs.get_auth()
self.store = hs.get_datastore()

async def on_GET(self, request, room_id):
await assert_requester_is_admin(self.auth, request)

members = await self.store.get_users_in_room(room_id)
if not members:
raise NotFoundError("Room not found or empty")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After playing with this a bit more, I think this is going to be confusing, I think we should add use the self.store.get_room(room_id) method first, if that returns None we can raise NotFoundError.

Then, if there are no members I think we should return it as a success: {"members": [], "total": 0}.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats a very good suggestion. I'll add the check.


ret = {"members": members, "total": len(members)}

return 200, ret


class JoinRoomAliasServlet(RestServlet):

PATTERNS = admin_patterns("/join/(?P<room_identifier>[^/]*)")
Expand Down
46 changes: 46 additions & 0 deletions tests/rest/admin/test_room.py
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,52 @@ def test_single_room(self):

self.assertEqual(room_id_1, channel.json_body["room_id"])

def test_room_members(self):
"""Test that room members can be requested correctly"""
# Create two test rooms
room_id_1 = self.helper.create_room_as(self.admin_user, tok=self.admin_user_tok)
room_id_2 = self.helper.create_room_as(self.admin_user, tok=self.admin_user_tok)

# Have another user join the room
user_1 = self.register_user("foo", "pass")
user_tok_1 = self.login("foo", "pass")
self.helper.join(room_id_1, user_1, tok=user_tok_1)

# Have another user join the room
user_2 = self.register_user("bar", "pass")
user_tok_2 = self.login("bar", "pass")
self.helper.join(room_id_1, user_2, tok=user_tok_2)
self.helper.join(room_id_2, user_2, tok=user_tok_2)

# Have another user join the room
user_3 = self.register_user("foobar", "pass")
user_tok_3 = self.login("foobar", "pass")
self.helper.join(room_id_2, user_3, tok=user_tok_3)

url = "/_synapse/admin/v1/rooms/%s/members" % (room_id_1,)
request, channel = self.make_request(
"GET", url.encode("ascii"), access_token=self.admin_user_tok,
)
self.render(request)
self.assertEqual(200, channel.code, msg=channel.json_body)

self.assertCountEqual(
["@admin:test", "@foo:test", "@bar:test"], channel.json_body["members"]
)
self.assertEqual(channel.json_body["total"], 3)

url = "/_synapse/admin/v1/rooms/%s/members" % (room_id_2,)
request, channel = self.make_request(
"GET", url.encode("ascii"), access_token=self.admin_user_tok,
)
self.render(request)
self.assertEqual(200, channel.code, msg=channel.json_body)

self.assertCountEqual(
["@admin:test", "@bar:test", "@foobar:test"], channel.json_body["members"]
)
self.assertEqual(channel.json_body["total"], 3)


class JoinAliasRoomTestCase(unittest.HomeserverTestCase):

Expand Down