From e44607747883af3ec4ebc3ae42f38f2c00010385 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 13 Mar 2018 01:34:20 +0000 Subject: [PATCH 1/6] delegate to the IS to check 3PID signup eligibility --- synapse/config/registration.py | 6 ++++++ synapse/util/threepids.py | 25 +++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/synapse/config/registration.py b/synapse/config/registration.py index 336959094b..14ef535b27 100644 --- a/synapse/config/registration.py +++ b/synapse/config/registration.py @@ -33,6 +33,7 @@ class RegistrationConfig(Config): self.registrations_require_3pid = config.get("registrations_require_3pid", []) self.allowed_local_3pids = config.get("allowed_local_3pids", []) + self.check_is_for_allowed_local_3pids = config.get("check_is_for_allowed_local_3pids", False) self.registration_shared_secret = config.get("registration_shared_secret") self.bcrypt_rounds = config.get("bcrypt_rounds", 12) @@ -63,6 +64,10 @@ class RegistrationConfig(Config): # Mandate that users are only allowed to associate certain formats of # 3PIDs with accounts on this server. # + # Use an Identity Server to establish which 3PIDs are allowed to register? + # Overrides allowed_local_3pids below. + # check_is_for_allowed_local_3pids: matrix.org + # # allowed_local_3pids: # - medium: email # pattern: ".*@matrix\\.org" @@ -71,6 +76,7 @@ class RegistrationConfig(Config): # - medium: msisdn # pattern: "\\+44" + # If set, allows registration by anyone who also has the shared # secret, even if registration is otherwise disabled. registration_shared_secret: "%(registration_shared_secret)s" diff --git a/synapse/util/threepids.py b/synapse/util/threepids.py index 75efa0117b..cd629c2ec9 100644 --- a/synapse/util/threepids.py +++ b/synapse/util/threepids.py @@ -16,9 +16,12 @@ import logging import re +from twisted.internet import defer + logger = logging.getLogger(__name__) +@defer.inlineCallbacks def check_3pid_allowed(hs, medium, address): """Checks whether a given format of 3PID is allowed to be used on this HS @@ -28,9 +31,20 @@ def check_3pid_allowed(hs, medium, address): address (str): address within that medium (e.g. "wotan@matrix.org") msisdns need to first have been canonicalised Returns: - bool: whether the 3PID medium/address is allowed to be added to this HS + defered bool: whether the 3PID medium/address is allowed to be added to this HS """ + if hs.config.check_is_for_allowed_local_3pids: + data = yield hs.http_client.get_json( + "https://%s%s" % ( + hs.config.check_is_for_allowed_local_3pids, + "/_matrix/identity/api/v1/discover_urls" + ), + {'medium': medium, 'address': address } + ) + defer.returnValue(data.hs_url+"/" == self.hs.config.public_baseurl) + return + if hs.config.allowed_local_3pids: for constraint in hs.config.allowed_local_3pids: logger.debug( @@ -41,8 +55,11 @@ def check_3pid_allowed(hs, medium, address): medium == constraint['medium'] and re.match(constraint['pattern'], address) ): - return True + defer.returnValue(True) + return else: - return True + defer.returnValue(True) + return - return False + defer.returnValue(False) + return From 82c4fd7226d65df4087ed2d6047397e197d9253a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 13 Mar 2018 01:38:02 +0000 Subject: [PATCH 2/6] add yields --- synapse/handlers/register.py | 2 +- synapse/rest/client/v2_alpha/account.py | 8 ++++---- synapse/rest/client/v2_alpha/register.py | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py index 9021d4d57f..87d0a45806 100644 --- a/synapse/handlers/register.py +++ b/synapse/handlers/register.py @@ -308,7 +308,7 @@ class RegistrationHandler(BaseHandler): logger.info("got threepid with medium '%s' and address '%s'", threepid['medium'], threepid['address']) - if not check_3pid_allowed(self.hs, threepid['medium'], threepid['address']): + if not (yield check_3pid_allowed(self.hs, threepid['medium'], threepid['address'])): raise RegistrationError( 403, "Third party identifier is not allowed" ) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 30523995af..7d43a33615 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -48,7 +48,7 @@ class EmailPasswordRequestTokenRestServlet(RestServlet): 'id_server', 'client_secret', 'email', 'send_attempt' ]) - if not check_3pid_allowed(self.hs, "email", body['email']): + if not (yield check_3pid_allowed(self.hs, "email", body['email'])): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) @@ -84,7 +84,7 @@ class MsisdnPasswordRequestTokenRestServlet(RestServlet): msisdn = phone_number_to_msisdn(body['country'], body['phone_number']) - if not check_3pid_allowed(self.hs, "msisdn", msisdn): + if not (yield check_3pid_allowed(self.hs, "msisdn", msisdn)): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) @@ -228,7 +228,7 @@ class EmailThreepidRequestTokenRestServlet(RestServlet): if absent: raise SynapseError(400, "Missing params: %r" % absent, Codes.MISSING_PARAM) - if not check_3pid_allowed(self.hs, "email", body['email']): + if not (yield check_3pid_allowed(self.hs, "email", body['email'])): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) @@ -271,7 +271,7 @@ class MsisdnThreepidRequestTokenRestServlet(RestServlet): msisdn = phone_number_to_msisdn(body['country'], body['phone_number']) - if not check_3pid_allowed(self.hs, "msisdn", msisdn): + if not (yield check_3pid_allowed(self.hs, "msisdn", msisdn)): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) diff --git a/synapse/rest/client/v2_alpha/register.py b/synapse/rest/client/v2_alpha/register.py index c6f4680a76..7824456eb6 100644 --- a/synapse/rest/client/v2_alpha/register.py +++ b/synapse/rest/client/v2_alpha/register.py @@ -71,7 +71,7 @@ class EmailRegisterRequestTokenRestServlet(RestServlet): 'id_server', 'client_secret', 'email', 'send_attempt' ]) - if not check_3pid_allowed(self.hs, "email", body['email']): + if not (yield check_3pid_allowed(self.hs, "email", body['email'])): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) @@ -111,7 +111,7 @@ class MsisdnRegisterRequestTokenRestServlet(RestServlet): msisdn = phone_number_to_msisdn(body['country'], body['phone_number']) - if not check_3pid_allowed(self.hs, "msisdn", msisdn): + if not (yield check_3pid_allowed(self.hs, "msisdn", msisdn)): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) @@ -371,7 +371,7 @@ class RegisterRestServlet(RestServlet): medium = auth_result[login_type]['medium'] address = auth_result[login_type]['address'] - if not check_3pid_allowed(self.hs, medium, address): + if not (yield check_3pid_allowed(self.hs, medium, address)): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, From 0e2d70e101f19fa2ab1f752071d8e79b88261a8c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 13 Mar 2018 01:41:20 +0000 Subject: [PATCH 3/6] typos --- synapse/util/threepids.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/synapse/util/threepids.py b/synapse/util/threepids.py index cd629c2ec9..d2f646db9c 100644 --- a/synapse/util/threepids.py +++ b/synapse/util/threepids.py @@ -35,14 +35,14 @@ def check_3pid_allowed(hs, medium, address): """ if hs.config.check_is_for_allowed_local_3pids: - data = yield hs.http_client.get_json( + data = yield hs.get_simple_http_client().get_json( "https://%s%s" % ( hs.config.check_is_for_allowed_local_3pids, "/_matrix/identity/api/v1/discover_urls" ), {'medium': medium, 'address': address } ) - defer.returnValue(data.hs_url+"/" == self.hs.config.public_baseurl) + defer.returnValue(data['hs_url'] + "/" == hs.config.public_baseurl) return if hs.config.allowed_local_3pids: From 739d3500feef8a4cb84a60839bba486001691697 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 13 Mar 2018 01:50:32 +0000 Subject: [PATCH 4/6] pep8 --- synapse/config/registration.py | 4 +++- synapse/handlers/register.py | 4 +++- synapse/util/threepids.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/synapse/config/registration.py b/synapse/config/registration.py index 14ef535b27..6cd830a78e 100644 --- a/synapse/config/registration.py +++ b/synapse/config/registration.py @@ -33,7 +33,9 @@ class RegistrationConfig(Config): self.registrations_require_3pid = config.get("registrations_require_3pid", []) self.allowed_local_3pids = config.get("allowed_local_3pids", []) - self.check_is_for_allowed_local_3pids = config.get("check_is_for_allowed_local_3pids", False) + self.check_is_for_allowed_local_3pids = config.get( + "check_is_for_allowed_local_3pids", False + ) self.registration_shared_secret = config.get("registration_shared_secret") self.bcrypt_rounds = config.get("bcrypt_rounds", 12) diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py index 87d0a45806..96f480f836 100644 --- a/synapse/handlers/register.py +++ b/synapse/handlers/register.py @@ -308,7 +308,9 @@ class RegistrationHandler(BaseHandler): logger.info("got threepid with medium '%s' and address '%s'", threepid['medium'], threepid['address']) - if not (yield check_3pid_allowed(self.hs, threepid['medium'], threepid['address'])): + if not ( + yield check_3pid_allowed(self.hs, threepid['medium'], threepid['address']) + ): raise RegistrationError( 403, "Third party identifier is not allowed" ) diff --git a/synapse/util/threepids.py b/synapse/util/threepids.py index d2f646db9c..e1cf5dbb13 100644 --- a/synapse/util/threepids.py +++ b/synapse/util/threepids.py @@ -40,7 +40,7 @@ def check_3pid_allowed(hs, medium, address): hs.config.check_is_for_allowed_local_3pids, "/_matrix/identity/api/v1/discover_urls" ), - {'medium': medium, 'address': address } + {'medium': medium, 'address': address} ) defer.returnValue(data['hs_url'] + "/" == hs.config.public_baseurl) return From 5c341c99f67b2533980fbf567b2e80c039f68a43 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 13 Mar 2018 21:15:14 +0000 Subject: [PATCH 5/6] add 'allow_invited_3pids' option to invited 3PIDs to register --- synapse/config/registration.py | 7 +++++++ synapse/util/threepids.py | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/synapse/config/registration.py b/synapse/config/registration.py index 6cd830a78e..dc3c85a517 100644 --- a/synapse/config/registration.py +++ b/synapse/config/registration.py @@ -36,6 +36,7 @@ class RegistrationConfig(Config): self.check_is_for_allowed_local_3pids = config.get( "check_is_for_allowed_local_3pids", False ) + self.allow_invited_3pids = config.get("allow_invited_3pids", False) self.registration_shared_secret = config.get("registration_shared_secret") self.bcrypt_rounds = config.get("bcrypt_rounds", 12) @@ -70,6 +71,12 @@ class RegistrationConfig(Config): # Overrides allowed_local_3pids below. # check_is_for_allowed_local_3pids: matrix.org # + # If you are using an IS you can also check whether that IS registers + # pending invites for the given 3PID (and then allow it to sign up on + # the platform): + # + # allow_invited_3pids: False + # # allowed_local_3pids: # - medium: email # pattern: ".*@matrix\\.org" diff --git a/synapse/util/threepids.py b/synapse/util/threepids.py index e1cf5dbb13..94c0852f0c 100644 --- a/synapse/util/threepids.py +++ b/synapse/util/threepids.py @@ -42,7 +42,10 @@ def check_3pid_allowed(hs, medium, address): ), {'medium': medium, 'address': address} ) - defer.returnValue(data['hs_url'] + "/" == hs.config.public_baseurl) + if hs.config.allow_invited_3pids and data.get('invited'): + defer.returnValue(True) + else: + defer.returnValue(data['hs_url'] + "/" == hs.config.public_baseurl) return if hs.config.allowed_local_3pids: From 2e4a6c5aaba238760c4ad4e97ca132ccbbb2cc7b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 14 Mar 2018 22:09:08 +0000 Subject: [PATCH 6/6] incorporate PR feedback and rename URL --- synapse/config/registration.py | 3 +-- synapse/util/threepids.py | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/synapse/config/registration.py b/synapse/config/registration.py index dc3c85a517..2854a48d0a 100644 --- a/synapse/config/registration.py +++ b/synapse/config/registration.py @@ -34,7 +34,7 @@ class RegistrationConfig(Config): self.registrations_require_3pid = config.get("registrations_require_3pid", []) self.allowed_local_3pids = config.get("allowed_local_3pids", []) self.check_is_for_allowed_local_3pids = config.get( - "check_is_for_allowed_local_3pids", False + "check_is_for_allowed_local_3pids", None ) self.allow_invited_3pids = config.get("allow_invited_3pids", False) self.registration_shared_secret = config.get("registration_shared_secret") @@ -85,7 +85,6 @@ class RegistrationConfig(Config): # - medium: msisdn # pattern: "\\+44" - # If set, allows registration by anyone who also has the shared # secret, even if registration is otherwise disabled. registration_shared_secret: "%(registration_shared_secret)s" diff --git a/synapse/util/threepids.py b/synapse/util/threepids.py index 94c0852f0c..353d220bad 100644 --- a/synapse/util/threepids.py +++ b/synapse/util/threepids.py @@ -38,15 +38,14 @@ def check_3pid_allowed(hs, medium, address): data = yield hs.get_simple_http_client().get_json( "https://%s%s" % ( hs.config.check_is_for_allowed_local_3pids, - "/_matrix/identity/api/v1/discover_urls" + "/_matrix/identity/api/v1/info" ), {'medium': medium, 'address': address} ) if hs.config.allow_invited_3pids and data.get('invited'): defer.returnValue(True) else: - defer.returnValue(data['hs_url'] + "/" == hs.config.public_baseurl) - return + defer.returnValue(data['hs'] == hs.config.server_name) if hs.config.allowed_local_3pids: for constraint in hs.config.allowed_local_3pids: @@ -59,10 +58,7 @@ def check_3pid_allowed(hs, medium, address): re.match(constraint['pattern'], address) ): defer.returnValue(True) - return else: defer.returnValue(True) - return defer.returnValue(False) - return