def post(self): """ Post Request to verify the OTP code using the non-root device and non-authorized devices :params: :auth_token: authorized token when logged in :mac_address: unique MAC address of the device :code: OTP code for verification :key_mod: modulus of a public key :key_exp: exponent of a public key :returns: :error response: or :encrypted_key: """ try: post_data = request.get_json() #Get data from post request body auth_token = RequestUtils.get_access_token(request) #Return authentication token mac_address = post_data.get('mac_address') #Get mac address from the body code = post_data.get('code') #Get authorized code key_mod = post_data.get('modulus') #Get public key from the body key_ex = post_data.get('exponent') #Check the provided params, return user_id if qualified user, key= self.__check_for_require_params(auth_token,mac_address,key_mod,key_ex) #If returned result is not an integer if not isinstance(user,User): return user #Return the exception message if it fail if OTP.verify(code)!=True: return CommonResponseObject.fail_response('Invalid code.', status.HTTP_401_UNAUTHORIZED) return self.__process_new_key(user.id, key, key_mod, key_ex) except Exception as e: print(e) return CommonResponseObject.fail_response( 'Missing important fields or values')
def post(self): # get the post data post_data = request.get_json() if post_data is None: return CommonResponseObject.fail_response( 'Please provide required data', status.HTTP_403_FORBIDDEN) user = User.get_user_by_email(post_data.get('email')) if user: # return response to inform that user already existed return CommonResponseObject.register_user_exist() # if user does not exist, try to create new user and store to the database # initialize new user object with information from the request try: user = self.__check_register_json_data(post_data) if not isinstance(user, User): return user # insert the user db.session.add(user) db.session.commit() token = ConfirmationToken.generate_confirmation_token(user.email) confirm_url = url_for('auth.confirm_api', token=token, _external=True) html = "<p>Welcome! Thanks for signing up. Please follow this link to activate your account:</p><p><a href=" + confirm_url + ">{{ Activate}}</a></p><br><p>Cheers!</p>" subject = "Scloud Service Email Confirmation" Mail.send(user.email, subject, html) # generate the auth token # return response with auth token return CommonResponseObject.success_resp_with_mess( 'Register succesfully, please confirm your email which is sent to your email address' ) except Exception as e: # database exception, cannot store user information print(e) return CommonResponseObject.register_exception()
def post(self): post_data = request.get_json() if not post_data or not post_data.get('mac_address'): return CommonResponseObject.fail_response( 'Please provide your mac_address for deauthorization', status.HTTP_412_PRECONDITION_FAILED) auth_token = RequestUtils.get_access_token(request) user_id = User.decode_auth_token(auth_token) mac_address = post_data.get('mac_address') device = DeviceList.get_device_by_user_id_and_mac(user_id, mac_address) if not device: return CommonResponseObject.fail_response( 'Invalid authentication token',status.HTTP_401_UNAUTHORIZED) if device.root: return CommonResponseObject.fail_response( 'You are not able to deauthorize without decoding your files to raw', status.HTTP_403_FORBIDDEN) try: db.session.delete(device) db.session.commit() return CommonResponseObject.success_resp_with_mess( 'Your device is no longer authorized') except Exception: return CommonResponseObject.fail_response( 'Some errors occured, please try again')
def __generate_encrypted_OTP(self, user_id, mac_address,encrypted_key): """ Store the received key in the database associate with the root device for later re-encryption with support authorization other devices by encrypt the key with other identifier :params: :user_id: the id of the user :mac_address: MAC address of the device :encrypted_key: temporarily encrypted key :returns: :Error Response: or :JSON object contains encrypted_code: """ device = DeviceList.get_root_device(user_id) print(user_id) if not device: #Check if root device is stored return CommonResponseObject.fail_response( 'Please register for the root device to process further encryption', status.HTTP_401_UNAUTHORIZED) if device.mac_address != mac_address: #check if the access mac_address is the root device return CommonResponseObject.fail_response( 'Please request for authorization with your root device', status.HTTP_403_FORBIDDEN) device.encrypted_key = encrypted_key db.session.commit() encrypted_code= KeyOperation.encrypt_OTP(device) #generate encrypted code return json.dumps(dict(code=encrypted_code)) #jsonize and return
def __check_for_require_params(self,auth_token,mac_address,encrypted_key): """ Check if the params is qualified, return error json response if any requisite does not meet, else check and return user entity for the corresponding user id :params: :auth_token: :mac_address: :public_key: :return: :user_id: or :responseObject: """ if not auth_token: # Check if the auth_token is valid return CommonResponseObject.unauthorized_token_response() user_id = User.decode_auth_token(auth_token) if isinstance(user_id,str): # Check if user_id is provided return CommonResponseObject.unauthorized_token_response() if not isinstance(mac_address,str): # Check if mac address is provided return CommonResponseObject.fail_response( 'Please provide your Mac address', status.HTTP_412_PRECONDITION_FAILED) if not encrypted_key:#check if encrypted_key is provided return CommonResponseObject.fail_response( 'Please provide your encrypted key for authorization', status.HTTP_412_PRECONDITION_FAILED) user = User.get_user_by_id(user_id) #get user from the database if not user:#if user is not available return CommonResponseObject.unauthorized_token_response() return user
def post(self): auth_token = RequestUtils.get_access_token(request) if auth_token: resp = User.decode_auth_token(auth_token) if not isinstance(resp, str): return CommonResponseObject.success_resp_with_mess( 'Token is still available') return CommonResponseObject.fail_response( message=resp, error_code=status.HTTP_401_UNAUTHORIZED)
def get(self): # Get the access token from the header auth_token = RequestUtils.get_access_token(request) if auth_token: response = User.decode_auth_token(auth_token) if not isinstance(response,str): device_list = DeviceList.get_device_by_user_id(response) data = [device.serialize() for device in device_list] return CommonResponseObject.success_response(data) return CommonResponseObject.fail_response(response,status.HTTP_401_UNAUTHORIZED) else: return CommonResponseObject.unauthorized_token_response()
def get(self): auth_header = request.headers.get('Authorization') if auth_header: auth_token = auth_header.split(" ")[1] else: auth_token = '' if auth_token: response = User.decode_auth_token(auth_token) if not isinstance(response, str): user = User.get_user_by_id(response) data = json.dumps(dict(encrypted_key=user.encrypted_key)) return CommonResponseObject.success_response(data) return CommonResponseObject.token_response(response) else: return CommonResponseObject.unauthorized_token_response()
def get(self, token): try: email = ConfirmationToken.confirm_token(token) except: return CommonResponseObject.fail_response( 'The token is invalid or expired', status.HTTP_404_NOT_FOUND) user = User.query.filter_by(email=email).first_or_404() if user.is_confirmed: return CommonResponseObject.fail_response( 'The user is confirmed, please login', status.HTTP_202_ACCEPTED) user.is_confirmed = True db.session.add(user) db.session.commit() return CommonResponseObject.success_resp_with_mess( 'The user is successfully confirmed')
def __process_new_key(self,user_id, key, key_mod, key_exp): """ Process key passing down to the new authorized device with provided key from the root device and encrypt the key with provided public key from the device """ device = DeviceList.get_root_device(user_id) #get root device by user_id if not device: #if root device does not exist return CommonResponseObject.fail_response( 'Some errors occured, please try again') encrypted_key = KeyOperation.re_encryption(key, [key_mod,key_exp], device.encrypted_key) if not encrypted_key: return CommonResponseObject.fail_response( 'Some errors occured, please try again') data = json.dumps(dict(key=encrypted_key)) return CommonResponseObject.success_response(data)
def __check_for_require_params(self,auth_token,mac_address,key_mod,key_ex): """ Check if the params is qualified :params auth_token mac_address public_key: :return user_id or responseObject: """ if not auth_token:#check if auth_token is available return CommonResponseObject.unauthorized_token_response() #get user_id and key from the auth_token user_id= User.decode_auth_token(auth_token) if isinstance(user_id,str):#check if user_id is valid return CommonResponseObject.unauthorized_token_response() if not mac_address: #check if mac_address is valid return CommonResponseObject.fail_response( 'Please provide your MAC address', status.HTTP_412_PRECONDITION_FAILED) #check if key is valid modulus, exponent = User.decode_public_key(auth_token) key = RSAPair.get_RSA_by_public(modulus) if not key:#check if key is existed return CommonResponseObject.response( 'Some errors occured, provided key does not exists') user = User.get_user_by_id(user_id) #retrieve the user entity if not user: #check if the user is existed return CommonResponseObject.unauthorized_token_response() #check if the mac_address is stored if DatabaseCheck.is_mac_address_existed(mac_address): if DatabaseCheck.is_root_by_mac(mac_address): return CommonResponseObject.fail_response( 'Your device is the root device', status.HTTP_202_ACCEPTED) return CommonResponseObject.fail_response( 'Your device is already authorized', status.HTTP_202_ACCEPTED) return user,key
def post(self): """ Add root device """ #Get authentication token auth_token = RequestUtils.get_access_token(request) #Get post data post_data = request.get_json() mac_address = post_data.get('mac_address') os = post_data.get('os') or "Unknown" backup_key = post_data.get('backup_key') otp_modulus = post_data.get('otp_modulus') otp_exponent = post_data.get('otp_exponent') main_key = post_data.get('main_key') root = post_data.get('is_root') user = self.__check_for_require_params(auth_token, mac_address, otp_modulus, otp_exponent, main_key, backup_key) if not isinstance(user, User): return user root_device = DeviceList.get_root_device(user.id) if root_device and root: return CommonResponseObject.fail_response( 'The account already register a root device', status.HTTP_202_ACCEPTED) device = DeviceList(user, mac_address=mac_address, main_key=main_key, backup_key=backup_key, otp_modulus=otp_modulus, otp_exponent=otp_exponent, os=os, is_root=root) try: db.session.add(device) db.session.commit() modulus, exponent = User.decode_public_key(auth_token) auth_token = User.encode_auth_token(user.id, str(modulus), str(exponent), main_key) return CommonResponseObject.login_success( auth_token, 'You are able to encrypt your file now') except Exception as e: print(e) return CommonResponseObject.fail_response( 'Some error occured, please try again.')
def __check_for_require_params(self, auth_token, mac_address, otp_modulus, otp_exponent, main_key, backup_key): """ Check if the params is qualified :params auth_token mac_address public_key: :return user_id or responseObject: """ if not auth_token: return CommonResponseObject.unauthorized_token_response() user_id = User.decode_auth_token(auth_token) if not main_key: return CommonResponseObject.fail_response( 'Please provide the main key', status.HTTP_412_PRECONDITION_FAILED) if not backup_key: return CommonResponseObject.fail_response( 'Please provide the backup_key', status.HTTP_412_PRECONDITION_FAILED) if isinstance(user_id, str): return CommonResponseObject.unauthorized_token_response() if not isinstance(mac_address, str): return CommonResponseObject.fail_response( 'Please provide your Mac address', status.HTTP_412_PRECONDITION_FAILED) user = User.get_user_by_id(user_id) if not user: return CommonResponseObject.unauthorized_token_response() if DatabaseCheck.is_mac_address_existed(mac_address): return CommonResponseObject.fail_response( 'Your device is the root device or already requested for authorization', status.HTTP_202_ACCEPTED) return user
def get(self): """ User Information retrieval API """ auth_token = RequestUtils.get_access_token(request) user_id = User.decode_auth_token(auth_token) user = User.query.filter_by(id=user_id).first() if not user: return CommonResponseObject.fail_response( 'User does not exist, please try again', status.HTTP_404_NOT_FOUND) responseObject = { 'status': 'success', 'birthday': user.birthday, 'fullname': user.fullname, 'job': user.job, 'country': user.country } return CommonResponseObject.response(responseObject, status.HTTP_200_OK)
def post(self): # get auth token auth_token = RequestUtils.get_access_token(request) if auth_token: resp = User.decode_auth_token(auth_token) if not isinstance(resp, str): # mark the token as blacklisted blacklist_token = BlacklistToken(token=auth_token) try: # insert the token db.session.add(blacklist_token) db.session.commit() DatabaseCheck.remove_key_pair(auth_token) return CommonResponseObject.logout_success() except Exception as e: return CommonResponseObject.logout_exception(e) else: return CommonResponseObject.token_response(resp) else: return CommonResponseObject.forbiden_token_response()
def post(self): # get the post data post_data = request.get_json() if post_data is None: return CommonResponseObject.fail_response( 'Please provide required data', status.HTTP_404_NOT_FOUND) try: # fetch the user data user = User.get_user_by_email(post_data.get('email')) if user and not user.is_confirmed: return CommonResponseObject.fail_response( 'Please confirm your email address which is sent to your email', status.HTTP_403_FORBIDDEN) mac_address = post_data.get('mac_address') if not mac_address: return CommonResponseObject.fail_response( 'Please provide your MAC address', status.HTTP_412_PRECONDITION_FAILED) if user and bcrypt.check_password_hash(user.password, post_data.get('password')): device = DeviceList.get_device_by_user_id_and_mac( user.id, mac_address) root = DeviceList.get_root_device(user.id) auth_token = DatabaseCheck.prepare_auth_token( user.id, mac_address, None if not device else device.main_key, True if root else False) if auth_token: return CommonResponseObject.login_success(auth_token) else: return CommonResponseObject.login_user_not_exist() except Exception as e: print(e) return CommonResponseObject.login_exception()
def post(self): post_data = request.get_json() root_mac_address = post_data.get('root_mac_address') mac_address = post_data.get('mac_address') if not post_data or not mac_address or not root_mac_address: return CommonResponseObject.fail_response( 'Please provide your mac_address and the mac_address of device for root changing', status.HTTP_412_PRECONDITION_FAILED) auth_token = RequestUtils.get_access_token(request) user_id = User.decode_auth_token(auth_token) device = DeviceList.get_device_by_user_id_and_mac(user_id,mac_address) if not device: return CommonResponseObject.fail_response( 'Your provided mac_address is unathorized', status.HTTP_401_UNAUTHORIZED) root_device = DeviceList.get_device_by_user_id_and_mac(user_id,root_mac_address) if not root_device: return CommonResponseObject.fail_response( 'Your provided mac address of root device is invalid', status.HTTP_404_NOT_FOUND) if not root_device.root: return CommonResponseObject.fail_response( 'Your provided mac address of root device is unauthorized', status.HTTP_401_UNAUTHORIZED) try: device.root = True root_device.root = False db.session.save() db.session.commit() return CommonResponseObject.success_resp_with_mess( 'Your root device is changed successfully') except Exception: return CommonResponseObject.fail_response( 'Some errors occurred')
def post(self): post_data = request.get_json() if post_data is None: return CommonResponseObject.fail_response( 'Please provde required data', status.HTTP_403_FORBIDDEN) auth_token = RequestUtils.get_access_token( request) #Return authentication token user_id = User.decode_auth_token(auth_token) user = User.query.filter_by(id=user_id).first() if not user: return CommonResponseObject.fail_response( 'User does not exist, please try again', status.HTTP_404_NOT_FOUND) isChanged = False password = post_data.get('password') if password: user.password = password isChanged = True bday = post_data.get('birthday') if bday: isChanged = True user.birthday = datetime.datetime.strptime(bday, "%d/%m/%Y") job = post_data.get('job') if job: user.job = job isChanged = True fullname = post_data.get('fullname') if fullname: user.fullname = fullname isChanged = True country = post_data.get('country') if country: user.country = country isChanged = True if isChanged: db.session.save() db.session.commit() return CommonResponseObject.success_resp_with_mess( 'Your information is updated successfully')
def __check_register_json_data(self, post_data): #Check for json data email = post_data.get('email') password = post_data.get('password') bday = post_data.get('birthday') job = post_data.get('job') fullname = post_data.get('fullname') country = post_data.get('country') if not email or not password or not fullname: return CommonResponseObject.fail_response( 'Missing email, password, birthday or fullname') user = User(email=email, password=password, bday=datetime.datetime.strptime(bday, "%d/%m/%Y"), job=job, fullname=fullname, country=country) return user