From b024acffeaf6013db65f439c29927fd9030b274f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 18 Aug 2020 15:21:30 -0600 Subject: Add rudimentary API for promoting/demoting other people in a group For https://github.com/matrix-org/synapse/issues/2855 (initial) --- synapse/groups/groups_server.py | 21 +++++++++++++++++++++ synapse/handlers/groups_local.py | 19 +++++++++++++++++++ synapse/rest/client/v2_alpha/groups.py | 26 ++++++++++++++++++++++++++ synapse/storage/databases/main/group_server.py | 8 ++++++++ 4 files changed, 74 insertions(+) diff --git a/synapse/groups/groups_server.py b/synapse/groups/groups_server.py index 8cb922ddc7..6f09253b87 100644 --- a/synapse/groups/groups_server.py +++ b/synapse/groups/groups_server.py @@ -719,6 +719,27 @@ class GroupsServerHandler(GroupsServerWorkerHandler): raise NotImplementedError() + async def change_user_admin_in_group( + self, group_id, user_id, want_admin, requester_user_id, content + ): + """Promotes or demotes a user in a group. + """ + + await self.check_group_is_ours(group_id, requester_user_id, and_exists=True) + + if requester_user_id == user_id: + raise SynapseError(400, "User cannot target themselves") + + is_admin = await self.store.is_user_admin_in_group( + group_id, requester_user_id + ) + if not is_admin: + raise SynapseError(403, "User is not admin in group") + + await self.store.change_user_admin_in_group(group_id, user_id, want_admin) + + return {} + async def remove_user_from_group( self, group_id, user_id, requester_user_id, content ): diff --git a/synapse/handlers/groups_local.py b/synapse/handlers/groups_local.py index 0e2656ccb3..aa98d6b441 100644 --- a/synapse/handlers/groups_local.py +++ b/synapse/handlers/groups_local.py @@ -461,6 +461,25 @@ class GroupsLocalHandler(GroupsLocalWorkerHandler): return {"state": "invite", "user_profile": user_profile} + async def change_user_admin_in_group( + self, group_id, user_id, want_admin, requester_user_id, content + ): + """Promotes or demotes a user in a group. + """ + + if not self.is_mine_id(user_id): + raise SynapseError(400, "User not on this server") + + # TODO: We should probably support federation, but this is fine for now + if not self.is_mine_id(group_id): + raise SynapseError(400, "Group not on this server") + + res = await self.groups_server_handler.change_user_admin_in_group( + group_id, user_id, want_admin, requester_user_id, content + ) + + return res + async def remove_user_from_group( self, group_id, user_id, requester_user_id, content ): diff --git a/synapse/rest/client/v2_alpha/groups.py b/synapse/rest/client/v2_alpha/groups.py index d84a6d7e11..1efe60f3a7 100644 --- a/synapse/rest/client/v2_alpha/groups.py +++ b/synapse/rest/client/v2_alpha/groups.py @@ -548,6 +548,31 @@ class GroupAdminUsersKickServlet(RestServlet): return 200, result +class GroupAdminChangeAdminServlet(RestServlet): + """Promote or demote a user in the group + """ + + PATTERNS = client_patterns( + "/groups/(?P[^/]*)/admin/users/admins/(?P[^/]*)$" + ) + + def __init__(self, hs): + super(GroupAdminChangeAdminServlet, self).__init__() + self.auth = hs.get_auth() + self.clock = hs.get_clock() + self.groups_handler = hs.get_groups_local_handler() + + async def on_POST(self, request, group_id, user_id): + requester = await self.auth.get_user_by_req(request) + requester_user_id = requester.user.to_string() + + content = parse_json_object_from_request(request) + want_admin = content["is_admin"] + result = await self.groups_handler.change_user_admin_in_group( + group_id, user_id, want_admin, requester_user_id, content + ) + + return 200, result class GroupSelfLeaveServlet(RestServlet): """Leave a joined group @@ -722,6 +747,7 @@ def register_servlets(hs, http_server): GroupAdminRoomsConfigServlet(hs).register(http_server) GroupAdminUsersInviteServlet(hs).register(http_server) GroupAdminUsersKickServlet(hs).register(http_server) + GroupAdminChangeAdminServlet(hs).register(http_server) GroupSelfLeaveServlet(hs).register(http_server) GroupSelfJoinServlet(hs).register(http_server) GroupSelfAcceptInviteServlet(hs).register(http_server) diff --git a/synapse/storage/databases/main/group_server.py b/synapse/storage/databases/main/group_server.py index 380db3a3f3..95d9868c3c 100644 --- a/synapse/storage/databases/main/group_server.py +++ b/synapse/storage/databases/main/group_server.py @@ -1038,6 +1038,14 @@ class GroupServerStore(GroupServerWorkerStore): "remove_user_from_group", _remove_user_from_group_txn ) + def change_user_admin_in_group(self, group_id, user_id, is_admin): + return self.db_pool.simple_update( + table="group_users", + keyvalues={"group_id": group_id, "user_id": user_id}, + updatevalues={"is_admin": is_admin}, + desc="change_user_admin_in_group" + ) + def add_room_to_group(self, group_id, room_id, is_public): return self.db_pool.simple_insert( table="group_rooms", -- cgit 1.4.1