From 56cec70b109917cacc18c5297903e457375db95c Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 20 Sep 2019 19:02:36 +0100 Subject: [PATCH 01/13] Add POST submit_token endpoint for MSISDN --- synapse/handlers/identity.py | 28 ++++++++++++++ synapse/rest/client/v2_alpha/account.py | 51 ++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index 156719e3087d..efeb4f29384b 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -447,6 +447,34 @@ def requestMsisdnToken( logger.info("Proxied requestToken failed: %r", e) raise e.to_synapse_error() + @defer.inlineCallbacks + def proxy_msisdn_submit_token(self, id_server, client_secret, sid, token): + """Proxy a POST submitToken request to an identity server for verification purposes + + Args: + id_server (str): The identity server URL to contact + + client_secret (str): Secret provided by the client + + sid (str): The ID of the session + + token (str): The verification token + + Raises: + SynapseError: If we failed to contact the identity server + + Returns: + The response dict from the identity server + """ + body = {"client_secret": client_secret, "sid": sid, "token": token} + + return ( + yield self.http_client.post_json_get_json( + id_server + "/_matrix/identity/api/v1/validate/msisdn/requestToken", + body, + ) + ) + def create_id_access_token_header(id_access_token): """Create an Authorization header for passing to SimpleHttpClient as the header value diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 1139bb156c1c..59f77e0e8f90 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -516,7 +516,7 @@ def on_POST(self, request): return 200, ret -class AddThreepidSubmitTokenServlet(RestServlet): +class AddThreepidEmailSubmitTokenServlet(RestServlet): """Handles 3PID validation token submission for adding an email to a user's account""" PATTERNS = client_patterns( @@ -592,6 +592,52 @@ def on_GET(self, request): finish_request(request) +class AddThreepidMsisdnSubmitTokenServlet(RestServlet): + """Handles 3PID validation token submission for adding a phone number to a user's + account + """ + + PATTERNS = client_patterns( + "/add_threepid/msisdn/submit_token$", releases=(), unstable=True + ) + + def __init__(self, hs): + """ + Args: + hs (synapse.server.HomeServer): server + """ + super().__init__() + self.config = hs.config + self.clock = hs.get_clock() + self.store = hs.get_datastore() + self.identity_handler = hs.get_handlers().identity_handler + + @defer.inlineCallbacks + def on_POST(self, request): + if not self.config.account_threepid_delegate_msisdn: + raise SynapseError( + 400, + "This homeserver is not validating phone numbers. Use an identity server " + "instead.", + ) + + body = parse_json_object_from_request(request) + assert_params_in_dict(body, ["client_secret", "sid", "token"]) + + try: + # Proxy submit_token request to msisdn threepid delegate + response = self.identity_handler.proxy_msisdn_submit_token( + self.config.account_threepid_delegate_msisdn, + body["client_secret"], + body["sid"], + body["token"], + ) + return 200, response + except HttpResponseException as e: + logger.warn("Error contacting msisdn account_threepid_delegate: %s", e) + raise SynapseError(400, "Error contacting the identity server") + + class ThreepidRestServlet(RestServlet): PATTERNS = client_patterns("/account/3pid$") @@ -792,7 +838,8 @@ def register_servlets(hs, http_server): DeactivateAccountRestServlet(hs).register(http_server) EmailThreepidRequestTokenRestServlet(hs).register(http_server) MsisdnThreepidRequestTokenRestServlet(hs).register(http_server) - AddThreepidSubmitTokenServlet(hs).register(http_server) + AddThreepidEmailSubmitTokenServlet(hs).register(http_server) + AddThreepidMsisdnSubmitTokenServlet(hs).register(http_server) ThreepidRestServlet(hs).register(http_server) ThreepidUnbindRestServlet(hs).register(http_server) ThreepidDeleteRestServlet(hs).register(http_server) From f6b265562132f489b6294120d58258262b4d7025 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 20 Sep 2019 19:04:30 +0100 Subject: [PATCH 02/13] Add changelog --- changelog.d/6078.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6078.feature diff --git a/changelog.d/6078.feature b/changelog.d/6078.feature new file mode 100644 index 000000000000..fae1e523221a --- /dev/null +++ b/changelog.d/6078.feature @@ -0,0 +1 @@ +Add `POST /add_threepid/msisdn/submit_token` endpoint for proxying submitToken on an account_threepid_handler. \ No newline at end of file From 4ec6468326bde15cd18081a99b59e4fbd6d62f56 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 20 Sep 2019 19:08:15 +0100 Subject: [PATCH 03/13] Add submit_url response parameter to msisdn /requestToken --- synapse/rest/client/v2_alpha/account.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 59f77e0e8f90..7bd878403639 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -513,6 +513,14 @@ def on_POST(self, request): id_server, country, phone_number, client_secret, send_attempt, next_link ) + assert self.hs.config.public_baseurl + + # Add submit_url response parameter as per MSC2078 + ret["submit_url"] = ( + self.hs.config.public_baseurl + + "_matrix/client/unstable/add_threepid/msisdn/submit_token" + ) + return 200, ret From 7b13ac68deadd021364866025bb5ad5f357806f1 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 20 Sep 2019 19:18:41 +0100 Subject: [PATCH 04/13] Add note about public_baseurl to config notes --- docs/sample_config.yaml | 1 + synapse/config/registration.py | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml index 61d9f09a9966..03e220432a37 100644 --- a/docs/sample_config.yaml +++ b/docs/sample_config.yaml @@ -937,6 +937,7 @@ uploads_path: "DATADIR/uploads" # by the Matrix Identity Service API specification: # https://matrix.org/docs/spec/identity_service/latest # +# If a delegate is specified, the config option public_baseurl must also be filled out. account_threepid_delegates: #email: https://example.com # Delegate email sending to example.org #msisdn: http://localhost:8090 # Delegate SMS sending to this local process diff --git a/synapse/config/registration.py b/synapse/config/registration.py index d4654e99b34a..ff2f373c3ab1 100644 --- a/synapse/config/registration.py +++ b/synapse/config/registration.py @@ -293,6 +293,7 @@ def generate_config_section(self, generate_secrets=False, **kwargs): # by the Matrix Identity Service API specification: # https://matrix.org/docs/spec/identity_service/latest # + # If a delegate is specified, the config option public_baseurl must also be filled out. account_threepid_delegates: #email: https://example.com # Delegate email sending to example.org #msisdn: http://localhost:8090 # Delegate SMS sending to this local process From 5daaa3bcd0bee6ff276c3efa61e36602d6a15e61 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 20 Sep 2019 19:20:21 +0100 Subject: [PATCH 05/13] Add changelog --- changelog.d/6079.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6079.feature diff --git a/changelog.d/6079.feature b/changelog.d/6079.feature new file mode 100644 index 000000000000..4788fccb1caa --- /dev/null +++ b/changelog.d/6079.feature @@ -0,0 +1 @@ +Add `submit_url` response parameter to /account/3pid/msisdn/requestToken`. \ No newline at end of file From 8186deaba3ababc532b91a51e8e3d40c05871aa1 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Fri, 20 Sep 2019 19:35:23 +0100 Subject: [PATCH 06/13] Update synapse/handlers/identity.py --- synapse/handlers/identity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index efeb4f29384b..ba9c9aed85fd 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -470,7 +470,7 @@ def proxy_msisdn_submit_token(self, id_server, client_secret, sid, token): return ( yield self.http_client.post_json_get_json( - id_server + "/_matrix/identity/api/v1/validate/msisdn/requestToken", + id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken", body, ) ) From a3817580799b8c1db0a9b4f91c4f4a4541ecbdd4 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 20 Sep 2019 22:50:06 +0100 Subject: [PATCH 07/13] lint --- synapse/handlers/identity.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index ba9c9aed85fd..656bf92c3187 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -470,8 +470,7 @@ def proxy_msisdn_submit_token(self, id_server, client_secret, sid, token): return ( yield self.http_client.post_json_get_json( - id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken", - body, + id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken", body ) ) From d03d583e5814bfc2bd02def7fc008ea3c8b30ad6 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 20 Sep 2019 23:07:00 +0100 Subject: [PATCH 08/13] Make sure to yield --- synapse/rest/client/v2_alpha/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 59f77e0e8f90..905d75b975f0 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -626,7 +626,7 @@ def on_POST(self, request): try: # Proxy submit_token request to msisdn threepid delegate - response = self.identity_handler.proxy_msisdn_submit_token( + response = yield self.identity_handler.proxy_msisdn_submit_token( self.config.account_threepid_delegate_msisdn, body["client_secret"], body["sid"], From 32288ede0ec7a59801b5f93e00e6bdfe4f875a11 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 23 Sep 2019 15:35:59 +0100 Subject: [PATCH 09/13] Move exception handling into Handler layer --- synapse/handlers/identity.py | 17 ++++++++++++----- synapse/rest/client/v2_alpha/account.py | 20 ++++++++------------ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index 656bf92c3187..42cb4903c074 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -464,15 +464,22 @@ def proxy_msisdn_submit_token(self, id_server, client_secret, sid, token): SynapseError: If we failed to contact the identity server Returns: - The response dict from the identity server + Deferred[dict]: The response dict from the identity server """ body = {"client_secret": client_secret, "sid": sid, "token": token} - return ( - yield self.http_client.post_json_get_json( - id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken", body + try: + return ( + yield self.http_client.post_json_get_json( + id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken", + body, + ) ) - ) + except TimeoutError: + raise SynapseError(500, "Timed out contacting identity server") + except HttpResponseException as e: + logger.warning("Error contacting msisdn account_threepid_delegate: %s", e) + raise SynapseError(400, "Error contacting the identity server") def create_id_access_token_header(id_access_token): diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 905d75b975f0..b4c7f23bb8eb 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -624,18 +624,14 @@ def on_POST(self, request): body = parse_json_object_from_request(request) assert_params_in_dict(body, ["client_secret", "sid", "token"]) - try: - # Proxy submit_token request to msisdn threepid delegate - response = yield self.identity_handler.proxy_msisdn_submit_token( - self.config.account_threepid_delegate_msisdn, - body["client_secret"], - body["sid"], - body["token"], - ) - return 200, response - except HttpResponseException as e: - logger.warn("Error contacting msisdn account_threepid_delegate: %s", e) - raise SynapseError(400, "Error contacting the identity server") + # Proxy submit_token request to msisdn threepid delegate + response = yield self.identity_handler.proxy_msisdn_submit_token( + self.config.account_threepid_delegate_msisdn, + body["client_secret"], + body["sid"], + body["token"], + ) + return 200, response class ThreepidRestServlet(RestServlet): From 21a979c8c5646b892a00119ac2d3cc3a24d9081e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 23 Sep 2019 18:10:39 +0100 Subject: [PATCH 10/13] remove duplicated function --- synapse/handlers/identity.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index aa2d08c06c6f..af6f5919428d 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -525,40 +525,6 @@ def proxy_msisdn_submit_token(self, id_server, client_secret, sid, token): logger.warning("Error contacting msisdn account_threepid_delegate: %s", e) raise SynapseError(400, "Error contacting the identity server") - @defer.inlineCallbacks - def proxy_msisdn_submit_token(self, id_server, client_secret, sid, token): - """Proxy a POST submitToken request to an identity server for verification purposes - - Args: - id_server (str): The identity server URL to contact - - client_secret (str): Secret provided by the client - - sid (str): The ID of the session - - token (str): The verification token - - Raises: - SynapseError: If we failed to contact the identity server - - Returns: - Deferred[dict]: The response dict from the identity server - """ - body = {"client_secret": client_secret, "sid": sid, "token": token} - - try: - return ( - yield self.http_client.post_json_get_json( - id_server + "/_matrix/identity/api/v1/validate/msisdn/submitToken", - body, - ) - ) - except TimeoutError: - raise SynapseError(500, "Timed out contacting identity server") - except HttpResponseException as e: - logger.warning("Error contacting msisdn account_threepid_delegate: %s", e) - raise SynapseError(400, "Error contacting the identity server") - def create_id_access_token_header(id_access_token): """Create an Authorization header for passing to SimpleHttpClient as the header value From cf9c0dcfab1ee82115697c621315e7f449958dd3 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 23 Sep 2019 18:12:39 +0100 Subject: [PATCH 11/13] Apply suggestions from code review --- docs/sample_config.yaml | 1 + synapse/config/registration.py | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml index 03e220432a37..10d562b4d254 100644 --- a/docs/sample_config.yaml +++ b/docs/sample_config.yaml @@ -938,6 +938,7 @@ uploads_path: "DATADIR/uploads" # https://matrix.org/docs/spec/identity_service/latest # # If a delegate is specified, the config option public_baseurl must also be filled out. +# account_threepid_delegates: #email: https://example.com # Delegate email sending to example.org #msisdn: http://localhost:8090 # Delegate SMS sending to this local process diff --git a/synapse/config/registration.py b/synapse/config/registration.py index ff2f373c3ab1..bef89e2bf4c4 100644 --- a/synapse/config/registration.py +++ b/synapse/config/registration.py @@ -294,6 +294,7 @@ def generate_config_section(self, generate_secrets=False, **kwargs): # https://matrix.org/docs/spec/identity_service/latest # # If a delegate is specified, the config option public_baseurl must also be filled out. + # account_threepid_delegates: #email: https://example.com # Delegate email sending to example.org #msisdn: http://localhost:8090 # Delegate SMS sending to this local process From b4105f4276518977f3a75006505b372b90b8197a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 23 Sep 2019 20:31:47 +0100 Subject: [PATCH 12/13] return submit_url from all msisdn/requestToken endpoints --- synapse/handlers/identity.py | 12 +++++++++++- synapse/rest/client/v2_alpha/account.py | 8 -------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index af6f5919428d..a1ba370c9791 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -440,13 +440,23 @@ def requestMsisdnToken( id_server + "/_matrix/identity/api/v1/validate/msisdn/requestToken", params, ) - return data except HttpResponseException as e: logger.info("Proxied requestToken failed: %r", e) raise e.to_synapse_error() except TimeoutError: raise SynapseError(500, "Timed out contacting identity server") + assert self.hs.config.public_baseurl + + # we need to tell the client to send the token back to us, since it doesn't + # otherwise know where to send it, so add submit_url response parameter + # (see also MSC2078) + data["submit_url"] = ( + self.hs.config.public_baseurl + + "_matrix/client/unstable/add_threepid/msisdn/submit_token" + ) + return data + @defer.inlineCallbacks def validate_threepid_session(self, client_secret, sid): """Validates a threepid session with only the client secret and session ID diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index b0adf426afad..f99676fd308c 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -521,14 +521,6 @@ def on_POST(self, request): next_link, ) - assert self.hs.config.public_baseurl - - # Add submit_url response parameter as per MSC2078 - ret["submit_url"] = ( - self.hs.config.public_baseurl - + "_matrix/client/unstable/add_threepid/msisdn/submit_token" - ) - return 200, ret From 0f51b7f32203bf9a3d01d85aea325c2e58f1e466 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 23 Sep 2019 20:33:26 +0100 Subject: [PATCH 13/13] update changelog --- changelog.d/6079.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/6079.feature b/changelog.d/6079.feature index 4788fccb1caa..bcbb49ac58a1 100644 --- a/changelog.d/6079.feature +++ b/changelog.d/6079.feature @@ -1 +1 @@ -Add `submit_url` response parameter to /account/3pid/msisdn/requestToken`. \ No newline at end of file +Add `submit_url` response parameter to `*/msisdn/requestToken` endpoints.