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')
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()
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.', }
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')
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.' }
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.')
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.'}
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.'}
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() }
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.')
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.', }
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()
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.'}