mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-06 21:34:56 -04:00
Add support for MSC2697: Dehydrated devices (#8380)
This allows a user to store an offline device on the server and then restore it at a subsequent login.
This commit is contained in:
parent
43c622885c
commit
4cb44a1585
9 changed files with 454 additions and 21 deletions
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2015, 2016 OpenMarket Ltd
|
||||
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -21,6 +22,7 @@ from synapse.http.servlet import (
|
|||
assert_params_in_dict,
|
||||
parse_json_object_from_request,
|
||||
)
|
||||
from synapse.http.site import SynapseRequest
|
||||
|
||||
from ._base import client_patterns, interactive_auth_handler
|
||||
|
||||
|
@ -151,7 +153,139 @@ class DeviceRestServlet(RestServlet):
|
|||
return 200, {}
|
||||
|
||||
|
||||
class DehydratedDeviceServlet(RestServlet):
|
||||
"""Retrieve or store a dehydrated device.
|
||||
|
||||
GET /org.matrix.msc2697.v2/dehydrated_device
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"device_id": "dehydrated_device_id",
|
||||
"device_data": {
|
||||
"algorithm": "org.matrix.msc2697.v1.dehydration.v1.olm",
|
||||
"account": "dehydrated_device"
|
||||
}
|
||||
}
|
||||
|
||||
PUT /org.matrix.msc2697/dehydrated_device
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"device_data": {
|
||||
"algorithm": "org.matrix.msc2697.v1.dehydration.v1.olm",
|
||||
"account": "dehydrated_device"
|
||||
}
|
||||
}
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"device_id": "dehydrated_device_id"
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
PATTERNS = client_patterns("/org.matrix.msc2697.v2/dehydrated_device", releases=())
|
||||
|
||||
def __init__(self, hs):
|
||||
super().__init__()
|
||||
self.hs = hs
|
||||
self.auth = hs.get_auth()
|
||||
self.device_handler = hs.get_device_handler()
|
||||
|
||||
async def on_GET(self, request: SynapseRequest):
|
||||
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": device_data}
|
||||
return (200, result)
|
||||
else:
|
||||
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 not isinstance(submission["device_data"], dict):
|
||||
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"],
|
||||
submission.get("initial_device_display_name", None),
|
||||
)
|
||||
return 200, {"device_id": device_id}
|
||||
|
||||
|
||||
class ClaimDehydratedDeviceServlet(RestServlet):
|
||||
"""Claim a dehydrated device.
|
||||
|
||||
POST /org.matrix.msc2697.v2/dehydrated_device/claim
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"device_id": "dehydrated_device_id"
|
||||
}
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"success": true,
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
PATTERNS = client_patterns(
|
||||
"/org.matrix.msc2697.v2/dehydrated_device/claim", releases=()
|
||||
)
|
||||
|
||||
def __init__(self, hs):
|
||||
super().__init__()
|
||||
self.hs = hs
|
||||
self.auth = hs.get_auth()
|
||||
self.device_handler = hs.get_device_handler()
|
||||
|
||||
async def on_POST(self, request: SynapseRequest):
|
||||
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 not isinstance(submission["device_id"], str):
|
||||
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),
|
||||
submission["device_id"],
|
||||
)
|
||||
|
||||
return (200, result)
|
||||
|
||||
|
||||
def register_servlets(hs, http_server):
|
||||
DeleteDevicesRestServlet(hs).register(http_server)
|
||||
DevicesRestServlet(hs).register(http_server)
|
||||
DeviceRestServlet(hs).register(http_server)
|
||||
DehydratedDeviceServlet(hs).register(http_server)
|
||||
ClaimDehydratedDeviceServlet(hs).register(http_server)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue