summary refs log tree commit diff
diff options
context:
space:
mode:
authorTravis Ralston <travpc@gmail.com>2020-08-18 15:21:30 -0600
committerTravis Ralston <travpc@gmail.com>2020-08-18 15:21:30 -0600
commitb024acffeaf6013db65f439c29927fd9030b274f (patch)
treedd52f7476bb673a338bc47cdc5c91c0c2ac81cc8
parentAdd a link to the matrix-synapse-rest-password-provider. (#8111) (diff)
downloadsynapse-travis/group-admin.tar.xz
Add rudimentary API for promoting/demoting other people in a group github/travis/group-admin travis/group-admin
For https://github.com/matrix-org/synapse/issues/2855 (initial)
-rw-r--r--synapse/groups/groups_server.py21
-rw-r--r--synapse/handlers/groups_local.py19
-rw-r--r--synapse/rest/client/v2_alpha/groups.py26
-rw-r--r--synapse/storage/databases/main/group_server.py8
4 files changed, 74 insertions, 0 deletions
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<group_id>[^/]*)/admin/users/admins/(?P<user_id>[^/]*)$"
+    )
+
+    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",