Ejemplo n.º 1
0
def set_standalone_user(user_id: int):
    ''' changes user password when logged in'''
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    username = post_data.get('username')
    pw_old = post_data.get('old_password')
    pw_new = post_data.get('new_password')
    if not username or not pw_old or not pw_new:
        raise InvalidPayload()

    # fetch the user data
    user = User.get(user_id)
    if not user.fb_id:
        raise NotFoundException(
            message='Must be a facebook user login. Please try again.')

    # fetch the user data
    user = User.get(user_id)
    if not bcrypt.check_password_hash(user.password, pw_old):
        raise NotFoundException(message='Invalid password. Please try again.')

    if not User.first(User.username == username):
        with session_scope(db.session):
            user.username = username
            user.password = bcrypt.generate_password_hash(
                pw_new, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode()
        return {
            'status': 'success',
            'message': 'Successfully changed password.',
        }
    else:
        raise BusinessException(
            message=
            'Sorry. That username already exists, choose another username')
Ejemplo n.º 2
0
def add_user(_):
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    username = post_data.get('username')
    email = post_data.get('email')
    password = post_data.get('password')

    try:
        user = User.first(or_(User.username == username, User.email == email))
        if not user:
            userModel = User(username=username, email=email, password=password)
            db.session.add(userModel)
            db.session.commit()
            response_object = {
                'status': 'success',
                'message': f'{email} was added!'
            }
            return response_object, 201
        else:
            raise BusinessException(
                message='Sorry. That email or username already exists.')
    except (exc.IntegrityError, ValueError):
        db.session.rollback()
        raise InvalidPayload()
Ejemplo n.º 3
0
def password_reset():
    ''' reset user password (assumes login=email)'''
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    token = post_data.get('token')
    pw_new = post_data.get('password')
    if not token or not pw_new:
        raise InvalidPayload()

    # fetch the user data

    user_id = User.decode_password_token(token)
    user = User.get(user_id)
    if not user or not user.token_hash or not bcrypt.check_password_hash(
            user.token_hash, token):
        raise NotFoundException(message='Invalid reset. Please try again.')

    with session_scope(db.session):
        user.password = bcrypt.generate_password_hash(
            pw_new, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode()
        user.token_hash = None
    return {
        'status': 'success',
        'message': 'Successfully reset password.',
    }
Ejemplo n.º 4
0
def password_recovery():
    ''' creates a password_recovery_hash and sends email to user (assumes login=email)'''
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    email = post_data.get('email')
    if not email:
        raise InvalidPayload()

    # fetch the user data
    user = User.first_by(email=email)
    if user:
        token = user.encode_password_token()
        with session_scope(db.session):
            user.token_hash = bcrypt.generate_password_hash(
                token, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode()
        if not current_app.testing:
            from project.api.common.utils.mails import send_password_recovery_email
            send_password_recovery_email(user,
                                         token.decode())  # send recovery email
        return {
            'status': 'success',
            'message': 'Successfully sent email with password recovery.',
        }
    else:
        raise NotFoundException(
            message=
            'Login/email does not exist, please write a valid login/email')
Ejemplo n.º 5
0
def register_user_cellphone(user_id: int):
    ''' generates cellphone_validation_code, idempotent (could be used for resend cellphone_validation_code)
        allows just 1 user per cellphone validation!
    '''
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    cellphone_number = post_data.get('cellphone_number')
    cellphone_cc = post_data.get('cellphone_cc')
    if not cellphone_number or not cellphone_cc:
        raise InvalidPayload()
    user = User.get(user_id)
    if user.cellphone_validation_date and user.cellphone_number == cellphone_number and user.cellphone_cc == cellphone_cc:
        raise BusinessException(
            message=
            'Registered. You have already registered this cellphone number.')

    cellphone_validation_code, cellphone_validation_code_expiration = User.generate_cellphone_validation_code(
    )
    with session_scope(db.session) as session:
        user.cellphone_number = cellphone_number
        user.cellphone_cc = cellphone_cc
        user.cellphone_validation_code = cellphone_validation_code
        user.cellphone_validation_code_expiration = cellphone_validation_code_expiration
        user.cellphone_validation_date = None

    if not current_app.testing:
        from project.api.common.utils.twilio import send_cellphone_verification_code
        send_cellphone_verification_code(user, cellphone_validation_code)

    return {
        'status': 'success',
        'message': 'Successfully sent validation code.'
    }
Ejemplo n.º 6
0
def register_user():
    # get post data
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    username = post_data.get('username')
    email = post_data.get('email')
    password = post_data.get('password')
    if not password or not username or not email:
        raise InvalidPayload()
    # check for existing user
    user = User.first(or_(User.username == username, User.email == email))
    if not user:
        # add new user to db
        new_user = User(username=username, email=email, password=password)
        with session_scope(db.session) as session:
            session.add(new_user)

        # need another scope if not new_user does not exists yet
        with session_scope(db.session) as session:
            token = new_user.encode_email_token()
            new_user.email_token_hash = bcrypt.generate_password_hash(
                token, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode()

        if not current_app.testing:
            from project.api.common.utils.mails import send_registration_email
            send_registration_email(new_user, token.decode())

        # save the device
        if all(x in request.headers for x in [
                Constants.HttpHeaders.DEVICE_ID,
                Constants.HttpHeaders.DEVICE_TYPE
        ]):
            device_id = request.headers.get(Constants.HttpHeaders.DEVICE_ID)
            device_type = request.headers.get(
                Constants.HttpHeaders.DEVICE_TYPE)
            with session_scope(db.session):
                Device.create_or_update(device_id=device_id,
                                        device_type=device_type,
                                        user=user)
        # generate auth token
        auth_token = new_user.encode_auth_token()
        return {
            'status': 'success',
            'message': 'Successfully registered.',
            'auth_token': auth_token.decode()
        }, 201
    else:
        # user already registered, set False to device.active
        if Constants.HttpHeaders.DEVICE_ID in request.headers:
            device_id = request.headers.get(Constants.HttpHeaders.DEVICE_ID)
            device = Device.first_by(device_id=device_id)
            if device:
                with session_scope(db.session):
                    device.active = False
        raise BusinessException(message='Sorry. That user already exists.')
Ejemplo n.º 7
0
def register_device():
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    device_id = post_data.get('device_id')
    device_type = post_data.get('device_type')
    if not device_id or not device_type:
        raise InvalidPayload()
    pn_token = post_data.get('pn_token')
    with session_scope(db.session):
        Device.create_or_update(device_id=device_id,
                                device_type=device_type,
                                pn_token=pn_token)
    return {'status': 'success', 'message': 'Device successfully registered.'}
Ejemplo n.º 8
0
def connect_device_with_logged_in_user(user_id: int, device_id: str):
    user = User.get(user_id)
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    device_type = post_data.get('device_type')
    if not device_type:
        raise InvalidPayload()
    pn_token = post_data.get('pn_token')
    with session_scope(db.session):
        Device.create_or_update(device_id=device_id,
                                device_type=device_type,
                                user=user,
                                pn_token=pn_token)
    return {'status': 'success', 'message': 'Device successfully registered.'}
Ejemplo n.º 9
0
def facebook_login():
    ''' logs in user using fb_access_token returning the corresponding JWT
        if user does not exist registers/creates a new one'''

    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    fb_access_token = post_data.get('fb_access_token')
    if not fb_access_token:
        raise InvalidPayload()
    try:
        graph = GraphAPI(fb_access_token)
        profile = graph.get("me?fields=id,name,email,link")
    except Exception:
        raise UnauthorizedException()

    fb_user = User.first(User.fb_id == profile['id'])
    if not fb_user:
        # Not an existing user so get info, register and login
        user = User.first(User.email == profile['email'])
        code = 200
        with session_scope(db.session) as session:
            if user:
                user.fb_access_token = fb_access_token
                user.fb_id = profile['id']
            else:
                # Create the user and insert it into the database
                user = User(email=profile['email'],
                            fb_id=profile['id'],
                            fb_access_token=fb_access_token)
                session.add(user)
                code = 201
        # generate auth token
        auth_token = user.encode_auth_token()
        return {
            'status': 'success',
            'message': 'Successfully facebook registered.',
            'auth_token': auth_token.decode()
        }, code
    else:
        auth_token = fb_user.encode_auth_token()
        with session_scope(db.session):
            fb_user.fb_access_token = fb_access_token
        return {
            'status': 'success',
            'message': 'Successfully facebook login.',
            'auth_token': auth_token.decode()
        }
Ejemplo n.º 10
0
def login_user():
    # get post data
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    email = post_data.get('email')
    password = post_data.get('password')
    if not password:
        raise InvalidPayload()

    user = User.first_by(email=email)
    if user and bcrypt.check_password_hash(user.password, password):
        # register device if needed
        if all(x in request.headers for x in [
                Constants.HttpHeaders.DEVICE_ID,
                Constants.HttpHeaders.DEVICE_TYPE
        ]):
            device_id = request.headers.get(Constants.HttpHeaders.DEVICE_ID)
            device_type = request.headers.get(
                Constants.HttpHeaders.DEVICE_TYPE)
            with session_scope(db.session):
                Device.create_or_update(device_id=device_id,
                                        device_type=device_type,
                                        user=user)
        auth_token = user.encode_auth_token()
        return {
            'status': 'success',
            'message': 'Successfully logged in.',
            'auth_token': auth_token.decode()
        }
    else:
        # user is not logged in, set False to device.active
        if Constants.HttpHeaders.DEVICE_ID in request.headers:
            device_id = request.headers.get(Constants.HttpHeaders.DEVICE_ID)
            device = Device.first_by(device_id=device_id)
            if device:
                with session_scope(db.session):
                    device.active = False
        raise NotFoundException(message='User does not exist.')
Ejemplo n.º 11
0
def password_change(user_id: int):
    ''' changes user password when logged in'''
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    pw_old = post_data.get('old_password')
    pw_new = post_data.get('new_password')
    if not pw_old or not pw_new:
        raise InvalidPayload()

    # fetch the user data
    user = User.get(user_id)
    if not bcrypt.check_password_hash(user.password, pw_old):
        raise BusinessException(message='Invalid password. Please try again.')

    with session_scope(db.session):
        user.password = bcrypt.generate_password_hash(
            pw_new, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode()
    return {
        'status': 'success',
        'message': 'Successfully changed password.',
    }
Ejemplo n.º 12
0
def add_vehicle(_):
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    plate = post_data.get('plate')

    try:
        vehicle = Vehicle.first(Vehicle.plate == plate)
        if not vehicle:
            vehicleModel = Vehicle(plate=plate)
            db.session.add(vehicleModel)
            db.session.commit()
            response_object = {
                'status': 'success',
                'message': f'Vehicle with plate: {plate} was added!'
            }
            return response_object, 201
        else:
            raise BusinessException(
                message='Sorry. That plate already exists.')
    except (exc.IntegrityError, ValueError):
        db.session.rollback()
        raise InvalidPayload()
Ejemplo n.º 13
0
def verify_user_cellphone(user_id: int):
    ''' verifies cellphone_validation_code, idempotent (could be used many times) '''
    post_data = request.get_json()
    if not post_data:
        raise InvalidPayload()
    validation_code = post_data.get('validation_code')
    user = User.get(user_id)

    valid_code, message = user.verify_cellphone_validation_code(
        validation_code)
    if not valid_code:
        raise BusinessException(message=message)

    with session_scope(db.session) as session:
        user.cellphone_validation_code = None
        user.cellphone_validation_code_expiration = None
        user.cellphone_validation_date = datetime.utcnow()

    return {'status': 'success', 'message': 'Successful cellphone validation.'}