예제 #1
0
    async def on_POST(self, request):
        body = parse_json_object_from_request(request)

        assert_params_in_dict(
            body, ["client_secret", "country", "phone_number", "send_attempt"])
        client_secret = body["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,
            )

        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.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.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.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
예제 #2
0
파일: register.py 프로젝트: Fnux/synapse
    async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
        if self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
            if (self.hs.config.email.
                    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/account.py)
        try:
            email = validate_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,
            )

        await self.identity_handler.ratelimit_request_token_requests(
            request, "email", email)

        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.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, "Email is already in use",
                               Codes.THREEPID_IN_USE)

        if self.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
            assert self.hs.config.registration.account_threepid_delegate_email

            # Have the configured identity server handle the request
            ret = await self.identity_handler.requestEmailToken(
                self.hs.config.registration.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}

        threepid_send_requests.labels(type="email",
                                      reason="register").observe(send_attempt)

        return 200, ret
예제 #3
0
    async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
        if self.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
            if self.config.email.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 = validate_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)

        await 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.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, "Email not found",
                               Codes.THREEPID_NOT_FOUND)

        if self.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
            assert self.hs.config.registration.account_threepid_delegate_email

            # Have the configured identity server handle the request
            ret = await self.identity_handler.requestEmailToken(
                self.hs.config.registration.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
예제 #4
0
    async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
        if self.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
            if self.config.email.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 = validate_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 await check_3pid_allowed(self.hs, "email", email):
            raise SynapseError(
                403,
                "Your email is not authorized on this server",
                Codes.THREEPID_DENIED,
            )

        await 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.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, "Email is already in use",
                               Codes.THREEPID_IN_USE)

        if self.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
            assert self.hs.config.registration.account_threepid_delegate_email

            # Have the configured identity server handle the request
            ret = await self.identity_handler.requestEmailToken(
                self.hs.config.registration.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