Пример #1
0
    def test_change_email_failure_invalid_token(self):
        """
            Test accessing the change email page with an invalid token.

            Expected result: The email address is not changed and a 404 error page is shown.
        """
        email = '*****@*****.**'
        name = 'John Doe'
        user = User(email, name)

        db.session.add(user)
        db.session.commit()

        user_id = user.id
        new_email = '*****@*****.**'
        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = user_id
        token_obj.new_email = new_email
        token = token_obj.create()

        response = self.client.get(f'/user/change-email-address/invalid-{token}', follow_redirects=True)
        user = User.load_from_id(user_id)

        self.assertEqual(404, response.status_code)
        self.assertEqual(email, user.get_email())
Пример #2
0
    def test_change_email_failure_email_in_use(self):
        """
            Test accessing the change email page with an email address that already is in use by another user.

            Expected result: The email address is not changed.
        """
        existing_email = '*****@*****.**'
        existing_name = 'Jane Doe'
        existing_user = User(existing_email, existing_name)

        email = '*****@*****.**'
        name = 'John Doe'
        user = User(email, name)

        db.session.add(existing_user)
        db.session.add(user)
        db.session.commit()

        user_id = user.id
        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = user_id
        token_obj.new_email = existing_email
        token = token_obj.create()

        response = self.client.get(f'/user/change-email-address/{token}', follow_redirects=True)
        data = response.get_data(as_text=True)
        user = User.load_from_id(user_id)

        self.assertIn('The email address already is in use.', data)
        self.assertEqual(email, user.get_email())
Пример #3
0
def reset_password_request() -> str:
    """
        Show a form to request resetting the password and process it upon submission.

        :return: The HTML response.
    """

    form = EmailForm()
    if form.validate_on_submit():
        user = User.load_from_email(form.email.data)
        if user is not None:
            token = user.send_password_reset_email()
        else:
            # Create a fake token to get the validity.
            token = ChangeEmailAddressToken()

        validity = token.get_validity(in_minutes=True)

        # Display a success message even if the specified address does not belong to a user account. Otherwise,
        # infiltrators could deduce if an account exists and use this information for attacks.
        flash(_('An email has been sent to the specified address. Please be aware that the included link for resetting \
                the password is only valid for %(validity)d minutes.', validity=validity))
        return redirect(url_for('userprofile.login'))

    return render_template('userprofile/reset_password_request.html', title=_('Forgot Your Password?'), form=form)
Пример #4
0
    def test_change_email_success(self):
        """
            Test accessing the change email page with a valid token.

            Expected result: The email address is changed.
        """
        email = '*****@*****.**'
        name = 'John Doe'
        user = User(email, name)

        db.session.add(user)
        db.session.commit()

        user_id = user.id
        new_email = '*****@*****.**'
        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = user_id
        token_obj.new_email = new_email
        token = token_obj.create()

        response = self.client.get(f'/user/change-email-address/{token}', follow_redirects=True)
        data = response.get_data(as_text=True)
        user = User.load_from_id(user_id)

        self.assertIn('Your email address has successfully been changed.', data)
        self.assertEqual(new_email, user.get_email())
Пример #5
0
    def test_change_email_failure_no_user(self):
        """
            Test accessing the change email page with a valid token for a non-existing user.

            Expected result: The email address is not changed and a 404 error page is shown.
        """

        user = self.create_user(email='*****@*****.**',
                                name='John Doe',
                                password='******')

        new_email = '*****@*****.**'
        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = user.id
        token_obj.new_email = new_email
        token = token_obj.create()

        db.session.delete(user)
        db.session.commit()

        data = self.get(f'/user/change-email-address/{token}',
                        expected_status=404)

        self.assertNotIn('Your email address has successfully been changed.',
                         data)
Пример #6
0
    def test_change_email_failure_email_in_use(self):
        """
            Test accessing the change email page with an email address that already is in use by another user.

            Expected result: The email address is not changed.
        """

        existing_email = '*****@*****.**'
        existing_name = 'Jane Doe'
        self.create_user(email=existing_email,
                         name=existing_name,
                         password='******')

        email = '*****@*****.**'
        name = 'John Doe'
        user = self.create_user(email=email, name=name, password='******')

        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = user.id
        token_obj.new_email = existing_email
        token = token_obj.create()

        data = self.get(f'/user/change-email-address/{token}')

        user = User.load_from_id(user.id)

        self.assertIn('The email address already is in use.', data)
        self.assertEqual(email, user.email)
