async def on_POST(self, request): if self.hs.config.threepid_behaviour_email == ThreepidBehaviour.OFF: if self.hs.config.local_threepid_handling_disabled_due_to_email_config: logger.warning( "Email registration has been disabled due to lack of email config" ) raise SynapseError( 400, "Email-based registration has been disabled on this server") body = parse_json_object_from_request(request) assert_params_in_dict(body, ["client_secret", "email", "send_attempt"]) # Extract params from body client_secret = body["client_secret"] assert_valid_client_secret(client_secret) # For emails, canonicalise the address. # We store all email addresses canonicalised in the DB. # (See on_POST in EmailThreepidRequestTokenRestServlet # in synapse/rest/client/v2_alpha/account.py) try: email = canonicalise_email(body["email"]) except ValueError as e: raise SynapseError(400, str(e)) send_attempt = body["send_attempt"] next_link = body.get("next_link") # Optional param if not check_3pid_allowed(self.hs, "email", email): raise SynapseError( 403, "Your email domain is not authorized to register on this server", Codes.THREEPID_DENIED, ) existing_user_id = await self.hs.get_datastore( ).get_user_id_by_threepid("email", email) if existing_user_id is not None: if self.hs.config.request_token_inhibit_3pid_errors: # Make the client think the operation succeeded. See the rationale in the # comments for request_token_inhibit_3pid_errors. return 200, {"sid": random_string(16)} raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) if self.config.threepid_behaviour_email == ThreepidBehaviour.REMOTE: assert self.hs.config.account_threepid_delegate_email # Have the configured identity server handle the request ret = await self.identity_handler.requestEmailToken( self.hs.config.account_threepid_delegate_email, email, client_secret, send_attempt, next_link, ) else: # Send registration emails from Synapse sid = await self.identity_handler.send_threepid_validation( email, client_secret, send_attempt, self.mailer.send_registration_mail, next_link, ) # Wrap the session id in a JSON object ret = {"sid": sid} return 200, ret
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]: body = parse_json_object_from_request(request) assert_params_in_dict( body, ["client_secret", "country", "phone_number", "send_attempt"]) client_secret = body["client_secret"] assert_valid_client_secret(client_secret) country = body["country"] phone_number = body["phone_number"] send_attempt = body["send_attempt"] next_link = body.get("next_link") # Optional param msisdn = phone_number_to_msisdn(country, phone_number) if not check_3pid_allowed(self.hs, "msisdn", msisdn): raise SynapseError( 403, "Phone numbers are not authorized to register on this server", Codes.THREEPID_DENIED, ) await self.identity_handler.ratelimit_request_token_requests( request, "msisdn", msisdn) existing_user_id = await self.hs.get_datastore( ).get_user_id_by_threepid("msisdn", msisdn) if existing_user_id is not None: if self.hs.config.server.request_token_inhibit_3pid_errors: # Make the client think the operation succeeded. See the rationale in the # comments for request_token_inhibit_3pid_errors. # Also wait for some random amount of time between 100ms and 1s to make it # look like we did something. await self.hs.get_clock().sleep(random.randint(1, 10) / 10) return 200, {"sid": random_string(16)} raise SynapseError(400, "Phone number is already in use", Codes.THREEPID_IN_USE) if not self.hs.config.registration.account_threepid_delegate_msisdn: logger.warning( "No upstream msisdn account_threepid_delegate configured on the server to " "handle this request") raise SynapseError( 400, "Registration by phone number is not supported on this homeserver" ) ret = await self.identity_handler.requestMsisdnToken( self.hs.config.registration.account_threepid_delegate_msisdn, country, phone_number, client_secret, send_attempt, next_link, ) threepid_send_requests.labels(type="msisdn", reason="register").observe(send_attempt) return 200, ret
async def on_POST(self, request): if self.config.threepid_behaviour_email == ThreepidBehaviour.OFF: if self.config.local_threepid_handling_disabled_due_to_email_config: logger.warning( "Adding emails have been disabled due to lack of an email config" ) raise SynapseError( 400, "Adding an email to your account is disabled on this server") body = parse_json_object_from_request(request) assert_params_in_dict(body, ["client_secret", "email", "send_attempt"]) client_secret = body["client_secret"] assert_valid_client_secret(client_secret) # Canonicalise the email address. The addresses are all stored canonicalised # in the database. # This ensures that the validation email is sent to the canonicalised address # as it will later be entered into the database. # Otherwise the email will be sent to "*****@*****.**" and stored as # "*****@*****.**" in database. try: email = canonicalise_email(body["email"]) except ValueError as e: raise SynapseError(400, str(e)) send_attempt = body["send_attempt"] next_link = body.get("next_link") # Optional param if not check_3pid_allowed(self.hs, "email", email): raise SynapseError( 403, "Your email domain is not authorized on this server", Codes.THREEPID_DENIED, ) self.identity_handler.ratelimit_request_token_requests( request, "email", email) if next_link: # Raise if the provided next_link value isn't valid assert_valid_next_link(self.hs, next_link) existing_user_id = await self.store.get_user_id_by_threepid( "email", email) if existing_user_id is not None: if self.config.request_token_inhibit_3pid_errors: # Make the client think the operation succeeded. See the rationale in the # comments for request_token_inhibit_3pid_errors. # Also wait for some random amount of time between 100ms and 1s to make it # look like we did something. await self.hs.get_clock().sleep(random.randint(1, 10) / 10) return 200, {"sid": random_string(16)} raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE) if self.config.threepid_behaviour_email == ThreepidBehaviour.REMOTE: assert self.hs.config.account_threepid_delegate_email # Have the configured identity server handle the request ret = await self.identity_handler.requestEmailToken( self.hs.config.account_threepid_delegate_email, email, client_secret, send_attempt, next_link, ) else: # Send threepid validation emails from Synapse sid = await self.identity_handler.send_threepid_validation( email, client_secret, send_attempt, self.mailer.send_add_threepid_mail, next_link, ) # Wrap the session id in a JSON object ret = {"sid": sid} threepid_send_requests.labels( type="email", reason="add_threepid").observe(send_attempt) return 200, ret
async def on_POST(self, request): if self.config.threepid_behaviour_email == ThreepidBehaviour.OFF: if self.config.local_threepid_handling_disabled_due_to_email_config: logger.warning( "User password resets have been disabled due to lack of email config" ) raise SynapseError( 400, "Email-based password resets have been disabled on this server" ) body = parse_json_object_from_request(request) assert_params_in_dict(body, ["client_secret", "email", "send_attempt"]) # Extract params from body client_secret = body["client_secret"] assert_valid_client_secret(client_secret) # Canonicalise the email address. The addresses are all stored canonicalised # in the database. This allows the user to reset his password without having to # know the exact spelling (eg. upper and lower case) of address in the database. # Stored in the database "*****@*****.**" # User requests with "*****@*****.**" would raise a Not Found error try: email = canonicalise_email(body["email"]) except ValueError as e: raise SynapseError(400, str(e)) send_attempt = body["send_attempt"] next_link = body.get("next_link") # Optional param if next_link: # Raise if the provided next_link value isn't valid assert_valid_next_link(self.hs, next_link) self.identity_handler.ratelimit_request_token_requests( request, "email", email) # The email will be sent to the stored address. # This avoids a potential account hijack by requesting a password reset to # an email address which is controlled by the attacker but which, after # canonicalisation, matches the one in our database. existing_user_id = await self.hs.get_datastore( ).get_user_id_by_threepid("email", email) if existing_user_id is None: if self.config.request_token_inhibit_3pid_errors: # Make the client think the operation succeeded. See the rationale in the # comments for request_token_inhibit_3pid_errors. # Also wait for some random amount of time between 100ms and 1s to make it # look like we did something. await self.hs.get_clock().sleep(random.randint(1, 10) / 10) return 200, {"sid": random_string(16)} raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND) if self.config.threepid_behaviour_email == ThreepidBehaviour.REMOTE: assert self.hs.config.account_threepid_delegate_email # Have the configured identity server handle the request ret = await self.identity_handler.requestEmailToken( self.hs.config.account_threepid_delegate_email, email, client_secret, send_attempt, next_link, ) else: # Send password reset emails from Synapse sid = await self.identity_handler.send_threepid_validation( email, client_secret, send_attempt, self.mailer.send_password_reset_mail, next_link, ) # Wrap the session id in a JSON object ret = {"sid": sid} threepid_send_requests.labels( type="email", reason="password_reset").observe(send_attempt) return 200, ret
async def on_POST(self, request): if self.config.threepid_behaviour_email == ThreepidBehaviour.OFF: if self.config.local_threepid_handling_disabled_due_to_email_config: logger.warning( "User password resets have been disabled due to lack of email config" ) raise SynapseError( 400, "Email-based password resets have been disabled on this server" ) body = parse_json_object_from_request(request) assert_params_in_dict(body, ["client_secret", "email", "send_attempt"]) # Extract params from body client_secret = body["client_secret"] assert_valid_client_secret(client_secret) email = body["email"] send_attempt = body["send_attempt"] next_link = body.get("next_link") # Optional param if not check_3pid_allowed(self.hs, "email", email): raise SynapseError( 403, "Your email domain is not authorized on this server", Codes.THREEPID_DENIED, ) existing_user_id = await self.hs.get_datastore( ).get_user_id_by_threepid("email", email) if existing_user_id is None: if self.config.request_token_inhibit_3pid_errors: # Make the client think the operation succeeded. See the rationale in the # comments for request_token_inhibit_3pid_errors. return 200, {"sid": random_string(16)} raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND) if self.config.threepid_behaviour_email == ThreepidBehaviour.REMOTE: assert self.hs.config.account_threepid_delegate_email # Have the configured identity server handle the request ret = await self.identity_handler.requestEmailToken( self.hs.config.account_threepid_delegate_email, email, client_secret, send_attempt, next_link, ) else: # Send password reset emails from Synapse sid = await self.identity_handler.send_threepid_validation( email, client_secret, send_attempt, self.mailer.send_password_reset_mail, next_link, ) # Wrap the session id in a JSON object ret = {"sid": sid} return 200, ret