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

Dehydrated devices #8380

Merged
merged 28 commits into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
52ddb79
initial version of dehydration
uhoreg Jul 24, 2020
e60a99d
run black
uhoreg Jul 27, 2020
0f9e402
add changelog
uhoreg Jul 27, 2020
b59bc66
minor fixes
uhoreg Aug 4, 2020
96d9fc3
maybe this will make lint happy?
uhoreg Aug 4, 2020
460ebc5
Merge remote-tracking branch 'origin/develop' into dehydration
uhoreg Aug 5, 2020
c7c8f28
newer version of dehydration proposal, add doc improvements and other…
uhoreg Aug 17, 2020
b7398f7
fix nonexistent reference
uhoreg Sep 3, 2020
355f123
implement alternative dehydration API
uhoreg Sep 22, 2020
037c201
remove unneeded table
uhoreg Sep 22, 2020
a84e491
move rest endpoint to devices and tweak endpoint names
uhoreg Sep 29, 2020
24405c7
some fixes
uhoreg Sep 30, 2020
bb7c732
invalidate cache and clear old device when setting new device ID
uhoreg Sep 30, 2020
6110a6a
run black
uhoreg Sep 30, 2020
7029d97
add unit tests
uhoreg Sep 30, 2020
90f42ad
lint and fix changelog
uhoreg Sep 30, 2020
3a27b74
Merge remote-tracking branch 'origin/develop' into dehydration2
uhoreg Sep 30, 2020
f63d6c0
adjust copyright headers
uhoreg Sep 30, 2020
2b30fc7
black
uhoreg Sep 30, 2020
8e5ef16
Apply suggestions from code review
uhoreg Oct 2, 2020
5935477
apply suggestions from review
uhoreg Oct 2, 2020
e69835e
Apply suggestions from code review
uhoreg Oct 5, 2020
b934fde
fix a couple incorrect names
uhoreg Oct 5, 2020
0b34ac0
update display name when dehydrating device
uhoreg Oct 5, 2020
a87cb40
black
uhoreg Oct 5, 2020
2a10d7a
fix comments
uhoreg Oct 5, 2020
f37f6a0
apply changes from review
uhoreg Oct 6, 2020
92ba279
Merge remote-tracking branch 'origin/develop' into dehydration2
uhoreg Oct 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion synapse/handlers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,9 @@ async def store_dehydrated_device(
await self.delete_device(user_id, old_device_id)
return device_id

async def get_dehydrated_device(self, user_id: str) -> Tuple[str, JsonDict]:
async def get_dehydrated_device(
self, user_id: str
) -> Optional[Tuple[str, JsonDict]]:
"""Retrieve the information for a dehydrated device.

Args:
Expand Down
42 changes: 32 additions & 10 deletions synapse/rest/client/v2_alpha/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class DehydratedDeviceServlet(RestServlet):

"""

PATTERNS = client_patterns("/org.matrix.msc2697.v2/dehydrated_device")
PATTERNS = client_patterns("/org.matrix.msc2697.v2/dehydrated_device", releases=())

def __init__(self, hs):
super(DehydratedDeviceServlet, self).__init__()
clokep marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -197,21 +197,32 @@ def __init__(self, hs):
self.device_handler = hs.get_device_handler()

async def on_GET(self, request: SynapseRequest):
requester = await self.auth.get_user_by_req(request, allow_guest=True)
(
device_id,
dehydrated_device,
) = await self.device_handler.get_dehydrated_device(requester.user.to_string())
if dehydrated_device:
requester = await self.auth.get_user_by_req(request)
dehydrated_device = await self.device_handler.get_dehydrated_device(
requester.user.to_string()
)
if dehydrated_device is not None:
(device_id, device_data) = dehydrated_device
result = {"device_id": device_id, "device_data": dehydrated_device}
return (200, result)
else:
raise errors.NotFoundError()
raise errors.NotFoundError("No dehydrated device available")

async def on_PUT(self, request: SynapseRequest):
submission = parse_json_object_from_request(request)
requester = await self.auth.get_user_by_req(request)

if "device_data" not in submission:
raise errors.SynapseError(
400, "device_data missing", errcode=errors.Codes.MISSING_PARAM,
)
elif isinstance(submission["device_id"], dict):
uhoreg marked this conversation as resolved.
Show resolved Hide resolved
raise errors.SynapseError(
400,
"device_data must be an object",
errcode=errors.Codes.INVALID_PARAM,
)

device_id = await self.device_handler.store_dehydrated_device(
requester.user.to_string(),
submission["device_data"],
clokep marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -239,7 +250,9 @@ class ClaimDehydratedDeviceServlet(RestServlet):

"""

PATTERNS = client_patterns("/org.matrix.msc2697.v2/dehydrated_device/claim")
PATTERNS = client_patterns(
"/org.matrix.msc2697.v2/dehydrated_device/claim", releases=()
)

def __init__(self, hs):
super(ClaimDehydratedDeviceServlet, self).__init__()
clokep marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -248,10 +261,19 @@ def __init__(self, hs):
self.device_handler = hs.get_device_handler()

async def on_POST(self, request: SynapseRequest):
requester = await self.auth.get_user_by_req(request, allow_guest=True)
requester = await self.auth.get_user_by_req(request)

submission = parse_json_object_from_request(request)

if "device_id" not in submission:
raise errors.SynapseError(
400, "device_id missing", errcode=errors.Codes.MISSING_PARAM,
)
elif isinstance(submission["device_id"], str):
uhoreg marked this conversation as resolved.
Show resolved Hide resolved
raise errors.SynapseError(
400, "device_id must be a string", errcode=errors.Codes.INVALID_PARAM,
)

result = await self.device_handler.rehydrate_device(
requester.user.to_string(),
self.auth.get_access_token_from_request(request),
Expand Down
14 changes: 7 additions & 7 deletions synapse/rest/client/v2_alpha/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ async def on_POST(self, request, device_id):
body = parse_json_object_from_request(request)

if device_id is not None:
# passing the device_id here is deprecated; however, we allow it
# for now for compatibility with older clients.
# passing the device_id here should only be done for setting keys
# for dehydrated devices; however, we allow it for now for
# compatibility with older clients.
uhoreg marked this conversation as resolved.
Show resolved Hide resolved
if requester.device_id is not None and device_id != requester.device_id:
(
dehydrated_device_id,
_,
) = await self.device_handler.get_dehydrated_device(user_id)
if device_id != dehydrated_device_id:
dehydrated_device = await self.device_handler.get_dehydrated_device(
user_id
)
if dehydrated_device is not None and device_id != dehydrated_device[0]:
set_tag("error", True)
log_kv(
{
Expand Down
33 changes: 11 additions & 22 deletions synapse/storage/databases/main/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,9 @@ def _mark_remote_user_device_list_as_unsubscribed_txn(txn):
_mark_remote_user_device_list_as_unsubscribed_txn,
)

async def get_dehydrated_device(self, user_id: str) -> Tuple[str, JsonDict]:
async def get_dehydrated_device(
self, user_id: str
) -> Optional[Tuple[str, JsonDict]]:
"""Retrieve the information for a dehydrated device.

Args:
Expand All @@ -715,9 +717,7 @@ async def get_dehydrated_device(self, user_id: str) -> Tuple[str, JsonDict]:
allow_none=True,
)
return (
(row["device_id"], json_decoder.decode(row["device_data"]))
if row
else (None, None)
(row["device_id"], json_decoder.decode(row["device_data"])) if row else None
)

def _store_dehydrated_device_txn(
Expand All @@ -730,23 +730,12 @@ def _store_dehydrated_device_txn(
retcol="device_id",
allow_none=True,
)
if old_device_id is None:
self.db_pool.simple_insert_txn(
txn,
table="dehydrated_devices",
values={
"user_id": user_id,
"device_id": device_id,
"device_data": device_data,
},
)
else:
self.db_pool.simple_update_txn(
txn,
table="dehydrated_devices",
keyvalues={"user_id": user_id},
updatevalues={"device_id": device_id, "device_data": device_data},
)
self.db_pool.simple_upsert_txn(
txn,
table="dehydrated_devices",
keyvalues={"user_id": user_id},
values={"device_id": device_id, "device_data": device_data},
)
return old_device_id

async def store_dehydrated_device(
Expand All @@ -756,8 +745,8 @@ async def store_dehydrated_device(

Args:
user_id: the user that we are storing the device for
device_id: the ID of the dehydrated device
device_data: the dehydrated device information
initial_device_display_name: The display name to use for the device
Returns:
device id of the user's previous dehydrated device, if any
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
CREATE TABLE IF NOT EXISTS dehydrated_devices(
user_id TEXT NOT NULL PRIMARY KEY,
device_id TEXT NOT NULL,
device_data TEXT NOT NULL
device_data TEXT NOT NULL -- JSON-encoded client-defined data
);
2 changes: 1 addition & 1 deletion tests/handlers/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,4 @@ def test_dehydrate_and_rehydrate_device(self):
# make sure that there's no device available for dehydrating now
ret = self.get_success(self.handler.get_dehydrated_device(user_id=user_id))

self.assertEqual(ret, (None, None))
self.assertEqual(ret, None)
uhoreg marked this conversation as resolved.
Show resolved Hide resolved