def test_change_password_successfully(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    insert_test_user(session)
    sut = UserPersistence(postgresql_db)
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'

    old_hash = user.hash

    sut.change_password_for_user('*****@*****.**', 'password')
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'

    assert not user.hash == old_hash
def test_block_existent_user_successfully(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    insert_test_user(session)
    sut = UserPersistence(postgresql_db)
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'
    assert user.full_name == 'Test User'
    assert user.phone_number == '444-4444'
    assert user.blocked_user == '0'

    sut.block_user('*****@*****.**')
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'
    assert user.blocked_user == '1'
def test_retrieve_existent_user(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    insert_test_user(session)
    sut = UserPersistence(postgresql_db)
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'
    assert user.full_name == 'Test User'
    assert user.phone_number == '444-4444'
def test_cant_change_password_for_firebase_user(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    insert_firebase_test_user(session)
    sut = UserPersistence(postgresql_db)
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'

    with pytest.raises(CantChangePasswordForFirebaseUser):
        sut.change_password_for_user('*****@*****.**', 'password')
def test_cant_unblock_user_because_doesnt_exist(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    insert_test_user(session)
    sut = UserPersistence(postgresql_db)
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'

    with pytest.raises(UserNotFoundException):
        sut.unblock_user('*****@*****.**')
def test_cant_change_password_for_non_existent_user(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    insert_test_user(session)
    sut = UserPersistence(postgresql_db)
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'

    with pytest.raises(UserNotFoundException):
        sut.change_password_for_user('*****@*****.**', 'password')
def test_cant_block_user_because_user_is_already_blocked(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    insert_test_user(session)
    sut = UserPersistence(postgresql_db)
    user = sut.get_user_by_email('*****@*****.**')
    assert user.email == '*****@*****.**'
    sut.block_user('*****@*****.**')

    with pytest.raises(UserlAlreadyBlockedException):
        sut.block_user('*****@*****.**')
def _get_user_profile(user_email):

    logger.debug('Requested {0} profile'.format(user_email))

    user_persistence = UserPersistence(current_app.db)

    try:
        user = user_persistence.get_user_by_email(user_email)
        result = format_with_underscores(user.serialize())
        status_code = 200
        logger.debug('User profile found')
    except UserNotFoundException:
        logger.debug('User doesnt exist')
        result = {'Error': 'user {0} doesnt exist'.format(user_email)}
        status_code = 404

    return result, status_code
def _login_user():
    data = request.json
    logger.debug(data['email'])
    with current_app.app_context():
        result, status_code, user = get_user(current_app.client, data['email'])
        if status_code == 200:
            if validar_usuario(user, data['password']):
                logger.debug('Usuario logueado con exito')
                user_persistence = UserPersistence(current_app.db)
                user_found = user_persistence.get_user_by_email(data['email'])
                token = generate_auth_token(user_found)
                logger.debug('This is the token {0}'.format(token))
                result = {'Token': token}
            else:
                logger.debug('Incorrect user or password')
                result = {'Login': '******'}
                status_code = 401
    return result, status_code
def _login_user_using_firebase():
    try:
        id_token = request.headers.get('authorization', None)
        claims = firebase_admin.auth.verify_id_token(id_token)
        if not claims or not claims.get('email'):
            logger.debug('Response from auth server login is 401')
            result = {'Login': '******'}
            status_code = 401
            return result, status_code

        user_persistence = UserPersistence(current_app.db)
        user = None
        try:
            user = user_persistence.get_user_by_email(claims.get('email'))
        except UserNotFoundException:
            user = User(claims.get('email'), None, claims.get('name'), 'NULL',
                        claims.get('picture'), True, False, False)
            user_persistence.save(user)

        if user.is_blocked_user():
            logger.debug('This user is BLOCKED')
            result = {'Login': '******'}
            status_code = 401
        elif user.is_firebase_user():
            logger.debug('Usuario logueado con exito')
            token = generate_auth_token(user)
            logger.debug('This is the token {0}'.format(token))
            result = {'Token': token, 'claims': claims}
            status_code = HTTPStatus.OK
        else:
            logger.debug('User not registered with Firebase')
            result = {'Login': '******'}
            status_code = 401
        return result, status_code
    except ValueError as exc:
        result = {'Login': '******'}
        status_code = 401
        logger.error(exc)
        return result, status_code
    except firebase_admin._auth_utils.InvalidIdTokenError as invalid_token_error:
        result = {'Register': str(invalid_token_error)}
        status_code = 401
        logger.error(invalid_token_error)
        return result, status_code
def test_retrieve_inexistent_user(postgresql_db):
    session = postgresql_db.session
    create_all(session)
    sut = UserPersistence(postgresql_db)
    with pytest.raises(UserNotFoundException):
        user = sut.get_user_by_email('*****@*****.**')
def _forgot_password(user_email):

    logger.debug('Forgot password request from user:{0}'.format(user_email))

    try:
        user_persistence = UserPersistence(current_app.db)
        user = user_persistence.get_user_by_email(user_email)

        if user.is_firebase_user():
            result = {
                "Error": "user {0} is a firebase user".format(user_email)
            }
            status_code = HTTPStatus.PRECONDITION_FAILED
            logger.debug('User is firebase user. Cant change password')
        else:
            reset_password_persistence = ResetPasswordPersistence(
                current_app.db)
            try:
                # Ya teniamos un codigo para resetear la pass de este usuario
                # Si esta vencido le damos uno nuevo y sino le mandamos el mismo
                reset_password_obtained = reset_password_persistence.get_reset_password_by_email(
                    user_email)
                logger.debug('User already has reset password')
                if reset_password_obtained.is_token_expired():
                    try:
                        logger.debug('Token expired. Regenerating new one')
                        reset_password_persistence.delete(user_email)
                        reset_password_updated = ResetPassword(user_email)
                        reset_password_persistence.save(reset_password_updated)

                        send_email_with_reset_password_token(
                            user_email, reset_password_updated.token)

                        result = {
                            "Forgot password":
                            "******".format(user_email)
                        }
                        status_code = HTTPStatus.OK
                        logger.debug(
                            'Email sent to user:{0}'.format(user_email))
                    except ResetPasswordNotFoundException:
                        logger.critical(
                            'Trying to delete non existent reset password')
                        result = {
                            "Error":
                            "couldnt update token for user {0}".format(
                                user_email)
                        }
                        status_code = HTTPStatus.INTERNAL_SERVER_ERROR
                    except ResetPasswordForNonExistentUserException:
                        logger.critical(
                            'Trying to generate reset password for inexistent user in Users table. Super critical!'
                        )
                        result = {
                            "Error":
                            "user {0} doesnt exist in table users".format(
                                user_email)
                        }
                        status_code = HTTPStatus.INTERNAL_SERVER_ERROR
                else:
                    logger.debug('Token is still valid. Sending email again')
                    send_email_with_reset_password_token(
                        user_email, reset_password_obtained.token)
                    result = {
                        "Forgot password":
                        "******".format(user_email)
                    }
                    status_code = HTTPStatus.OK
                    logger.debug('Email sent to user:{0}'.format(user_email))
            except ResetPasswordNotFoundException:
                # No tenemos un codigo activo para resetear la pass de este user
                # Creamos uno
                logger.debug('User hasnt reset password. Lets create one')
                try:
                    reset_password_to_save = ResetPassword(user_email)
                    reset_password_persistence.save(reset_password_to_save)

                    result = {
                        "Forgot password":
                        "******".format(user_email)
                    }
                    status_code = HTTPStatus.OK

                    send_email_with_reset_password_token(
                        user_email, reset_password_to_save.token)

                    logger.debug('Email sent to user:{0}'.format(user_email))
                except ResetPasswordForNonExistentUserException:
                    logger.critical(
                        'Trying to generate reset password for inexistent user in Users table!'
                    )
                    result = {
                        "Error":
                        "user {0} doesnt exist in table users".format(
                            user_email)
                    }
                    status_code = HTTPStatus.INTERNAL_SERVER_ERROR
    except UserNotFoundException:
        result = {"Error": "user {0} doesnt exist".format(user_email)}
        status_code = HTTPStatus.NOT_FOUND
        logger.debug('User doesnt exist')

    return result, status_code