diff options
Diffstat (limited to 'synapse/handlers/register.py')
-rw-r--r-- | synapse/handlers/register.py | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py index 432bbcdcb5..bee052274f 100644 --- a/synapse/handlers/register.py +++ b/synapse/handlers/register.py @@ -20,9 +20,13 @@ from synapse.types import UserID from synapse.api.errors import SynapseError, RegistrationError from ._base import BaseHandler import synapse.util.stringutils as stringutils +from synapse.http.client import PlainHttpClient import base64 import bcrypt +import logging + +logger = logging.getLogger(__name__) class RegistrationHandler(BaseHandler): @@ -34,7 +38,7 @@ class RegistrationHandler(BaseHandler): self.distributor.declare("registered_user") @defer.inlineCallbacks - def register(self, localpart=None, password=None): + def register(self, localpart=None, password=None, threepidCreds=None): """Registers a new client on the server. Args: @@ -47,6 +51,20 @@ class RegistrationHandler(BaseHandler): Raises: RegistrationError if there was a problem registering. """ + + if threepidCreds: + for c in threepidCreds: + logger.info("validating theeepidcred sid %s on id server %s", c['sid'], c['idServer']) + try: + threepid = yield self._threepid_from_creds(c) + except: + logger.err() + raise RegistrationError(400, "Couldn't validate 3pid") + + if not threepid: + raise RegistrationError(400, "Couldn't validate 3pid") + logger.info("got threepid medium %s address %s", threepid['medium'], threepid['address']) + password_hash = None if password: password_hash = bcrypt.hashpw(password, bcrypt.gensalt()) @@ -61,7 +79,6 @@ class RegistrationHandler(BaseHandler): password_hash=password_hash) self.distributor.fire("registered_user", user) - defer.returnValue((user_id, token)) else: # autogen a random user ID attempts = 0 @@ -80,7 +97,6 @@ class RegistrationHandler(BaseHandler): password_hash=password_hash) self.distributor.fire("registered_user", user) - defer.returnValue((user_id, token)) except SynapseError: # if user id is taken, just generate another user_id = None @@ -90,6 +106,15 @@ class RegistrationHandler(BaseHandler): raise RegistrationError( 500, "Cannot generate user ID.") + # Now we have a matrix ID, bind it to the threepids we were given + if threepidCreds: + for c in threepidCreds: + # XXX: This should be a deferred list, shouldn't it? + yield self._bind_threepid(c, user_id) + + + defer.returnValue((user_id, token)) + def _generate_token(self, user_id): # urlsafe variant uses _ and - so use . as the separator and replace # all =s with .s so http clients don't quote =s when it is used as @@ -99,3 +124,34 @@ class RegistrationHandler(BaseHandler): def _generate_user_id(self): return "-" + stringutils.random_string(18) + + @defer.inlineCallbacks + def _threepid_from_creds(self, creds): + httpCli = PlainHttpClient(self.hs) + # XXX: make this configurable! + trustedIdServers = [ 'matrix.org:8090' ] + if not creds['idServer'] in trustedIdServers: + logger.warn('%s is not a trusted ID server: rejecting 3pid credentials', creds['idServer']) + defer.returnValue(None) + data = yield httpCli.get_json( + creds['idServer'], + "/_matrix/identity/api/v1/3pid/getValidated3pid", + { 'sid': creds['sid'], 'clientSecret': creds['clientSecret'] } + ) + + if 'medium' in data: + defer.returnValue(data) + defer.returnValue(None) + + @defer.inlineCallbacks + def _bind_threepid(self, creds, mxid): + httpCli = PlainHttpClient(self.hs) + data = yield httpCli.post_urlencoded_get_json( + creds['idServer'], + "/_matrix/identity/api/v1/3pid/bind", + { 'sid': creds['sid'], 'clientSecret': creds['clientSecret'], 'mxid':mxid } + ) + defer.returnValue(data) + + + |