From 2ad1cc9d746494378d4fc15e198edc72d86f972a Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Tue, 4 Apr 2023 18:11:41 +0200 Subject: [PATCH 1/4] Add a POST /_synapse/admin/v2/users/{user_id}/devices API to provision a new device --- synapse/rest/admin/devices.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/synapse/rest/admin/devices.py b/synapse/rest/admin/devices.py index 3b2f2d9abbd6..37a10e8fb676 100644 --- a/synapse/rest/admin/devices.py +++ b/synapse/rest/admin/devices.py @@ -137,6 +137,34 @@ async def on_GET( devices = await self.device_handler.get_devices_by_user(target_user.to_string()) return HTTPStatus.OK, {"devices": devices, "total": len(devices)} + async def on_POST( + self, request: SynapseRequest, user_id: str + ) -> Tuple[int, JsonDict]: + await assert_requester_is_admin(self.auth, request) + + target_user = UserID.from_string(user_id) + if not self.is_mine(target_user): + raise SynapseError( + HTTPStatus.BAD_REQUEST, "Can only create devices for local users" + ) + + u = await self.store.get_user_by_id(target_user.to_string()) + if u is None: + raise NotFoundError("Unknown user") + + body = parse_json_object_from_request(request) + device_id = body.get("device_id") + if not device_id: + raise SynapseError(HTTPStatus.BAD_REQUEST, "Missing device_id") + if not isinstance(device_id, str): + raise SynapseError(HTTPStatus.BAD_REQUEST, "device_id must be a string") + + await self.device_handler.check_device_registered( + user_id=user_id, device_id=device_id + ) + + return HTTPStatus.CREATED, {} + class DeleteDevicesRestServlet(RestServlet): """ From d4f7fe25b81877846514cf9a5829cd2c483f5ed1 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 17 May 2023 15:16:43 +0200 Subject: [PATCH 2/4] Document the new admin API --- docs/admin_api/user_admin_api.md | 26 ++++++++++++++++++++++++++ synapse/rest/admin/devices.py | 1 + 2 files changed, 27 insertions(+) diff --git a/docs/admin_api/user_admin_api.md b/docs/admin_api/user_admin_api.md index 6b952ba3969b..8bc37f9a4d6f 100644 --- a/docs/admin_api/user_admin_api.md +++ b/docs/admin_api/user_admin_api.md @@ -813,6 +813,32 @@ The following fields are returned in the JSON response body: - `total` - Total number of user's devices. +### Create a device + +Creates a new device for a specific `user_id`. + +The API is: + +``` +POST /_synapse/admin/v2/users//devices + +{ + "device_id": "QBUAZIFURK" +} +``` + +An empty JSON dict is returned. + +**Parameters** + +The following parameters should be set in the URL: + +- `user_id` - fully qualified: for example, `@user:server.com`. + +The following fields are required in the JSON request body: + +- `device_id` - The device ID to create. + ### Delete multiple devices Deletes the given devices for a specific `user_id`, and invalidates any access token associated with them. diff --git a/synapse/rest/admin/devices.py b/synapse/rest/admin/devices.py index 37a10e8fb676..11ebed9bfdcb 100644 --- a/synapse/rest/admin/devices.py +++ b/synapse/rest/admin/devices.py @@ -140,6 +140,7 @@ async def on_GET( async def on_POST( self, request: SynapseRequest, user_id: str ) -> Tuple[int, JsonDict]: + """Creates a new device for the user.""" await assert_requester_is_admin(self.auth, request) target_user = UserID.from_string(user_id) From bb2499e9f2a9b9662bb56dcc17bfb0eeeaec68d1 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 17 May 2023 15:19:58 +0200 Subject: [PATCH 3/4] Newsfile. --- changelog.d/15611.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/15611.feature diff --git a/changelog.d/15611.feature b/changelog.d/15611.feature new file mode 100644 index 000000000000..7cfb46fd0a6c --- /dev/null +++ b/changelog.d/15611.feature @@ -0,0 +1 @@ +Add a new admin API to create a new device for a user. From e57595bd1a67fe71ea365e1380f84b3fdbe474d4 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 17 May 2023 15:45:50 +0200 Subject: [PATCH 4/4] Update docs/admin_api/user_admin_api.md Co-authored-by: Patrick Cloke --- docs/admin_api/user_admin_api.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/admin_api/user_admin_api.md b/docs/admin_api/user_admin_api.md index 8bc37f9a4d6f..229942b3112f 100644 --- a/docs/admin_api/user_admin_api.md +++ b/docs/admin_api/user_admin_api.md @@ -815,7 +815,8 @@ The following fields are returned in the JSON response body: ### Create a device -Creates a new device for a specific `user_id`. +Creates a new device for a specific `user_id` and `device_id`. Does nothing if the `device_id` +exists already. The API is: