def test_reset_password(self, mailgun_mock):
        mailgun_mock.return_value = None

        with app.app_context():
            found_user = UserDAO().get(self.test_uid)
            self.assertIsNotNone(found_user)
            original_token = found_user.reset_token

            data = {
                'email': self.test_user_email,
            }

            response = self.test_client.put(
                '/users/reset_password',
                content_type='application/json',
                data=json.dumps(data),
            )

            self.assertEqual(response.status_code, HTTPStatus.OK)

            found_user = UserDAO().get(self.test_uid)

            self.assertIsNotNone(found_user)
            self.assertIsNotNone(found_user.reset_token)
            self.assertNotEqual(found_user.reset_token, original_token)
    def test_reset_password_token_resets_password(self, mailgun_mock):
        mailgun_mock.return_value = None

        with app.app_context():
            found_user = UserDAO().get(self.test_uid)
            self.assertIsNotNone(found_user)
            original_token = found_user.reset_token
            original_password = found_user.password

            data = {
                'email': self.test_user_email,
            }

            response = self.test_client.put(
                '/users/reset_password',
                content_type='application/json',
                data=json.dumps(data),
            )

            self.assertEqual(response.status_code, HTTPStatus.OK)

            found_user = UserDAO().get(self.test_uid)

            self.assertIsNotNone(found_user)
            self.assertIsNotNone(found_user.reset_token)
            self.assertNotEqual(found_user.reset_token, original_token)

            # Now reset the password and verify it worked..
            data = {
                'token': found_user.reset_token,
                'plaintext_password': '******'
            }

            response = self.test_client.post(
                '/users/reset_password',
                content_type='application/json',
                data=json.dumps(data),
            )

            self.assertEqual(response.status_code, HTTPStatus.OK)

            found_user = UserDAO().get(self.test_uid)

            self.assertIsNotNone(found_user)
            self.assertIsNone(found_user.reset_token)

            self.assertNotEqual(found_user.password, original_password)
            # Verify new password works.
            self.assertTrue(
                User.bcrypt_compare(data['plaintext_password'],
                                    found_user.password))

            # Kind of a duplicate, but verify old doesn't work.
            self.assertFalse(
                User.bcrypt_compare(data['plaintext_password'],
                                    original_password))
Example #3
0
    def authenticate(username, password):
        user = UserDAO().get_by_username(username)
        if User.bcrypt_compare(password, user.password):
            jwt_claim = uuid.uuid4()
            db.session.query(User).filter_by(public_id=user.public_id).update(
                {'jwt_claim': jwt_claim})
            db.session.commit()

            user.jwt_claim = jwt_claim
            return user
    def setUpClass(cls):
        with app.app_context():
            db.drop_all()
            db.create_all()

            cls.test_dao = UserDAO()

            test_user = User('*****@*****.**', 'testpw',
                             'test-{0}-username'.format(uuid.uuid4()))

            deleted_user = User('*****@*****.**', 'testpassword',
                                'test-{0}-username'.format(uuid.uuid4()))
            deleted_user.is_deleted = True

            user_to_delete = User('*****@*****.**', 'testpw',
                                  'test-{0}-username'.format(uuid.uuid4()))

            cls.test_uid = test_user.public_id
            cls.deleted_uid = deleted_user.public_id
            cls.to_delete_uid = user_to_delete.public_id

            db.session.add(test_user)
            db.session.add(deleted_user)
            db.session.add(user_to_delete)
            db.session.commit()
Example #5
0
    def regenerate_verification_token(self, email):
        """
        Handles generating a new verification token should a user ever forget
        theirs.

        :param str email: The email of the user who forgot/lost their
        verification email.
        :rtype: str
        :return: The newly generated verification token.
        """

        try:
            new_token, user = UserDAO().regenerate_token(email, 'verify_token')

            MailgunIntegration.send_email(
                current_app.config['MAILGUN_ORIGIN_EMAIL'], user.email,
                'Please verify your account',
                current_app.config['VERIFY_EMAIL_CONTENT'].format(new_token))

            return new_token
        except IntegrationException as e:
            logging.error(
                'Failed to generate token for user with exception: {0}'.format(
                    e))

            raise FacadeException(
                'Failed to generate new token. Email sending failed.',
                e.status_code)
        except DAOException as e:
            logging.error(
                'Failed to generate token for user with exception: {0}'.format(
                    e))

            raise FacadeException(
                'Failed to generate new token: {0}'.format(e), e.status_code)
    def setUpClass(cls):
        with app.app_context():
            db.drop_all()
            db.create_all()

            cls.test_client = app.test_client()
            cls.test_dao = UserDAO()
Example #7
0
    def regenerate_reset_password_token(self, email):
        """
        Regenerates a reset password token and sends another email.

        :param str email: The email of the user who forgot/lost their
        reset password email token.
        :rtype: str
        :return: The newly generated token.
        """
        try:
            new_token, user = UserDAO().regenerate_token(email, 'reset_token')

            MailgunIntegration().send_email(
                current_app.config['MAILGUN_ORIGIN_EMAIL'], user.email,
                'Reset your password',
                current_app.config['RESET_EMAIL_CONTENT'].format(
                    '{0}/users/reset_password/{1}'.format(
                        current_app.config['HOST'],
                        new_token,
                    )))

            return new_token
        except IntegrationException as e:
            logging.error('Failed to send email with exception: {0}'.format(e))

            raise FacadeException('Failed to send reset token email.',
                                  e.status_code)
        except DAOException as e:
            logging.error(
                'Failed to regenerate reset token with exception: {0}'.format(
                    e))

            raise FacadeException('Failed to regenerate reset token.',
                                  e.status_code)
Example #8
0
    def delete(self, user_id):
        user_info = UserDAO().soft_delete(user_id)

        logging.info(
            'Successfully soft deleted user {0} for requesting user.'.format(
                user_id))

        return jsonify(UserMarshal().dump(user_info).data)
Example #9
0
    def delete(self):
        """
        Logs a user out and invalidates their JWT.
        """
        UserDAO().logout_current_user()

        logging.info('Successfully logged out user')

        return jsonify({'success': True})
Example #10
0
    def put(self, user_id):
        arg_fields = {
            'email': String(),
            'current_password': String(),
            'plaintext_password': String()
        }
        args = parser.parse(arg_fields)

        user_info = UserDAO().update_user_data(user_id, **args)

        logging.info(
            'Successfully updated information for user {0}'.format(user_info))

        return jsonify(UserMarshal().dump(user_info).data)
    def setUpClass(cls):
        with app.app_context():
            db.drop_all()
            db.create_all()

            cls.test_client = app.test_client()
            cls.test_dao = UserDAO()

            test_user = User('*****@*****.**', 'testpw', 'test-verify')

            cls.test_user_token = test_user.verify_token
            cls.test_uid = test_user.public_id

            db.session.add(test_user)
            db.session.commit()
Example #12
0
    def post(self):
        """
        Validate a user by providing the correct token.
        """
        arg_fields = {
            'token': String(required=True),
        }
        args = parser.parse(arg_fields)

        validated_user = UserDAO().verify_token(args['token'])

        logging.info('Successfully validated token {0} for user {1}.'.format(
            args['token'],
            validated_user,
        ))

        return jsonify(UserMarshal().dump(validated_user).data)
    def post(self):
        """
        Reset a users password.
        """
        arg_fields = {
            'token': String(required=True),
            'plaintext_password': String(required=True)
        }
        args = parser.parse(arg_fields)

        validated_user = UserDAO().reset_user_password(**args)

        logging.info('Successfully validated token {0} for user {1}.'.format(
            args['token'],
            validated_user,
        ))

        return jsonify(UserMarshal().dump(validated_user).data)
Example #14
0
    def get(self, user_id):
        user_info = UserDAO().get(user_id)

        if user_info is None:
            logging.info('Requested user ({0} does not exist.'.format(user_id))

            raise EndpointException('Requested user does not exist.',
                                    HTTPStatus.NOT_FOUND)

        if not user_info.is_validated:
            logging.info('Requested unvalidated account: {0}'.format(user_id))

            raise EndpointException('Account is not validated.',
                                    HTTPStatus.FORBIDDEN)

        logging.info('Retrieved user info for {0}'.format(user_id))

        return jsonify(UserMarshal().dump(user_info).data)
Example #15
0
    def test_token_verification_fail_invalid_token(self):
        with app.app_context():
            data = {
                'token': 'asldkfjalksdjf',
            }

            response = self.test_client.post(
                '/users/verify'.format(self.test_uid),
                content_type='application/json',
                data=json.dumps(data),
            )

            self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND)

            found_user = UserDAO().get(self.test_uid)

            self.assertIsNotNone(found_user)
            self.assertIsNotNone(found_user.verify_token)
            self.assertFalse(found_user.is_validated)
Example #16
0
    def create_new_user(self, email, plaintext_password, username):
        """
        Handles creation of a new user and sending the verification token to
        the user.

        :param str email: The user's email
        :param str plaintext_password: The plaintext password. Is hashed
        at the model level.
        :param str username: The requested username for the user.
        :rtype: UserTable
        :return: The newly created user.
        """
        try:
            new_user = UserDAO().create_new_user(email, plaintext_password,
                                                 username)

            MailgunIntegration().send_email(
                current_app.config['MAILGUN_ORIGIN_EMAIL'], new_user.email,
                'Please verify your account',
                current_app.config['VERIFY_EMAIL_CONTENT'].format(
                    '{0}/users/verify/{1}'.format(
                        current_app.config['HOST'],
                        new_user.verify_token,
                    )))

            return new_user
        except IntegrationException as e:
            db.session.rollback()
            logging.error(
                'Failed to send mail when creating new user: {0}'.format(e))

            raise FacadeException('Failed to create user. Cannot send email.',
                                  e.status_code)
        except DAOException as e:
            db.session.rollback()
            logging.error(
                'Failed to create new user with exception: {0}'.format(e))

            raise FacadeException(
                'Failed to create user. User creation failed.', e.status_code)
        finally:
            self._safe_commit()
Example #17
0
    def test_token_verification(self):
        with app.app_context():
            data = {
                'token': self.test_user_token,
            }

            response = self.test_client.post(
                '/users/verify',
                content_type='application/json',
                data=json.dumps(data),
            )

            self.assertEqual(response.status_code, HTTPStatus.OK)
            self.assertIsNotNone(response)

            found_user = UserDAO().get(self.test_uid)

            self.assertIsNotNone(found_user)
            self.assertIsNone(found_user.verify_token)
            self.assertTrue(found_user.is_validated)