Пример #7
0
    def test_change_email_failure_invalid_token(self):
        """
            Test accessing the change email page with an invalid token.

            Expected result: The email address is not changed and a 404 error page is shown.
        """

        email = '*****@*****.**'
        user = self.create_user(email=email,
                                name='John Doe',
                                password='******')

        new_email = '*****@*****.**'
        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = user.id
        token_obj.new_email = new_email
        token = token_obj.create()

        data = self.get(f'/user/change-email-address/invalid-{token}',
                        expected_status=404)

        user = User.load_from_id(user.id)

        self.assertNotIn('Your email address has successfully been changed.',
                         data)
        self.assertEqual(email, user.email)
Пример #8
0
    def set_email_address_from_token(token: str) -> bool:
        """
            Verify the token to change a user's email address. If it is valid, change the email address of the user
            given in the token to the email address given in the token.

            To get a token, execute :meth:`request_email_address_change`.

            :param token: The change-email token.
            :return: `True` if the email address has been set, `False` if the email address could not be set.
            :raise EasyJWTError: If the given token is invalid.
            :raise ValueError: If the user given in the token does not exist.
        """

        token_obj = ChangeEmailAddressToken.verify(token)
        user = User.load_from_id(token_obj.user_id)
        if user is None:
            raise ValueError(f'User {token_obj.user_id} does not exist')

        # Set the email address and commit the change to the DB on success.
        changed = user._set_email(token_obj.new_email)
        if not changed:
            return False

        db.session.commit()
        return True
Пример #9
0
    def test_init(self):
        """
            Test initializing a change email address token.

            Expected result: The token is initialized with emtpy values.
        """

        token = ChangeEmailAddressToken()
        self.assertIsNotNone(token)
        self.assertIsNone(token.user_id)
        self.assertIsNone(token.new_email)
Пример #10
0
    def verify_change_email_address_token(token: str) -> Tuple[Optional['User'], Optional[str]]:
        """
            Verify the JWT to change a user's email address.

            :param token: The change-email token.
            :return: The user to which the token belongs and the new email address; both are ``None`` if the token is
                     invalid.
        """
        token_obj = ChangeEmailAddressToken.verify(token)
        user = User.load_from_id(token_obj.user_id)
        return user, token_obj.new_email
Пример #11
0
    def test_change_email_success(self):
        """
            Test accessing the change email page with a valid token.

            Expected result: The email address is changed.
        """

        user = self.create_user(email='*****@*****.**',
                                name='John Doe',
                                password='******')

        new_email = '*****@*****.**'
        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = user.id
        token_obj.new_email = new_email
        token = token_obj.create()

        data = self.get(f'/user/change-email-address/{token}')

        user = User.load_from_id(user.id)

        self.assertIn('Your email address has successfully been changed.',
                      data)
        self.assertEqual(new_email, user.email)
Пример #12
0
    def send_change_email_address_email(self, email: str) -> ChangeEmailAddressToken:
        """
            Send a token to the user to change their email address.

            :param email: The email address to which the token will be sent and to which the user's email will be
                          changed upon verification.
            :return: The token send in the mail.
        """

        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = self.id
        token_obj.new_email = email

        token = token_obj.create()
        validity = token_obj.get_validity(in_minutes=True)

        link = url_for('userprofile.change_email', token=token, _external=True)
        email_old = self.get_email()

        email_obj = Email(_('Change Your Email Address'), 'userprofile/emails/change_email_address_request')
        email_obj.prepare(name=self.name, link=link, validity=validity, email_old=email_old, email_new=email)
        email_obj.send(email)

        return token_obj
Пример #13
0
    def request_email_address_change(self,
                                     new_email_address: str) -> timedelta:
        """
            Request to change the user's email address to the given new email address.

            This method will only create a JWT and send it in an email to the user's new email address. The user will
            then have to verify this token within the token's validity to actually change the email address to the new
            one. Until this verification has taken place, the email address will not have been changed.

            To verify the token and actually set the new email address, execute :meth:`set_email_from_token`.

            :param new_email_address: The email address to which the token will be sent and to which the user's email
                                      will be changed upon verification.
            :return: The validity of the token.
        """

        token_obj = ChangeEmailAddressToken()
        token_obj.user_id = self.id
        token_obj.new_email = new_email_address

        token = token_obj.create()
        validity: timedelta = token_obj.get_validity()

        link = url_for('userprofile.change_email', token=token, _external=True)
        email_old = self.email

        email_obj = Email(_('Change Your Email Address'),
                          'userprofile/emails/change_email_address_request')
        email_obj.prepare(name=self.name,
                          link=link,
                          validity=timedelta_to_minutes(validity),
                          email_old=email_old,
                          email_new=new_email_address)
        email_obj.send(new_email_address)

        return validity