ソースを参照

Fix deletion for Dehydrated Devices (#16046)

tags/v1.90.0rc1
Shay 9ヶ月前
committed by GitHub
コミット
84ae2e3f6f
この署名に対応する既知のキーがデータベースに存在しません GPGキーID: 4AEE18F83AFDEB23
4個のファイルの変更165行の追加5行の削除
  1. +1
    -0
      changelog.d/16046.bugfix
  2. +16
    -0
      synapse/handlers/device.py
  3. +10
    -4
      synapse/rest/client/devices.py
  4. +138
    -1
      tests/rest/client/test_devices.py

+ 1
- 0
changelog.d/16046.bugfix ファイルの表示

@@ -0,0 +1 @@
Fix deletion in dehydrated devices v2.

+ 16
- 0
synapse/handlers/device.py ファイルの表示

@@ -722,6 +722,22 @@ class DeviceHandler(DeviceWorkerHandler):

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")
async def _handle_new_device_update_async(self) -> None:
"""Called when we have a new local device list update that we need to


+ 10
- 4
synapse/rest/client/devices.py ファイルの表示

@@ -513,10 +513,8 @@ class DehydratedDeviceV2Servlet(RestServlet):
if dehydrated_device is not None:
(device_id, device_data) = dehydrated_device

result = await self.device_handler.rehydrate_device(
requester.user.to_string(),
self.auth.get_access_token_from_request(request),
device_id,
await self.device_handler.delete_dehydrated_device(
requester.user.to_string(), device_id
)

result = {"device_id": device_id}
@@ -538,6 +536,14 @@ class DehydratedDeviceV2Servlet(RestServlet):
requester = await self.auth.get_user_by_req(request)
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()
if "device_keys" not in device_info.keys():
raise SynapseError(


+ 138
- 1
tests/rest/client/test_devices.py ファイルの表示

@@ -379,4 +379,141 @@ class DehydratedDeviceTestCase(unittest.HomeserverTestCase):
access_token=token,
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": {}})

読み込み中…
キャンセル
保存