From d296cdc9ddb799e8354dae4308a01b0984933186 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 30 Apr 2019 15:15:02 +0100 Subject: Add bulk lookup --- synapse/handlers/identity.py | 46 ++++++++++++++++++++++++++++++++- synapse/rest/client/v2_alpha/account.py | 27 ++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index d2039e2825..910f572a1d 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -347,7 +347,7 @@ class IdentityHandler(BaseHandler): Returns: Deferred[dict]: The result of the lookup. See - https://matrix.org/docs/spec/identity_service/r0.1.0.html#id15 + https://matrix.org/docs/spec/identity_service/r0.1.0.html#association-lookup for details """ if not self._enable_lookup: @@ -380,6 +380,50 @@ class IdentityHandler(BaseHandler): defer.returnValue(data) + @defer.inlineCallbacks + def bulk_lookup_3pid(self, id_server, threepids): + """Looks up a 3pid in the passed identity server. + + Args: + id_server (str): The server name (including port, if required) + of the identity server to use. + threepids ([[str, str]]): The third party identifiers to lookup, as + a list of 2-string sized lists ([medium, address]). + + Returns: + Deferred[dict]: The result of the lookup. See + https://matrix.org/docs/spec/identity_service/r0.1.0.html#association-lookup + for details + """ + if not self._enable_lookup: + raise AuthError( + 403, "Looking up third-party identifiers is denied from this server", + ) + + target = self.rewrite_identity_server_urls.get(id_server, id_server) + + try: + data = yield self.http_client.get_json( + "https://%s/_matrix/identity/api/v1/lookup" % (target,), + { + "threepids": threepids, + } + ) + + if "mxid" in data: + if "signatures" not in data: + raise AuthError(401, "No signatures on 3pid bindings") + yield self._verify_any_signature(data, id_server) + + except HttpResponseException as e: + logger.info("Proxied lookup failed: %r", e) + raise e.to_synapse_error() + except IOError as e: + logger.info("Failed to contact %r: %s", id_server, e) + raise ProxiedRequestError(503, "Failed to contact homeserver") + + defer.returnValue(data) + @defer.inlineCallbacks def _verify_any_signature(self, data, server_hostname): if server_hostname not in data["signatures"]: diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 752ea265bd..de9e2cd5f1 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Copyright 2015, 2016 OpenMarket Ltd # Copyright 2017 Vector Creations Ltd -# Copyright 2018 New Vector Ltd +# Copyright 2018, 2019 New Vector Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -512,6 +512,31 @@ class ThreepidLookupRestServlet(RestServlet): respond_with_json(200, ret) +class ThreepidBulkLookupRestServlet(RestServlet): + PATTERNS = client_v2_patterns("/account/3pid/bulk_lookup$") + + def __init__(self, hs): + super(ThreepidLookupRestServlet, self).__init__() + self.config = hs.config + self.auth = hs.get_auth() + self.identity_handler = IdentityHandler(hs) + + @defer.inlineCallbacks + def on_GET(self, request): + """Proxy a /_matrix/identity/api/v1/bulk_lookup request to an identity + server + """ + yield self.auth.get_user_by_req(request) + + body = parse_json_object_from_request(request) + + # Proxy the request to the identity server. lookup_3pid handles checking + # if the lookup is allowed so we don't need to do it here. + ret = yield self.identity_handler.bulk_lookup_3pid(id_server, body["threepids"]) + + respond_with_json(200, ret) + + class WhoamiRestServlet(RestServlet): PATTERNS = client_v2_patterns("/account/whoami$") -- cgit 1.5.1