def process_request(self, request_object): """Process update Account Request""" identifier = request_object.identifier data = request_object.data account = Account.get(identifier) if pbkdf2_sha256.verify(data['current_password'], account.password): password_check = validate_new_password(data['new_password'], account.password_history) if password_check['is_valid']: password = pbkdf2_sha256.hash(data['new_password']) password_history = modify_password_history( account.password, account.password_history) account.update({ 'password': password, 'password_history': password_history }) return ResponseSuccess(Status.SUCCESS, {"message": "Success"}) else: return ResponseFailure.build_unprocessable_error( {'new_password': password_check['error']}) else: return ResponseFailure.build_unprocessable_error( {'current_password': '******'})
def process_request(self, request_object): token = request_object.token account = get_account_entity().query.filter( verification_token=token).first if account: token_time = account.token_timestamp if datetime.datetime.utcnow() > token_time: return ResponseFailure.build_unprocessable_error( "Token expired") else: account.update({"is_verified": True}) return ResponseSuccess(Status.SUCCESS, account) else: return ResponseFailure.build_unprocessable_error("Invalid Token")
def process_request(self, request_object): token = request_object.token data = request_object.data verify_token_use_case = VerifyTokenUseCase() verify_token_req_obj = VerifyTokenRequestObject.from_dict( request_object.entity_cls, {'token': token}) response_object = verify_token_use_case.execute(verify_token_req_obj) if response_object.success: account = response_object.value password_check = validate_new_password(data['new_password'], account.password_history) if password_check['is_valid']: password = pbkdf2_sha256.hash(data['new_password']) password_history = modify_password_history( account.password, account.password_history) account.update({ 'password': password, 'is_locked': False, 'login_attempts': 0, 'password_history': password_history }) return ResponseSuccess(Status.SUCCESS, {"message": "Success"}) else: return ResponseFailure.build_unprocessable_error( {'new_password': password_check['error']}) else: return response_object
def process_request(self, request_object): email = request_object.email account = Account.query.filter(email=email).first if account: token = str(uuid.uuid4()) token_ts = datetime.datetime.utcnow() + datetime.timedelta( hours=24) account.update({ "verification_token": token, "token_timestamp": token_ts }) # Send the password request email email_builder = perform_import(active_config.RESET_EMAIL_CALLBACK) if not email_builder: raise ConfigurationError( '`RESET_EMAIL_CALLBACK` config must be set to a ' 'valid function.') email_msg = email_builder(account.email, token) email_msg.send() return ResponseSuccess(Status.SUCCESS, {"message": "Success"}) else: return ResponseFailure.build_unprocessable_error( {'email': 'Account does not exist.'})
def process_request(self, request_object): """Process Login Request""" # FIXME Use `OR` condition for `username` or `email` query account = Account.query.filter( username=request_object.username_or_email).first if not account: account = Account.query.filter( email=request_object.username_or_email).first if not account: return ResponseFailure.build_unprocessable_error( {'username_or_email': 'Account does not exist'}) if not account.is_locked and account.is_active: if pbkdf2_sha256.verify(request_object.password, account.password): if active_config.ENABLE_ACCOUNT_VERIFICATION and \ not account.is_verified: # Todo: Handle sending account verification mail return ResponseFailure.build_unprocessable_error( {'username_or_email': 'Account is not verified'}) else: # Run the login callback usecase and return its response auth_backend = get_auth_backend() cb_usecase = auth_backend.LoginCallbackUseCase() cb_request_obj = LoginCallbackRequestObject.from_dict( request_object.entity_cls, {'account': account}) return cb_usecase.execute(cb_request_obj) else: allowed_login_attempts = \ active_config.PASSWORD_RULES['max_invalid_attempts'] if account.login_attempts and \ account.login_attempts >= allowed_login_attempts: account.update(account.id, {'is_locked': True}) return ResponseFailure.build_unprocessable_error({ 'password': '******' 'Account has been locked.' }) else: account.login_attempts += 1 account.update({'login_attempts': account.login_attempts}) return ResponseFailure.build_unprocessable_error( {'password': '******'}) else: return ResponseFailure.build_unprocessable_error( {'username_or_email': 'Account has been locked/deactivated.'})
def process_request(self, request_object): """Process Create Account Request""" data = request_object.data is_idp_login = request_object.data.get('is_idp', False) if Account.query.filter(email=data['email']): return ResponseFailure.build_unprocessable_error( {'email': 'Email already exists'}) if not is_idp_login: if Account.query.filter(username=data['username']): return ResponseFailure.build_unprocessable_error( {'username': '******'}) password_check = validate_new_password(data['password'], []) if not password_check['is_valid']: return ResponseFailure.build_unprocessable_error( {'password': password_check['error']}) data['password'] = pbkdf2_sha256.hash(data['password']) account = Account.create(data) return ResponseSuccessCreated(account)
def process_request(self, request_object): """Process update Account Request""" account_obj = Account.get(request_object.identifier) if request_object.data.get('email') and \ account_obj.email != request_object.data.get('email') and \ Account.query.filter(email=request_object.data['email']): return ResponseFailure.build_unprocessable_error( {'email': 'Email already exists'}) # Remove fields that cannot be updated for field in ['password', 'username']: request_object.data.pop(field, None) return super().process_request(request_object)
def process_request(self, request_object): """Process Authentication Request""" # Get the decode key for the alg decode_key = active_config.SECRET_KEY if active_config.JWT_ALGORITHM in requires_cryptography: with open(active_config.JWT_PUBLIC_KEY) as fp: decode_key = fp.read() # Decode and validate the jwt try: jwt_data = decode_jwt( encoded_token=request_object.credentials, secret=decode_key, algorithm=active_config.JWT_ALGORITHM, identity_claim_key=active_config.JWT_IDENTITY_CLAIM) except (JWTDecodeError, DecodeError, ExpiredSignatureError) as e: return ResponseFailure(Status.UNAUTHORIZED, {'credentials': f'Invalid JWT Token. {e}'}) # Find the identity in the decoded jwt identity = jwt_data.get(active_config.JWT_IDENTITY_CLAIM, None) try: account = Account.get(identity.get('account_id')) except ObjectNotFoundError: return ResponseFailure( Status.UNAUTHORIZED, {'username_or_email': 'Account does not exist'}) # Make sure that the session exits session = Session.query.filter( session_key=f'token-{account.id}-{jwt_data["jti"]}', ) if not session or session.first.expire_date < datetime.utcnow(): return ResponseFailure(Status.UNAUTHORIZED, {'token': 'Invalid Token'}) context.set_context({'jwt_data': jwt_data}) return ResponseSuccess(Status.SUCCESS, account)
def process_request(self, request_object): identifier = request_object.identifier mfa_otp = request_object.mfa_otp account = Account.get(identifier) # FIXME MFA throws invalid key with the following approach # secret = base64.b64encode(bytes(account.mfa_key + CONFIG.MFA_SECRET_KEY, # encoding='utf-8')).decode('utf-8')[:16] totp = pyotp.TOTP(account.mfa_key) if not totp.verify(mfa_otp): return ResponseFailure.build_unprocessable_error( "Invalid OTP") if not account.mfa_enabled: account.update({"mfa_enabled": True}) return ResponseSuccess({"message": "Valid OTP"})
def process_request(self, request_object): """Process Authentication Request""" try: auth_parts = base64.b64decode( request_object.credentials).decode('iso-8859-1').partition(':') except (TypeError, UnicodeDecodeError, binascii.Error): return ResponseFailure.build_unprocessable_error({ 'credentials': 'Invalid basic header. Credentials not ' 'correctly base64 encoded.' }) payload = { 'username_or_email': auth_parts[0], 'password': auth_parts[2], } request_object = LoginRequestObject.from_dict( request_object.entity_cls, payload) use_case = LoginUseCase() return use_case.execute(request_object)