diff --git a/synapse/rest/client/v1/login.py b/synapse/rest/client/v1/login.py
index e8b791519c..92fcae674a 100644
--- a/synapse/rest/client/v1/login.py
+++ b/synapse/rest/client/v1/login.py
@@ -152,7 +152,10 @@ class LoginRestServlet(ClientV1RestServlet):
)
device_id = yield self._register_device(user_id, login_submission)
access_token, refresh_token = (
- yield auth_handler.get_login_tuple_for_user_id(user_id, device_id)
+ yield auth_handler.get_login_tuple_for_user_id(
+ user_id, device_id,
+ login_submission.get("initial_device_display_name")
+ )
)
result = {
"user_id": user_id, # may have changed
@@ -173,7 +176,10 @@ class LoginRestServlet(ClientV1RestServlet):
)
device_id = yield self._register_device(user_id, login_submission)
access_token, refresh_token = (
- yield auth_handler.get_login_tuple_for_user_id(user_id, device_id)
+ yield auth_handler.get_login_tuple_for_user_id(
+ user_id, device_id,
+ login_submission.get("initial_device_display_name")
+ )
)
result = {
"user_id": user_id, # may have changed
@@ -262,7 +268,8 @@ class LoginRestServlet(ClientV1RestServlet):
)
access_token, refresh_token = (
yield auth_handler.get_login_tuple_for_user_id(
- registered_user_id, device_id
+ registered_user_id, device_id,
+ login_submission.get("initial_device_display_name")
)
)
result = {
diff --git a/synapse/rest/client/v2_alpha/devices.py b/synapse/rest/client/v2_alpha/devices.py
index 8b9ab4f674..8fbd3d3dfc 100644
--- a/synapse/rest/client/v2_alpha/devices.py
+++ b/synapse/rest/client/v2_alpha/devices.py
@@ -13,19 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from twisted.internet import defer
+import logging
-from synapse.http.servlet import RestServlet
+from twisted.internet import defer
+from synapse.http import servlet
from ._base import client_v2_patterns
-import logging
-
-
logger = logging.getLogger(__name__)
-class DevicesRestServlet(RestServlet):
+class DevicesRestServlet(servlet.RestServlet):
PATTERNS = client_v2_patterns("/devices$", releases=[], v2_alpha=False)
def __init__(self, hs):
@@ -47,7 +45,7 @@ class DevicesRestServlet(RestServlet):
defer.returnValue((200, {"devices": devices}))
-class DeviceRestServlet(RestServlet):
+class DeviceRestServlet(servlet.RestServlet):
PATTERNS = client_v2_patterns("/devices/(?P<device_id>[^/]*)$",
releases=[], v2_alpha=False)
@@ -70,6 +68,32 @@ class DeviceRestServlet(RestServlet):
)
defer.returnValue((200, device))
+ @defer.inlineCallbacks
+ def on_DELETE(self, request, device_id):
+ # XXX: it's not completely obvious we want to expose this endpoint.
+ # It allows the client to delete access tokens, which feels like a
+ # thing which merits extra auth. But if we want to do the interactive-
+ # auth dance, we should really make it possible to delete more than one
+ # device at a time.
+ requester = yield self.auth.get_user_by_req(request)
+ yield self.device_handler.delete_device(
+ requester.user.to_string(),
+ device_id,
+ )
+ defer.returnValue((200, {}))
+
+ @defer.inlineCallbacks
+ def on_PUT(self, request, device_id):
+ requester = yield self.auth.get_user_by_req(request)
+
+ body = servlet.parse_json_object_from_request(request)
+ yield self.device_handler.update_device(
+ requester.user.to_string(),
+ device_id,
+ body
+ )
+ defer.returnValue((200, {}))
+
def register_servlets(hs, http_server):
DevicesRestServlet(hs).register(http_server)
diff --git a/synapse/rest/client/v2_alpha/keys.py b/synapse/rest/client/v2_alpha/keys.py
index 89ab39491c..dc1d4d8fc6 100644
--- a/synapse/rest/client/v2_alpha/keys.py
+++ b/synapse/rest/client/v2_alpha/keys.py
@@ -13,24 +13,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
+
+import simplejson as json
+from canonicaljson import encode_canonical_json
from twisted.internet import defer
+import synapse.api.errors
+import synapse.server
+import synapse.types
from synapse.http.servlet import RestServlet, parse_json_object_from_request
from synapse.types import UserID
-
-from canonicaljson import encode_canonical_json
-
from ._base import client_v2_patterns
-import logging
-import simplejson as json
-
logger = logging.getLogger(__name__)
class KeyUploadServlet(RestServlet):
"""
- POST /keys/upload/<device_id> HTTP/1.1
+ POST /keys/upload HTTP/1.1
Content-Type: application/json
{
@@ -53,23 +54,45 @@ class KeyUploadServlet(RestServlet):
},
}
"""
- PATTERNS = client_v2_patterns("/keys/upload/(?P<device_id>[^/]*)", releases=())
+ PATTERNS = client_v2_patterns("/keys/upload(/(?P<device_id>[^/]+))?$",
+ releases=())
def __init__(self, hs):
+ """
+ Args:
+ hs (synapse.server.HomeServer): server
+ """
super(KeyUploadServlet, self).__init__()
self.store = hs.get_datastore()
self.clock = hs.get_clock()
self.auth = hs.get_auth()
+ self.device_handler = hs.get_device_handler()
@defer.inlineCallbacks
def on_POST(self, request, device_id):
requester = yield self.auth.get_user_by_req(request)
+
user_id = requester.user.to_string()
- # TODO: Check that the device_id matches that in the authentication
- # or derive the device_id from the authentication instead.
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.
+ if (requester.device_id is not None and
+ device_id != requester.device_id):
+ logger.warning("Client uploading keys for a different device "
+ "(logged in as %s, uploading for %s)",
+ requester.device_id, device_id)
+ else:
+ device_id = requester.device_id
+
+ if device_id is None:
+ raise synapse.api.errors.SynapseError(
+ 400,
+ "To upload keys, you must pass device_id when authenticating"
+ )
+
time_now = self.clock.time_msec()
# TODO: Validate the JSON to make sure it has the right keys.
@@ -102,13 +125,14 @@ class KeyUploadServlet(RestServlet):
user_id, device_id, time_now, key_list
)
- result = yield self.store.count_e2e_one_time_keys(user_id, device_id)
- defer.returnValue((200, {"one_time_key_counts": result}))
-
- @defer.inlineCallbacks
- def on_GET(self, request, device_id):
- requester = yield self.auth.get_user_by_req(request)
- user_id = requester.user.to_string()
+ # the device should have been registered already, but it may have been
+ # deleted due to a race with a DELETE request. Or we may be using an
+ # old access_token without an associated device_id. Either way, we
+ # need to double-check the device is registered to avoid ending up with
+ # keys without a corresponding device.
+ self.device_handler.check_device_registered(
+ user_id, device_id, "unknown device"
+ )
result = yield self.store.count_e2e_one_time_keys(user_id, device_id)
defer.returnValue((200, {"one_time_key_counts": result}))
diff --git a/synapse/rest/client/v2_alpha/register.py b/synapse/rest/client/v2_alpha/register.py
index c8c9395fc6..9f599ea8bb 100644
--- a/synapse/rest/client/v2_alpha/register.py
+++ b/synapse/rest/client/v2_alpha/register.py
@@ -374,13 +374,13 @@ class RegisterRestServlet(RestServlet):
"""
device_id = yield self._register_device(user_id, params)
- access_token = yield self.auth_handler.issue_access_token(
- user_id, device_id=device_id
+ access_token, refresh_token = (
+ yield self.auth_handler.get_login_tuple_for_user_id(
+ user_id, device_id=device_id,
+ initial_display_name=params.get("initial_device_display_name")
+ )
)
- refresh_token = yield self.auth_handler.issue_refresh_token(
- user_id, device_id=device_id
- )
defer.returnValue({
"user_id": user_id,
"access_token": access_token,
diff --git a/synapse/rest/client/versions.py b/synapse/rest/client/versions.py
index ca5468c402..e984ea47db 100644
--- a/synapse/rest/client/versions.py
+++ b/synapse/rest/client/versions.py
@@ -26,7 +26,11 @@ class VersionsRestServlet(RestServlet):
def on_GET(self, request):
return (200, {
- "versions": ["r0.0.1"]
+ "versions": [
+ "r0.0.1",
+ "r0.1.0",
+ "r0.2.0",
+ ]
})
|