From 8df16a8aeef3e169ca8795abe5fd9baac650f3bb Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 30 Apr 2019 14:36:35 +0100 Subject: Move lookup endpoint to CS API (and s/is_server/id_server/) --- synapse/rest/client/v2_alpha/account.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'synapse/rest/client') diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 7e5884df0c..752ea265bd 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -480,6 +480,38 @@ class ThreepidDeleteRestServlet(RestServlet): ) +class ThreepidLookupRestServlet(RestServlet): + PATTERNS = client_v2_patterns("/account/3pid/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/lookup request to an identity + server + """ + yield self.auth.get_user_by_req(request) + + # Extract query parameters + query_params = request.args + assert_params_in_dict(query_params, [b"medium", b"address", b"id_server"]) + + # Retrieve address and medium from the request parameters + medium = parse_string(request, "medium") + address = parse_string(request, "address") + id_server = parse_string(request, "id_server") + + # 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.lookup_3pid(id_server, medium, address) + + respond_with_json(200, ret) + + class WhoamiRestServlet(RestServlet): PATTERNS = client_v2_patterns("/account/whoami$") -- cgit 1.5.1 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(-) (limited to 'synapse/rest/client') 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 From 2d979e639da9e6757b58cf10f8a47e58105c3720 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 30 Apr 2019 16:51:50 +0100 Subject: Register servlets --- synapse/rest/client/v2_alpha/account.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'synapse/rest/client') diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index de9e2cd5f1..cdf499af6d 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -560,4 +560,6 @@ def register_servlets(hs, http_server): MsisdnThreepidRequestTokenRestServlet(hs).register(http_server) ThreepidRestServlet(hs).register(http_server) ThreepidDeleteRestServlet(hs).register(http_server) + ThreepidLookupRestServlet(hs).register(http_server) + ThreepidBulkLookupRestServlet(hs).register(http_server) WhoamiRestServlet(hs).register(http_server) -- cgit 1.5.1 From 34bbbe81a605655c3d2a548a34a94a93b621ad48 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 30 Apr 2019 16:59:46 +0100 Subject: Fix method --- synapse/rest/client/v2_alpha/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client') diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index cdf499af6d..f3707068bb 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -522,7 +522,7 @@ class ThreepidBulkLookupRestServlet(RestServlet): self.identity_handler = IdentityHandler(hs) @defer.inlineCallbacks - def on_GET(self, request): + def on_POST(self, request): """Proxy a /_matrix/identity/api/v1/bulk_lookup request to an identity server """ -- cgit 1.5.1 From 70da5202ba2c88333b18c1968e446d3dd0268282 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 30 Apr 2019 17:27:47 +0100 Subject: Fixes --- synapse/rest/client/v2_alpha/account.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'synapse/rest/client') diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index f3707068bb..f7110f3b40 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -26,6 +26,7 @@ from synapse.http.servlet import ( RestServlet, assert_params_in_dict, parse_json_object_from_request, + parse_string, ) from synapse.types import UserID from synapse.util.msisdn import phone_number_to_msisdn @@ -487,7 +488,7 @@ class ThreepidLookupRestServlet(RestServlet): super(ThreepidLookupRestServlet, self).__init__() self.config = hs.config self.auth = hs.get_auth() - self.identity_handler = IdentityHandler(hs) + self.identity_handler = hs.get_handlers().identity_handler @defer.inlineCallbacks def on_GET(self, request): @@ -516,10 +517,10 @@ class ThreepidBulkLookupRestServlet(RestServlet): PATTERNS = client_v2_patterns("/account/3pid/bulk_lookup$") def __init__(self, hs): - super(ThreepidLookupRestServlet, self).__init__() + super(ThreepidBulkLookupRestServlet, self).__init__() self.config = hs.config self.auth = hs.get_auth() - self.identity_handler = IdentityHandler(hs) + self.identity_handler = hs.get_handlers().identity_handler @defer.inlineCallbacks def on_POST(self, request): @@ -532,7 +533,9 @@ class ThreepidBulkLookupRestServlet(RestServlet): # 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"]) + ret = yield self.identity_handler.bulk_lookup_3pid( + body["id_server"], body["threepids"], + ) respond_with_json(200, ret) -- cgit 1.5.1 From fe6ac9c5d709053abdd7a72297aaa64e6aa8e8fb Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 30 Apr 2019 18:28:01 +0100 Subject: Fixed return value --- synapse/rest/client/v2_alpha/account.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'synapse/rest/client') diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index f7110f3b40..bf5d28b6e3 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -510,7 +510,7 @@ class ThreepidLookupRestServlet(RestServlet): # if the lookup is allowed so we don't need to do it here. ret = yield self.identity_handler.lookup_3pid(id_server, medium, address) - respond_with_json(200, ret) + defer.returnValue((200, ret)) class ThreepidBulkLookupRestServlet(RestServlet): @@ -537,7 +537,7 @@ class ThreepidBulkLookupRestServlet(RestServlet): body["id_server"], body["threepids"], ) - respond_with_json(200, ret) + defer.returnValue((200, ret)) class WhoamiRestServlet(RestServlet): -- cgit 1.5.1 From 26c004129fcb26f5e1d91f65194fa276a4b0bdc5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 1 May 2019 10:01:57 +0100 Subject: Update synapse/rest/client/v2_alpha/account.py Co-Authored-By: babolivier --- synapse/rest/client/v2_alpha/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client') diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index bf5d28b6e3..fc3d0e789e 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -501,7 +501,7 @@ class ThreepidLookupRestServlet(RestServlet): query_params = request.args assert_params_in_dict(query_params, [b"medium", b"address", b"id_server"]) - # Retrieve address and medium from the request parameters + # Retrieve needed information from query parameters medium = parse_string(request, "medium") address = parse_string(request, "address") id_server = parse_string(request, "id_server") -- cgit 1.5.1 From 1973eb11d2d2392096f8be7fd17d947b8ffd0ec2 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 1 May 2019 10:02:18 +0100 Subject: Update synapse/rest/client/v2_alpha/account.py Co-Authored-By: babolivier --- synapse/rest/client/v2_alpha/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'synapse/rest/client') diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index fc3d0e789e..154700d7d1 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -497,7 +497,7 @@ class ThreepidLookupRestServlet(RestServlet): """ yield self.auth.get_user_by_req(request) - # Extract query parameters + # Verify query parameters query_params = request.args assert_params_in_dict(query_params, [b"medium", b"address", b"id_server"]) -- cgit 1.5.1 From b4f3d70b212b60576c12e99f62b53df169467067 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 7 May 2019 11:47:37 +0100 Subject: Incorporate review --- synapse/handlers/identity.py | 2 +- synapse/rest/client/v2_alpha/account.py | 2 ++ tests/rest/client/test_identity.py | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'synapse/rest/client') diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index 5b610990b6..dc77b6786f 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -403,7 +403,7 @@ class IdentityHandler(BaseHandler): target = self.rewrite_identity_server_urls.get(id_server, id_server) try: - data = yield self.http_client.post_json( + data = yield self.http_client.post_json_get_json( "https://%s/_matrix/identity/api/v1/bulk_lookup" % (target,), { "threepids": threepids, diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 154700d7d1..f1037ce115 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -531,6 +531,8 @@ class ThreepidBulkLookupRestServlet(RestServlet): body = parse_json_object_from_request(request) + assert_params_in_dict(body, ["threepids", "id_server"]) + # 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( diff --git a/tests/rest/client/test_identity.py b/tests/rest/client/test_identity.py index c1b1b11202..ed149f3600 100644 --- a/tests/rest/client/test_identity.py +++ b/tests/rest/client/test_identity.py @@ -115,10 +115,10 @@ class IdentityEnabledTestCase(unittest.HomeserverTestCase): mock_http_client = Mock(spec=[ "get_json", - "post_json", + "post_json_get_json", ]) mock_http_client.get_json.return_value = defer.succeed((200, "{}")) - mock_http_client.post_json.return_value = defer.succeed((200, "{}")) + mock_http_client.post_json_get_json.return_value = defer.succeed((200, "{}")) self.hs = self.setup_test_homeserver( config=config, @@ -198,7 +198,7 @@ class IdentityEnabledTestCase(unittest.HomeserverTestCase): ) self.render(request) - post_json = self.hs.get_simple_http_client().post_json + post_json = self.hs.get_simple_http_client().post_json_get_json post_json.assert_called_once_with( "https://testis/_matrix/identity/api/v1/bulk_lookup", { -- cgit 1.5.1 From f304f1a574a7114ad4ccc335563d1ecb3eb49501 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Thu, 9 May 2019 13:07:43 +0100 Subject: Incorporate review --- synapse/handlers/identity.py | 2 +- synapse/rest/client/v2_alpha/account.py | 7 +++---- tests/rest/client/test_identity.py | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'synapse/rest/client') diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index b4c6e94777..f39803629e 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -388,7 +388,7 @@ class IdentityHandler(BaseHandler): @defer.inlineCallbacks def bulk_lookup_3pid(self, id_server, threepids): - """Looks up a 3pid in the passed identity server. + """Looks up given 3pids in the passed identity server. Args: id_server (str): The server name (including port, if required) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index f1037ce115..08079a9bc6 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -15,6 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging +import re from six.moves import http_client @@ -482,11 +483,10 @@ class ThreepidDeleteRestServlet(RestServlet): class ThreepidLookupRestServlet(RestServlet): - PATTERNS = client_v2_patterns("/account/3pid/lookup$") + PATTERNS = [re.compile("^/_matrix/client/unstable/account/3pid/lookup$")] def __init__(self, hs): super(ThreepidLookupRestServlet, self).__init__() - self.config = hs.config self.auth = hs.get_auth() self.identity_handler = hs.get_handlers().identity_handler @@ -514,11 +514,10 @@ class ThreepidLookupRestServlet(RestServlet): class ThreepidBulkLookupRestServlet(RestServlet): - PATTERNS = client_v2_patterns("/account/3pid/bulk_lookup$") + PATTERNS = [re.compile("^/_matrix/client/unstable/account/3pid/bulk_lookup$")] def __init__(self, hs): super(ThreepidBulkLookupRestServlet, self).__init__() - self.config = hs.config self.auth = hs.get_auth() self.identity_handler = hs.get_handlers().identity_handler diff --git a/tests/rest/client/test_identity.py b/tests/rest/client/test_identity.py index 7edcfa8f67..b942f1ffe6 100644 --- a/tests/rest/client/test_identity.py +++ b/tests/rest/client/test_identity.py @@ -26,6 +26,7 @@ from tests import unittest class IdentityDisabledTestCase(unittest.HomeserverTestCase): + """Tests that 3PID lookup attempts fail when the HS's config disallows them.""" servlets = [ account.register_servlets, @@ -104,6 +105,7 @@ class IdentityDisabledTestCase(unittest.HomeserverTestCase): class IdentityEnabledTestCase(unittest.HomeserverTestCase): + """Tests that 3PID lookup attempts succeed when the HS's config allows them.""" servlets = [ account.register_servlets, -- cgit 1.5.1