Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Fix using dehydrated devices (MSC2697) & refresh tokens (#16288)
Browse files Browse the repository at this point in the history
Refresh tokens were not correctly moved to the rehydrated
device (similar to how the access token is currently handled).
This resulted in invalid refresh tokens after rehydration.
  • Loading branch information
hanadi92 committed Sep 13, 2023
1 parent d38d0df commit 7afb5e0
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 4 deletions.
1 change: 1 addition & 0 deletions changelog.d/16288.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix bug introduced in Synapse 1.49.0 when using dehydrated devices ([MSC2697](https://github.com/matrix-org/matrix-spec-proposals/pull/2697)) and refresh tokens. Contributed by Hanadi.
7 changes: 4 additions & 3 deletions synapse/handlers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,12 +758,13 @@ async def rehydrate_device(

# If the dehydrated device was successfully deleted (the device ID
# matched the stored dehydrated device), then modify the access
# token to use the dehydrated device's ID and copy the old device
# display name to the dehydrated device, and destroy the old device
# ID
# token and refresh token to use the dehydrated device's ID and
# copy the old device display name to the dehydrated device,
# and destroy the old device ID
old_device_id = await self.store.set_device_for_access_token(
access_token, device_id
)
await self.store.set_device_for_refresh_token(user_id, old_device_id, device_id)
old_device = await self.store.get_device(user_id, old_device_id)
if old_device is None:
raise errors.NotFoundError()
Expand Down
20 changes: 20 additions & 0 deletions synapse/storage/databases/main/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2312,6 +2312,26 @@ async def add_refresh_token_to_user(

return next_id

async def set_device_for_refresh_token(
self, user_id: str, old_device_id: str, device_id: str
) -> None:
"""Moves refresh tokens from old device to current device
Args:
user_id: The user of the devices.
old_device_id: The old device.
device_id: The new device ID.
Returns:
None
"""

await self.db_pool.simple_update(
"refresh_tokens",
keyvalues={"user_id": user_id, "device_id": old_device_id},
updatevalues={"device_id": device_id},
desc="set_device_for_refresh_token",
)

def _set_device_for_access_token_txn(
self, txn: LoggingTransaction, token: str, device_id: str
) -> str:
Expand Down
10 changes: 9 additions & 1 deletion tests/handlers/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
self.message_handler = hs.get_device_message_handler()
self.registration = hs.get_registration_handler()
self.auth = hs.get_auth()
self.auth_handler = hs.get_auth_handler()
self.store = hs.get_datastores().main
return hs

Expand All @@ -487,11 +488,12 @@ def test_dehydrate_and_rehydrate_device(self) -> None:
self.assertEqual(device_data, {"device_data": {"foo": "bar"}})

# Create a new login for the user and dehydrated the device
device_id, access_token, _expiration_time, _refresh_token = self.get_success(
device_id, access_token, _expiration_time, refresh_token = self.get_success(
self.registration.register_device(
user_id=user_id,
device_id=None,
initial_display_name="new device",
should_issue_refresh_token=True,
)
)

Expand Down Expand Up @@ -522,6 +524,12 @@ def test_dehydrate_and_rehydrate_device(self) -> None:

self.assertEqual(user_info.device_id, retrieved_device_id)

# make sure the user device has the refresh token
assert refresh_token is not None
self.get_success(
self.auth_handler.refresh_token(refresh_token, 5 * 60 * 1000, 5 * 60 * 1000)
)

# make sure the device has the display name that was set from the login
res = self.get_success(self.handler.get_device(user_id, retrieved_device_id))

Expand Down

0 comments on commit 7afb5e0

Please sign in to comment.