def on_POST(self, request): user_json = parse_json_object_from_request(request) access_token = get_access_token_from_request(request) app_service = yield self.store.get_app_service_by_token(access_token) if not app_service: raise SynapseError(403, "Invalid application service token.") logger.debug("creating user: %s", user_json) response = yield self._do_create(user_json) defer.returnValue((200, response))
def on_POST(self, request): user_json = parse_json_object_from_request(request) access_token = get_access_token_from_request(request) app_service = yield self.store.get_app_service_by_token( access_token ) if not app_service: raise SynapseError(403, "Invalid application service token.") logger.debug("creating user: %s", user_json) response = yield self._do_create(user_json) defer.returnValue((200, response))
def get_transaction_key(request): """A helper function which returns a transaction key that can be used with TransactionCache for idempotent requests. Idempotency is based on the returned key being the same for separate requests to the same endpoint. The key is formed from the HTTP request path and the access_token for the requesting user. Args: request (twisted.web.http.Request): The incoming request. Must contain an access_token. Returns: str: A transaction key """ token = get_access_token_from_request(request) return request.path + "/" + token
def get_transaction_key(request): """A helper function which returns a transaction key that can be used with TransactionCache for idempotent requests. Idempotency is based on the returned key being the same for separate requests to the same endpoint. The key is formed from the HTTP request path and the access_token for the requesting user. Args: request (twisted.web.http.Request): The incoming request. Must contain an access_token. Returns: str: A transaction key """ token = get_access_token_from_request(request) return request.path + "/" + token
def _do_app_service(self, request, register_json, session): as_token = get_access_token_from_request(request) if "user" not in register_json: raise SynapseError(400, "Expected 'user' key.") user_localpart = register_json["user"].encode("utf-8") handler = self.handlers.registration_handler user_id = yield handler.appservice_register(user_localpart, as_token) token = yield self.auth_handler.issue_access_token(user_id) self._remove_session(session) defer.returnValue({ "user_id": user_id, "access_token": token, "home_server": self.hs.hostname, })
def on_POST(self, request): try: requester = yield self.auth.get_user_by_req(request) except AuthError: # this implies the access token has already been deleted. pass else: if requester.device_id is None: # the acccess token wasn't associated with a device. # Just delete the access token access_token = get_access_token_from_request(request) yield self._auth_handler.delete_access_token(access_token) else: yield self._device_handler.delete_device( requester.user.to_string(), requester.device_id) defer.returnValue((200, {}))
def _do_app_service(self, request, register_json, session): as_token = get_access_token_from_request(request) if "user" not in register_json: raise SynapseError(400, "Expected 'user' key.") user_localpart = register_json["user"].encode("utf-8") handler = self.handlers.registration_handler user_id = yield handler.appservice_register( user_localpart, as_token ) token = yield self.auth_handler.issue_access_token(user_id) self._remove_session(session) defer.returnValue({ "user_id": user_id, "access_token": token, "home_server": self.hs.hostname, })
def on_POST(self, request): try: requester = yield self.auth.get_user_by_req(request) except AuthError: # this implies the access token has already been deleted. defer.returnValue((401, { "errcode": "M_UNKNOWN_TOKEN", "error": "Access Token unknown or expired" })) else: if requester.device_id is None: # the acccess token wasn't associated with a device. # Just delete the access token access_token = get_access_token_from_request(request) yield self._auth_handler.delete_access_token(access_token) else: yield self._device_handler.delete_device( requester.user.to_string(), requester.device_id) defer.returnValue((200, {}))
def on_POST(self, request): yield run_on_reactor() body = parse_json_object_from_request(request) kind = "user" if "kind" in request.args: kind = request.args["kind"][0] if kind == "guest": ret = yield self._do_guest_registration(body) defer.returnValue(ret) return elif kind != "user": raise UnrecognizedRequestError( "Do not understand membership kind: %s" % (kind, )) # we do basic sanity checks here because the auth layer will store these # in sessions. Pull out the username/password provided to us. desired_password = None if 'password' in body: if (not isinstance(body['password'], basestring) or len(body['password']) > 512): raise SynapseError(400, "Invalid password") desired_password = body["password"] desired_username = None if 'username' in body: if (not isinstance(body['username'], basestring) or len(body['username']) > 512): raise SynapseError(400, "Invalid username") desired_username = body['username'] appservice = None if has_access_token(request): appservice = yield self.auth.get_appservice_by_req(request) # fork off as soon as possible for ASes and shared secret auth which # have completely different registration flows to normal users # == Application Service Registration == if appservice: # Set the desired user according to the AS API (which uses the # 'user' key not 'username'). Since this is a new addition, we'll # fallback to 'username' if they gave one. desired_username = body.get("user", desired_username) access_token = get_access_token_from_request(request) if isinstance(desired_username, basestring): result = yield self._do_appservice_registration( desired_username, access_token, body) defer.returnValue((200, result)) # we throw for non 200 responses return # == Shared Secret Registration == (e.g. create new user scripts) if 'mac' in body: # FIXME: Should we really be determining if this is shared secret # auth based purely on the 'mac' key? result = yield self._do_shared_secret_registration( desired_username, desired_password, body) defer.returnValue((200, result)) # we throw for non 200 responses return # == Normal User Registration == (everyone else) if not self.hs.config.enable_registration: raise SynapseError(403, "Registration has been disabled") guest_access_token = body.get("guest_access_token", None) if ('initial_device_display_name' in body and 'password' not in body): # ignore 'initial_device_display_name' if sent without # a password to work around a client bug where it sent # the 'initial_device_display_name' param alone, wiping out # the original registration params logger.warn( "Ignoring initial_device_display_name without password") del body['initial_device_display_name'] session_id = self.auth_handler.get_session_id(body) registered_user_id = None if session_id: # if we get a registered user id out of here, it means we previously # registered a user for this session, so we could just return the # user here. We carry on and go through the auth checks though, # for paranoia. registered_user_id = self.auth_handler.get_session_data( session_id, "registered_user_id", None) if desired_username is not None: yield self.registration_handler.check_username( desired_username, guest_access_token=guest_access_token, assigned_user_id=registered_user_id, ) # Only give msisdn flows if the x_show_msisdn flag is given: # this is a hack to work around the fact that clients were shipped # that use fallback registration if they see any flows that they don't # recognise, which means we break registration for these clients if we # advertise msisdn flows. Once usage of Riot iOS <=0.3.9 and Riot # Android <=0.6.9 have fallen below an acceptable threshold, this # parameter should go away and we should always advertise msisdn flows. show_msisdn = False if 'x_show_msisdn' in body and body['x_show_msisdn']: show_msisdn = True if self.hs.config.enable_registration_captcha: flows = [ [LoginType.RECAPTCHA], [LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA], ] if show_msisdn: flows.extend([ [LoginType.MSISDN, LoginType.RECAPTCHA], [ LoginType.MSISDN, LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA ], ]) else: flows = [ [LoginType.DUMMY], [LoginType.EMAIL_IDENTITY], ] if show_msisdn: flows.extend([ [LoginType.MSISDN], [LoginType.MSISDN, LoginType.EMAIL_IDENTITY], ]) authed, auth_result, params, session_id = yield self.auth_handler.check_auth( flows, body, self.hs.get_ip_from_request(request)) if not authed: defer.returnValue((401, auth_result)) return if registered_user_id is not None: logger.info("Already registered user ID %r for this session", registered_user_id) # don't re-register the threepids add_email = False add_msisdn = False else: # NB: This may be from the auth handler and NOT from the POST if 'password' not in params: raise SynapseError(400, "Missing password.", Codes.MISSING_PARAM) desired_username = params.get("username", None) new_password = params.get("password", None) guest_access_token = params.get("guest_access_token", None) (registered_user_id, _) = yield self.registration_handler.register( localpart=desired_username, password=new_password, guest_access_token=guest_access_token, generate_token=False, ) # remember that we've now registered that user account, and with # what user ID (since the user may not have specified) self.auth_handler.set_session_data(session_id, "registered_user_id", registered_user_id) add_email = True add_msisdn = True return_dict = yield self._create_registration_details( registered_user_id, params) if add_email and auth_result and LoginType.EMAIL_IDENTITY in auth_result: threepid = auth_result[LoginType.EMAIL_IDENTITY] yield self._register_email_threepid(registered_user_id, threepid, return_dict["access_token"], params.get("bind_email")) if add_msisdn and auth_result and LoginType.MSISDN in auth_result: threepid = auth_result[LoginType.MSISDN] yield self._register_msisdn_threepid(registered_user_id, threepid, return_dict["access_token"], params.get("bind_msisdn")) defer.returnValue((200, return_dict))
def on_POST(self, request): body = parse_json_object_from_request(request) kind = "user" if "kind" in request.args: kind = request.args["kind"][0] if kind == "guest": ret = yield self._do_guest_registration(body) defer.returnValue(ret) return elif kind != "user": raise UnrecognizedRequestError( "Do not understand membership kind: %s" % (kind, )) # we do basic sanity checks here because the auth layer will store these # in sessions. Pull out the username/password provided to us. desired_password = None if 'password' in body: if (not isinstance(body['password'], string_types) or len(body['password']) > 512): raise SynapseError(400, "Invalid password") desired_password = body["password"] desired_username = None if 'username' in body: if (not isinstance(body['username'], string_types) or len(body['username']) > 512): raise SynapseError(400, "Invalid username") desired_username = body['username'] appservice = None if has_access_token(request): appservice = yield self.auth.get_appservice_by_req(request) # fork off as soon as possible for ASes and shared secret auth which # have completely different registration flows to normal users # == Application Service Registration == if appservice: # Set the desired user according to the AS API (which uses the # 'user' key not 'username'). Since this is a new addition, we'll # fallback to 'username' if they gave one. desired_username = body.get("user", desired_username) # XXX we should check that desired_username is valid. Currently # we give appservices carte blanche for any insanity in mxids, # because the IRC bridges rely on being able to register stupid # IDs. access_token = get_access_token_from_request(request) if isinstance(desired_username, string_types): result = yield self._do_appservice_registration( desired_username, access_token, body) defer.returnValue((200, result)) # we throw for non 200 responses return # for either shared secret or regular registration, downcase the # provided username before attempting to register it. This should mean # that people who try to register with upper-case in their usernames # don't get a nasty surprise. (Note that we treat username # case-insenstively in login, so they are free to carry on imagining # that their username is CrAzYh4cKeR if that keeps them happy) if desired_username is not None: desired_username = desired_username.lower() # == Shared Secret Registration == (e.g. create new user scripts) if 'mac' in body: # FIXME: Should we really be determining if this is shared secret # auth based purely on the 'mac' key? result = yield self._do_shared_secret_registration( desired_username, desired_password, body) defer.returnValue((200, result)) # we throw for non 200 responses return # == Normal User Registration == (everyone else) if not self.hs.config.enable_registration: raise SynapseError(403, "Registration has been disabled") guest_access_token = body.get("guest_access_token", None) if ('initial_device_display_name' in body and 'password' not in body): # ignore 'initial_device_display_name' if sent without # a password to work around a client bug where it sent # the 'initial_device_display_name' param alone, wiping out # the original registration params logger.warn( "Ignoring initial_device_display_name without password") del body['initial_device_display_name'] session_id = self.auth_handler.get_session_id(body) registered_user_id = None if session_id: # if we get a registered user id out of here, it means we previously # registered a user for this session, so we could just return the # user here. We carry on and go through the auth checks though, # for paranoia. registered_user_id = self.auth_handler.get_session_data( session_id, "registered_user_id", None) if desired_username is not None: yield self.registration_handler.check_username( desired_username, guest_access_token=guest_access_token, assigned_user_id=registered_user_id, ) # Only give msisdn flows if the x_show_msisdn flag is given: # this is a hack to work around the fact that clients were shipped # that use fallback registration if they see any flows that they don't # recognise, which means we break registration for these clients if we # advertise msisdn flows. Once usage of Riot iOS <=0.3.9 and Riot # Android <=0.6.9 have fallen below an acceptable threshold, this # parameter should go away and we should always advertise msisdn flows. show_msisdn = False if 'x_show_msisdn' in body and body['x_show_msisdn']: show_msisdn = True # FIXME: need a better error than "no auth flow found" for scenarios # where we required 3PID for registration but the user didn't give one require_email = 'email' in self.hs.config.registrations_require_3pid require_msisdn = 'msisdn' in self.hs.config.registrations_require_3pid flows = [] if self.hs.config.enable_registration_captcha: # only support 3PIDless registration if no 3PIDs are required if not require_email and not require_msisdn: flows.extend([[LoginType.RECAPTCHA]]) # only support the email-only flow if we don't require MSISDN 3PIDs if not require_msisdn: flows.extend([[LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA]]) if show_msisdn: # only support the MSISDN-only flow if we don't require email 3PIDs if not require_email: flows.extend([[LoginType.MSISDN, LoginType.RECAPTCHA]]) # always let users provide both MSISDN & email flows.extend([ [ LoginType.MSISDN, LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA ], ]) else: # only support 3PIDless registration if no 3PIDs are required if not require_email and not require_msisdn: flows.extend([[LoginType.DUMMY]]) # only support the email-only flow if we don't require MSISDN 3PIDs if not require_msisdn: flows.extend([[LoginType.EMAIL_IDENTITY]]) if show_msisdn: # only support the MSISDN-only flow if we don't require email 3PIDs if not require_email or require_msisdn: flows.extend([[LoginType.MSISDN]]) # always let users provide both MSISDN & email flows.extend([[LoginType.MSISDN, LoginType.EMAIL_IDENTITY]]) auth_result, params, session_id = yield self.auth_handler.check_auth( flows, body, self.hs.get_ip_from_request(request)) # Check that we're not trying to register a denied 3pid. # # the user-facing checks will probably already have happened in # /register/email/requestToken when we requested a 3pid, but that's not # guaranteed. if auth_result: for login_type in [LoginType.EMAIL_IDENTITY, LoginType.MSISDN]: if login_type in auth_result: medium = auth_result[login_type]['medium'] address = auth_result[login_type]['address'] if not check_3pid_allowed(self.hs, medium, address): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) if registered_user_id is not None: logger.info("Already registered user ID %r for this session", registered_user_id) # don't re-register the threepids add_email = False add_msisdn = False else: # NB: This may be from the auth handler and NOT from the POST if 'password' not in params: raise SynapseError(400, "Missing password.", Codes.MISSING_PARAM) desired_username = params.get("username", None) new_password = params.get("password", None) guest_access_token = params.get("guest_access_token", None) if desired_username is not None: desired_username = desired_username.lower() (registered_user_id, _) = yield self.registration_handler.register( localpart=desired_username, password=new_password, guest_access_token=guest_access_token, generate_token=False, ) # remember that we've now registered that user account, and with # what user ID (since the user may not have specified) self.auth_handler.set_session_data(session_id, "registered_user_id", registered_user_id) add_email = True add_msisdn = True return_dict = yield self._create_registration_details( registered_user_id, params) if add_email and auth_result and LoginType.EMAIL_IDENTITY in auth_result: threepid = auth_result[LoginType.EMAIL_IDENTITY] yield self._register_email_threepid(registered_user_id, threepid, return_dict["access_token"], params.get("bind_email")) if add_msisdn and auth_result and LoginType.MSISDN in auth_result: threepid = auth_result[LoginType.MSISDN] yield self._register_msisdn_threepid(registered_user_id, threepid, return_dict["access_token"], params.get("bind_msisdn")) defer.returnValue((200, return_dict))
def on_POST(self, request): access_token = get_access_token_from_request(request) yield self._auth_handler.delete_access_token(access_token) defer.returnValue((200, {}))
def _get_key(self, request): token = get_access_token_from_request(request) path_without_txn_id = request.path.rsplit("/", 1)[0] return path_without_txn_id + "/" + token
def on_POST(self, request): yield run_on_reactor() body = parse_json_object_from_request(request) kind = "user" if "kind" in request.args: kind = request.args["kind"][0] if kind == "guest": ret = yield self._do_guest_registration(body) defer.returnValue(ret) return elif kind != "user": raise UnrecognizedRequestError( "Do not understand membership kind: %s" % (kind,) ) # we do basic sanity checks here because the auth layer will store these # in sessions. Pull out the username/password provided to us. desired_password = None if 'password' in body: if (not isinstance(body['password'], string_types) or len(body['password']) > 512): raise SynapseError(400, "Invalid password") desired_password = body["password"] desired_username = None if 'username' in body: if (not isinstance(body['username'], string_types) or len(body['username']) > 512): raise SynapseError(400, "Invalid username") desired_username = body['username'] appservice = None if has_access_token(request): appservice = yield self.auth.get_appservice_by_req(request) # fork off as soon as possible for ASes and shared secret auth which # have completely different registration flows to normal users # == Application Service Registration == if appservice: # Set the desired user according to the AS API (which uses the # 'user' key not 'username'). Since this is a new addition, we'll # fallback to 'username' if they gave one. desired_username = body.get("user", desired_username) # XXX we should check that desired_username is valid. Currently # we give appservices carte blanche for any insanity in mxids, # because the IRC bridges rely on being able to register stupid # IDs. access_token = get_access_token_from_request(request) if isinstance(desired_username, string_types): result = yield self._do_appservice_registration( desired_username, access_token, body ) defer.returnValue((200, result)) # we throw for non 200 responses return # for either shared secret or regular registration, downcase the # provided username before attempting to register it. This should mean # that people who try to register with upper-case in their usernames # don't get a nasty surprise. (Note that we treat username # case-insenstively in login, so they are free to carry on imagining # that their username is CrAzYh4cKeR if that keeps them happy) if desired_username is not None: desired_username = desired_username.lower() # == Shared Secret Registration == (e.g. create new user scripts) if 'mac' in body: # FIXME: Should we really be determining if this is shared secret # auth based purely on the 'mac' key? result = yield self._do_shared_secret_registration( desired_username, desired_password, body ) defer.returnValue((200, result)) # we throw for non 200 responses return # == Normal User Registration == (everyone else) if not self.hs.config.enable_registration: raise SynapseError(403, "Registration has been disabled") guest_access_token = body.get("guest_access_token", None) if ( 'initial_device_display_name' in body and 'password' not in body ): # ignore 'initial_device_display_name' if sent without # a password to work around a client bug where it sent # the 'initial_device_display_name' param alone, wiping out # the original registration params logger.warn("Ignoring initial_device_display_name without password") del body['initial_device_display_name'] session_id = self.auth_handler.get_session_id(body) registered_user_id = None if session_id: # if we get a registered user id out of here, it means we previously # registered a user for this session, so we could just return the # user here. We carry on and go through the auth checks though, # for paranoia. registered_user_id = self.auth_handler.get_session_data( session_id, "registered_user_id", None ) if desired_username is not None: yield self.registration_handler.check_username( desired_username, guest_access_token=guest_access_token, assigned_user_id=registered_user_id, ) # Only give msisdn flows if the x_show_msisdn flag is given: # this is a hack to work around the fact that clients were shipped # that use fallback registration if they see any flows that they don't # recognise, which means we break registration for these clients if we # advertise msisdn flows. Once usage of Riot iOS <=0.3.9 and Riot # Android <=0.6.9 have fallen below an acceptable threshold, this # parameter should go away and we should always advertise msisdn flows. show_msisdn = False if 'x_show_msisdn' in body and body['x_show_msisdn']: show_msisdn = True # FIXME: need a better error than "no auth flow found" for scenarios # where we required 3PID for registration but the user didn't give one require_email = 'email' in self.hs.config.registrations_require_3pid require_msisdn = 'msisdn' in self.hs.config.registrations_require_3pid flows = [] if self.hs.config.enable_registration_captcha: # only support 3PIDless registration if no 3PIDs are required if not require_email and not require_msisdn: flows.extend([[LoginType.RECAPTCHA]]) # only support the email-only flow if we don't require MSISDN 3PIDs if not require_msisdn: flows.extend([[LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA]]) if show_msisdn: # only support the MSISDN-only flow if we don't require email 3PIDs if not require_email: flows.extend([[LoginType.MSISDN, LoginType.RECAPTCHA]]) # always let users provide both MSISDN & email flows.extend([ [LoginType.MSISDN, LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA], ]) else: # only support 3PIDless registration if no 3PIDs are required if not require_email and not require_msisdn: flows.extend([[LoginType.DUMMY]]) # only support the email-only flow if we don't require MSISDN 3PIDs if not require_msisdn: flows.extend([[LoginType.EMAIL_IDENTITY]]) if show_msisdn: # only support the MSISDN-only flow if we don't require email 3PIDs if not require_email or require_msisdn: flows.extend([[LoginType.MSISDN]]) # always let users provide both MSISDN & email flows.extend([ [LoginType.MSISDN, LoginType.EMAIL_IDENTITY] ]) auth_result, params, session_id = yield self.auth_handler.check_auth( flows, body, self.hs.get_ip_from_request(request) ) # Check that we're not trying to register a denied 3pid. # # the user-facing checks will probably already have happened in # /register/email/requestToken when we requested a 3pid, but that's not # guaranteed. if auth_result: for login_type in [LoginType.EMAIL_IDENTITY, LoginType.MSISDN]: if login_type in auth_result: medium = auth_result[login_type]['medium'] address = auth_result[login_type]['address'] if not check_3pid_allowed(self.hs, medium, address): raise SynapseError( 403, "Third party identifier is not allowed", Codes.THREEPID_DENIED, ) if registered_user_id is not None: logger.info( "Already registered user ID %r for this session", registered_user_id ) # don't re-register the threepids add_email = False add_msisdn = False else: # NB: This may be from the auth handler and NOT from the POST if 'password' not in params: raise SynapseError(400, "Missing password.", Codes.MISSING_PARAM) desired_username = params.get("username", None) new_password = params.get("password", None) guest_access_token = params.get("guest_access_token", None) if desired_username is not None: desired_username = desired_username.lower() (registered_user_id, _) = yield self.registration_handler.register( localpart=desired_username, password=new_password, guest_access_token=guest_access_token, generate_token=False, ) # remember that we've now registered that user account, and with # what user ID (since the user may not have specified) self.auth_handler.set_session_data( session_id, "registered_user_id", registered_user_id ) add_email = True add_msisdn = True return_dict = yield self._create_registration_details( registered_user_id, params ) if add_email and auth_result and LoginType.EMAIL_IDENTITY in auth_result: threepid = auth_result[LoginType.EMAIL_IDENTITY] yield self._register_email_threepid( registered_user_id, threepid, return_dict["access_token"], params.get("bind_email") ) if add_msisdn and auth_result and LoginType.MSISDN in auth_result: threepid = auth_result[LoginType.MSISDN] yield self._register_msisdn_threepid( registered_user_id, threepid, return_dict["access_token"], params.get("bind_msisdn") ) defer.returnValue((200, return_dict))
def _get_key(self, request): token = get_access_token_from_request(request) path_without_txn_id = request.path.rsplit("/", 1)[0] return path_without_txn_id + "/" + token
def on_POST(self, request): yield run_on_reactor() kind = "user" if "kind" in request.args: kind = request.args["kind"][0] if kind == "guest": ret = yield self._do_guest_registration() defer.returnValue(ret) return elif kind != "user": raise UnrecognizedRequestError( "Do not understand membership kind: %s" % (kind,) ) body = parse_json_object_from_request(request) # we do basic sanity checks here because the auth layer will store these # in sessions. Pull out the username/password provided to us. desired_password = None if 'password' in body: if (not isinstance(body['password'], basestring) or len(body['password']) > 512): raise SynapseError(400, "Invalid password") desired_password = body["password"] desired_username = None if 'username' in body: if (not isinstance(body['username'], basestring) or len(body['username']) > 512): raise SynapseError(400, "Invalid username") desired_username = body['username'] appservice = None if has_access_token(request): appservice = yield self.auth.get_appservice_by_req(request) # fork off as soon as possible for ASes and shared secret auth which # have completely different registration flows to normal users # == Application Service Registration == if appservice: # Set the desired user according to the AS API (which uses the # 'user' key not 'username'). Since this is a new addition, we'll # fallback to 'username' if they gave one. desired_username = body.get("user", desired_username) access_token = get_access_token_from_request(request) if isinstance(desired_username, basestring): result = yield self._do_appservice_registration( desired_username, access_token, body ) defer.returnValue((200, result)) # we throw for non 200 responses return # == Shared Secret Registration == (e.g. create new user scripts) if 'mac' in body: # FIXME: Should we really be determining if this is shared secret # auth based purely on the 'mac' key? result = yield self._do_shared_secret_registration( desired_username, desired_password, body ) defer.returnValue((200, result)) # we throw for non 200 responses return # == Normal User Registration == (everyone else) if not self.hs.config.enable_registration: raise SynapseError(403, "Registration has been disabled") guest_access_token = body.get("guest_access_token", None) session_id = self.auth_handler.get_session_id(body) registered_user_id = None if session_id: # if we get a registered user id out of here, it means we previously # registered a user for this session, so we could just return the # user here. We carry on and go through the auth checks though, # for paranoia. registered_user_id = self.auth_handler.get_session_data( session_id, "registered_user_id", None ) if desired_username is not None: yield self.registration_handler.check_username( desired_username, guest_access_token=guest_access_token, assigned_user_id=registered_user_id, ) if self.hs.config.enable_registration_captcha: flows = [ [LoginType.RECAPTCHA], [LoginType.EMAIL_IDENTITY, LoginType.RECAPTCHA] ] else: flows = [ [LoginType.DUMMY], [LoginType.EMAIL_IDENTITY] ] authed, auth_result, params, session_id = yield self.auth_handler.check_auth( flows, body, self.hs.get_ip_from_request(request) ) if not authed: defer.returnValue((401, auth_result)) return if registered_user_id is not None: logger.info( "Already registered user ID %r for this session", registered_user_id ) # don't re-register the email address add_email = False else: # NB: This may be from the auth handler and NOT from the POST if 'password' not in params: raise SynapseError(400, "Missing password.", Codes.MISSING_PARAM) desired_username = params.get("username", None) new_password = params.get("password", None) guest_access_token = params.get("guest_access_token", None) (registered_user_id, _) = yield self.registration_handler.register( localpart=desired_username, password=new_password, guest_access_token=guest_access_token, generate_token=False, ) # remember that we've now registered that user account, and with # what user ID (since the user may not have specified) self.auth_handler.set_session_data( session_id, "registered_user_id", registered_user_id ) add_email = True return_dict = yield self._create_registration_details( registered_user_id, params ) if add_email and auth_result and LoginType.EMAIL_IDENTITY in auth_result: threepid = auth_result[LoginType.EMAIL_IDENTITY] yield self._register_email_threepid( registered_user_id, threepid, return_dict["access_token"], params.get("bind_email") ) defer.returnValue((200, return_dict))