mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-24 10:35:46 +03:00
Fix deletion for Dehydrated Devices (#16046)
This commit is contained in:
parent
d98a43d922
commit
84ae2e3f6f
4 changed files with 165 additions and 5 deletions
1
changelog.d/16046.bugfix
Normal file
1
changelog.d/16046.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fix deletion in dehydrated devices v2.
|
|
@ -722,6 +722,22 @@ class DeviceHandler(DeviceWorkerHandler):
|
||||||
|
|
||||||
return {"success": True}
|
return {"success": True}
|
||||||
|
|
||||||
|
async def delete_dehydrated_device(self, user_id: str, device_id: str) -> None:
|
||||||
|
"""
|
||||||
|
Delete a stored dehydrated device.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: the user_id to delete the device from
|
||||||
|
device_id: id of the dehydrated device to delete
|
||||||
|
"""
|
||||||
|
success = await self.store.remove_dehydrated_device(user_id, device_id)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
raise errors.NotFoundError()
|
||||||
|
|
||||||
|
await self.delete_devices(user_id, [device_id])
|
||||||
|
await self.store.delete_e2e_keys_by_device(user_id=user_id, device_id=device_id)
|
||||||
|
|
||||||
@wrap_as_background_process("_handle_new_device_update_async")
|
@wrap_as_background_process("_handle_new_device_update_async")
|
||||||
async def _handle_new_device_update_async(self) -> None:
|
async def _handle_new_device_update_async(self) -> None:
|
||||||
"""Called when we have a new local device list update that we need to
|
"""Called when we have a new local device list update that we need to
|
||||||
|
|
|
@ -513,10 +513,8 @@ class DehydratedDeviceV2Servlet(RestServlet):
|
||||||
if dehydrated_device is not None:
|
if dehydrated_device is not None:
|
||||||
(device_id, device_data) = dehydrated_device
|
(device_id, device_data) = dehydrated_device
|
||||||
|
|
||||||
result = await self.device_handler.rehydrate_device(
|
await self.device_handler.delete_dehydrated_device(
|
||||||
requester.user.to_string(),
|
requester.user.to_string(), device_id
|
||||||
self.auth.get_access_token_from_request(request),
|
|
||||||
device_id,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
result = {"device_id": device_id}
|
result = {"device_id": device_id}
|
||||||
|
@ -538,6 +536,14 @@ class DehydratedDeviceV2Servlet(RestServlet):
|
||||||
requester = await self.auth.get_user_by_req(request)
|
requester = await self.auth.get_user_by_req(request)
|
||||||
user_id = requester.user.to_string()
|
user_id = requester.user.to_string()
|
||||||
|
|
||||||
|
old_dehydrated_device = await self.device_handler.get_dehydrated_device(user_id)
|
||||||
|
|
||||||
|
# if an old device exists, delete it before creating a new one
|
||||||
|
if old_dehydrated_device:
|
||||||
|
await self.device_handler.delete_dehydrated_device(
|
||||||
|
user_id, old_dehydrated_device[0]
|
||||||
|
)
|
||||||
|
|
||||||
device_info = submission.dict()
|
device_info = submission.dict()
|
||||||
if "device_keys" not in device_info.keys():
|
if "device_keys" not in device_info.keys():
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
|
|
|
@ -379,4 +379,141 @@ class DehydratedDeviceTestCase(unittest.HomeserverTestCase):
|
||||||
access_token=token,
|
access_token=token,
|
||||||
shorthand=False,
|
shorthand=False,
|
||||||
)
|
)
|
||||||
self.assertEqual(channel.code, 404)
|
self.assertEqual(channel.code, 401)
|
||||||
|
|
||||||
|
@unittest.override_config(
|
||||||
|
{"experimental_features": {"msc2697_enabled": False, "msc3814_enabled": True}}
|
||||||
|
)
|
||||||
|
def test_msc3814_dehydrated_device_delete_works(self) -> None:
|
||||||
|
user = self.register_user("mikey", "pass")
|
||||||
|
token = self.login(user, "pass", device_id="device1")
|
||||||
|
content: JsonDict = {
|
||||||
|
"device_data": {
|
||||||
|
"algorithm": "m.dehydration.v1.olm",
|
||||||
|
},
|
||||||
|
"device_id": "device2",
|
||||||
|
"initial_device_display_name": "foo bar",
|
||||||
|
"device_keys": {
|
||||||
|
"user_id": "@mikey:test",
|
||||||
|
"device_id": "device2",
|
||||||
|
"valid_until_ts": "80",
|
||||||
|
"algorithms": [
|
||||||
|
"m.olm.curve25519-aes-sha2",
|
||||||
|
],
|
||||||
|
"keys": {
|
||||||
|
"<algorithm>:<device_id>": "<key_base64>",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"<user_id>": {"<algorithm>:<device_id>": "<signature_base64>"}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
channel = self.make_request(
|
||||||
|
"PUT",
|
||||||
|
"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device",
|
||||||
|
content=content,
|
||||||
|
access_token=token,
|
||||||
|
shorthand=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(channel.code, 200)
|
||||||
|
device_id = channel.json_body.get("device_id")
|
||||||
|
assert device_id is not None
|
||||||
|
self.assertIsInstance(device_id, str)
|
||||||
|
self.assertEqual("device2", device_id)
|
||||||
|
|
||||||
|
# ensure that keys were uploaded and available
|
||||||
|
channel = self.make_request(
|
||||||
|
"POST",
|
||||||
|
"/_matrix/client/r0/keys/query",
|
||||||
|
{
|
||||||
|
"device_keys": {
|
||||||
|
user: ["device2"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
channel.json_body["device_keys"][user]["device2"]["keys"],
|
||||||
|
{
|
||||||
|
"<algorithm>:<device_id>": "<key_base64>",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# delete the dehydrated device
|
||||||
|
channel = self.make_request(
|
||||||
|
"DELETE",
|
||||||
|
"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device",
|
||||||
|
access_token=token,
|
||||||
|
shorthand=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(channel.code, 200)
|
||||||
|
|
||||||
|
# ensure that keys are no longer available for deleted device
|
||||||
|
channel = self.make_request(
|
||||||
|
"POST",
|
||||||
|
"/_matrix/client/r0/keys/query",
|
||||||
|
{
|
||||||
|
"device_keys": {
|
||||||
|
user: ["device2"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
self.assertEqual(channel.json_body["device_keys"], {"@mikey:test": {}})
|
||||||
|
|
||||||
|
# check that an old device is deleted when user PUTs a new device
|
||||||
|
# First, create a device
|
||||||
|
content["device_id"] = "device3"
|
||||||
|
content["device_keys"]["device_id"] = "device3"
|
||||||
|
channel = self.make_request(
|
||||||
|
"PUT",
|
||||||
|
"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device",
|
||||||
|
content=content,
|
||||||
|
access_token=token,
|
||||||
|
shorthand=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(channel.code, 200)
|
||||||
|
device_id = channel.json_body.get("device_id")
|
||||||
|
assert device_id is not None
|
||||||
|
self.assertIsInstance(device_id, str)
|
||||||
|
self.assertEqual("device3", device_id)
|
||||||
|
|
||||||
|
# create a second device without deleting first device
|
||||||
|
content["device_id"] = "device4"
|
||||||
|
content["device_keys"]["device_id"] = "device4"
|
||||||
|
channel = self.make_request(
|
||||||
|
"PUT",
|
||||||
|
"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device",
|
||||||
|
content=content,
|
||||||
|
access_token=token,
|
||||||
|
shorthand=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(channel.code, 200)
|
||||||
|
device_id = channel.json_body.get("device_id")
|
||||||
|
assert device_id is not None
|
||||||
|
self.assertIsInstance(device_id, str)
|
||||||
|
self.assertEqual("device4", device_id)
|
||||||
|
|
||||||
|
# check that the second device that was created is what is returned when we GET
|
||||||
|
channel = self.make_request(
|
||||||
|
"GET",
|
||||||
|
"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device",
|
||||||
|
access_token=token,
|
||||||
|
shorthand=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(channel.code, 200)
|
||||||
|
returned_device_id = channel.json_body["device_id"]
|
||||||
|
self.assertEqual(returned_device_id, "device4")
|
||||||
|
|
||||||
|
# and that if we query the keys for the first device they are not there
|
||||||
|
channel = self.make_request(
|
||||||
|
"POST",
|
||||||
|
"/_matrix/client/r0/keys/query",
|
||||||
|
{
|
||||||
|
"device_keys": {
|
||||||
|
user: ["device3"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
self.assertEqual(channel.json_body["device_keys"], {"@mikey:test": {}})
|
||||||
|
|
Loading…
Reference in a new issue