def mutate(self, info, stage_id, payload, preview, name=None): current_user_id = get_jwt_identity() with ScopedSession() as local_db_session: scene = SceneModel(owner_id=current_user_id, stage_id=stage_id, payload=payload, scene_preview=preview) scene_order = local_db_session.query(SceneModel).filter( SceneModel.stage_id == stage_id).count() + 1 scene.scene_order = scene_order if name: existedScene = local_db_session.query(SceneModel)\ .filter(SceneModel.stage_id == stage_id)\ .filter(SceneModel.active == True)\ .filter(SceneModel.name == name)\ .first() if existedScene: raise Exception( 'Scene "{}" already existed. Please choose another name!' .format(name)) scene.name = name else: scene.name = f"Scene {scene_order}" local_db_session.add(scene) local_db_session.flush() local_db_session.commit() scene_id = scene.id return SaveScene(id=scene_id)
def mutate(self, info, id): with ScopedSession() as local_db_session: id = from_global_id(id)[1] stage = local_db_session.query(StageModel).filter( StageModel.id == id).first() if stage: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == stage.owner_id: raise Exception( "Only stage owner or admin can delete this stage!") local_db_session.query(ParentStage).filter( ParentStage.stage_id == id).delete( synchronize_session=False) local_db_session.query(StageAttributeModel).filter( StageAttributeModel.stage_id == id).delete( synchronize_session=False) for performance in local_db_session.query( PerformanceModel).filter( PerformanceModel.stage_id == id).all(): local_db_session.query(EventModel).filter( EventModel.performance_id == performance.id).delete( synchronize_session=False) local_db_session.delete(performance) local_db_session.delete(stage) local_db_session.flush() local_db_session.commit() else: raise Exception("Stage not found!") return DeleteStage(success=True)
def refresh(): current_user_id = get_jwt_identity() refresh_token = request.headers[app.config['JWT_HEADER_NAME']] user = DBSession.query(User).filter(User.id == current_user_id).filter( User.active == True).first() if not user: TNL.add(refresh_token) return make_response( jsonify({'error': "Your session expired. Please log in again."}), 401) access_token = create_access_token(identity=current_user_id) user_session = UserSession( user_id=current_user_id, access_token=access_token, refresh_token=refresh_token, app_version=request.headers.get('X-Upstage-App-Version'), app_os_type=request.headers.get("X-Upstage-Os-Type"), app_os_version=request.headers.get("X-Upstage-Os-Version"), app_device=request.headers.get("X-Upstage-Device-Model")) with ScopedSession() as local_db_session: local_db_session.add(user_session) local_db_session.flush() user_session_id = user_session.id return make_response(jsonify({'access_token': access_token}), 200)
def mutate(self, info, inbound): data = graphql_utils.input_to_dictionary(inbound) code,error,user,timezone = current_user() if not user.role in (ADMIN,SUPER_ADMIN) : if not user.id == int(data['id']): raise Exception("Permission denied!") if not data['email'] and data['role'] != GUEST: raise Exception("Email is required!") with ScopedSession() as local_db_session: user = local_db_session.query(UserModel)\ .filter(UserModel.id==data['id']).first() if (data['password']): data['password'] = encrypt(data['password']) else: del data['password'] for key, value in data.items(): if key == 'active': if value and not user.active and not user.deactivated_on: send(user.email, f"Registration approved for user {user.username}", user_approved(user)) if not value and user.active: user.deactivated_on = datetime.now() if hasattr(user, key): setattr(user, key, value) user = DBSession.query(UserModel).filter(UserModel.id==data['id']).first() return UpdateUser(user=user)
def mutate(self, info, refresh_token): current_user_id = get_jwt_identity() refresh_token = request.headers[app.config['JWT_HEADER_NAME']] user = DBSession.query(User).filter(User.id == current_user_id).filter( User.active == True).first() if not user: TNL.add(refresh_token) raise Exception("Your session expired. Please log in again.") access_token = create_access_token(identity=current_user_id) user_session = UserSession( user_id=current_user_id, access_token=access_token, refresh_token=refresh_token, app_version=request.headers.get('X-Upstage-App-Version'), app_os_type=request.headers.get("X-Upstage-Os-Type"), app_os_version=request.headers.get("X-Upstage-Os-Version"), app_device=request.headers.get("X-Upstage-Device-Model")) with ScopedSession() as local_db_session: local_db_session.add(user_session) local_db_session.flush() user_session_id = user_session.id return RefreshMutation(new_token=access_token)
def mutate(self, info, input): data = graphql_utils.input_to_dictionary(input) with ScopedSession() as local_db_session: stage = local_db_session.query(StageModel).filter( StageModel.id == data['id']).first() for key, value in data.items(): if hasattr(stage, key): setattr(stage, key, value) elif value: attribute = stage.attributes.filter( StageAttributeModel.name == key).first() if attribute: attribute.description = value else: attribute = StageAttributeModel(stage_id=data['id'], name=key, description=value) local_db_session.add(attribute) local_db_session.commit() stage = DBSession.query(StageModel).filter( StageModel.id == data['id']).first() return UpdateStage(stage=stage)
def mutate(self, info, username_or_email): with ScopedSession() as local_db_session: if '@' in username_or_email: user = local_db_session.query(User).filter( User.email == username_or_email).first() else: user = local_db_session.query(User).filter( User.username == username_or_email).first() if user: email = user.email username = user.username else: raise Exception( f"We cannot find any user with this {'email' if '@' in username_or_email else 'username'}!" ) totp = pyotp.TOTP(pyotp.random_base32()) otp = totp.now() local_db_session.query(OneTimeTOTP).filter( OneTimeTOTP.user_id == user.id).delete() local_db_session.flush() local_db_session.add(OneTimeTOTP(user_id=user.id, code=otp)) local_db_session.flush() send(email, f"Password reset for account {user.username}", password_reset(user, otp)) return RequestPasswordResetMutation( message= f"We've sent an email with a code to reset your password to {email}.", username=username)
def mutate(self, info, stage_id, name=None, description=None): if not name: raise Exception("Please pick a name!") current_user_id = get_jwt_identity() with ScopedSession() as local_db_session: id = from_global_id(stage_id)[1] stage = local_db_session.query(Stage).filter( Stage.id == id).first() if stage: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == stage.owner_id: raise Exception( "Only stage owner or Admin can start a recording on this stage!" ) else: raise Exception("Stage does not exist!") performance = PerformanceModel(stage=stage, name=name, description=description, recording=True) local_db_session.add(performance) local_db_session.flush() local_db_session.commit() recording = local_db_session.query(PerformanceModel).filter( PerformanceModel.id == performance.id).first() return StartRecording(recording=recording)
def mutate(self, info, id): with ScopedSession() as local_db_session: id = from_global_id(id)[1] asset = local_db_session.query(AssetModel).filter( AssetModel.id == id).first() if asset: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == asset.owner_id: return DeleteMedia(success=False, message="Only media owner or admin can delete this media!") if asset.description: attributes = json.loads(asset.description) if 'frames' in attributes and attributes['frames']: # Delete frames that was assigned only to this media for frame in attributes['frames']: frame_asset = local_db_session.query(AssetModel).filter( or_(AssetModel.file_location == frame, AssetModel.description.contains(frame))).first() if not frame_asset: physical_path = os.path.join( absolutePath, storagePath, frame) if os.path.exists(physical_path): os.remove(physical_path) physical_path = os.path.join( absolutePath, storagePath, asset.file_location) local_db_session.query(ParentStage).filter( ParentStage.child_asset_id == id).delete(synchronize_session=False) local_db_session.query(MediaTag).filter( MediaTag.asset_id == id).delete(synchronize_session=False) local_db_session.query(AssetLicense).filter( AssetLicense.asset_id == id).delete(synchronize_session=False) local_db_session.query(AssetUsage).filter( AssetUsage.asset_id == id).delete(synchronize_session=False) for multiframe_media in local_db_session.query(AssetModel).filter(AssetModel.description.like(f"%{asset.file_location}%")).all(): attributes = json.loads(multiframe_media.description) for i, frame in enumerate(attributes['frames']): if "?" in frame: attributes['frames'][i] = frame[:frame.index("?")] if asset.file_location in attributes['frames']: attributes['frames'].remove(asset.file_location) multiframe_media.description = json.dumps(attributes) local_db_session.flush() local_db_session.delete(asset) local_db_session.flush() local_db_session.commit() else: return DeleteMedia(success=False, message="Media not found!") if os.path.exists(physical_path): os.remove(physical_path) else: return DeleteMedia(success=True, message="Media deleted successfully but file not existed on storage!") return DeleteMedia(success=True, message="Media deleted successfully!")
def mutate(self, info, inbound): data = graphql_utils.input_to_dictionary(inbound) with ScopedSession() as local_db_session: user = local_db_session.query(UserModel).filter(UserModel.id==data['id']).first() if decrypt(user.password) != data['oldPassword']: raise Exception('Old password incorrect') else: user.password = encrypt(data['newPassword']) local_db_session.commit() return ChangePassword(success=True)
def mutate(self, info, id, stage_id): id = from_global_id(id)[1] with ScopedSession() as local_db_session: asset = local_db_session.query(AssetModel).get(id) if asset: code, error, user, timezone = current_user() stage = local_db_session.query(StageModel).get(stage_id) if stage: asset.stages.append(ParentStage(stage_id=stage_id)) local_db_session.flush() local_db_session.commit() return QuickAssignMutation(success=True) return QuickAssignMutation(success=False, message="Stage not found")
def mutate(self, info, id, name): with ScopedSession() as local_db_session: code, error, user, timezone = current_user() id = from_global_id(id)[1] stage = local_db_session.query(StageModel).filter( StageModel.id == id).first() if stage: local_db_session.expunge(stage) make_transient(stage) original_stage_id = id stage.id = None stage.name = name stage.owner_id = user.id shortname = re.sub('\s+', '-', re.sub('[^A-Za-z0-9 ]+', '', name)).lower() suffix = "" while True: existedStages = DBSession.query(StageModel).filter( StageModel.file_location == f"{shortname}{suffix}").first() if existedStages: suffix = int(suffix or 0) + 1 else: break stage.file_location = f"{shortname}{suffix}" local_db_session.add(stage) local_db_session.flush() new_stage_id = stage.id # Clone media and attributes, player accesses,... for ps in local_db_session.query(ParentStage).filter( ParentStage.stage_id == original_stage_id).all(): local_db_session.add( ParentStage(stage_id=new_stage_id, child_asset_id=ps.child_asset_id)) for attribute in local_db_session.query( StageAttributeModel).filter( StageAttributeModel.stage_id == original_stage_id).all(): local_db_session.add( StageAttributeModel(stage_id=new_stage_id, name=attribute.name, description=attribute.description)) local_db_session.flush() local_db_session.commit() return DuplicateStage(success=True, new_stage_id=to_global_id( 'Stage', new_stage_id)) else: raise Exception("Stage not found!")
def mutate(self, info, input): data = graphql_utils.input_to_dictionary(input) with ScopedSession() as local_db_session: stage = local_db_session.query(StageModel).filter( StageModel.id == data['id']).first() stage.assets.delete() for id in data['media_ids']: stage.assets.append(ParentStage(child_asset_id=id)) local_db_session.commit() stage = DBSession.query(StageModel).filter( StageModel.id == data['id']).first() return AssignMedia(stage=stage)
def mutate(self, info, url): with ScopedSession() as local_db_session: config = local_db_session.query(ConfigModel).filter( ConfigModel.name == TERMS_OF_SERVICE ).first() if config: config.value = url else: config = ConfigModel(name=TERMS_OF_SERVICE, value=url) local_db_session.add(config) local_db_session.commit() return UpdateTermsOfService(url=url)
def mutate(self, info): total = 0 with ScopedSession() as local_db_session: for media in local_db_session.query(AssetModel): if not media.size: full_path = os.path.join(absolutePath, storagePath, media.file_location) try: size = os.path.getsize(full_path) except: size = 0 # file not exist media.size = size local_db_session.flush() total += media.size return CalcSizes(size=total)
def mutate(self, info, username, otp): with ScopedSession() as local_db_session: user = local_db_session.query(User).filter( User.username == username).first() if not user: raise Exception(f"We cannot find any user with this username!") otp_record = local_db_session.query(OneTimeTOTP).filter( OneTimeTOTP.user_id == user.id).first() if not otp_record or otp_record.code != otp: raise Exception(f"Invalid OTP code. Please try again.") return VerifyPasswordResetMutation( message=f"Valid OTP code. Please enter a new password.")
def mutate(self, info, name, value): with ScopedSession() as local_db_session: config = local_db_session.query(ConfigModel).filter( ConfigModel.name == name).first() if name == TERMS_OF_SERVICE: # Use UpdateTermsOfService mutation instead. return SaveConfig(success=False) if config: config.value = value else: config = ConfigModel(name=name, value=value) local_db_session.add(config) return SaveConfig(success=True)
def mutate(self, info, input): data = input_to_dictionary(input) with ScopedSession() as local_db_session: asset = local_db_session.query(AssetModel).filter( AssetModel.id == data['id'] ).first() asset.stages.delete() for id in data['stage_ids']: asset.stages.append(ParentStage(stage_id=id)) local_db_session.flush() local_db_session.commit() asset = local_db_session.query(AssetModel).filter( AssetModel.id == data['id']).first() return AssignStages(asset=asset)
def mutate(self, info, asset_id, note=None): asset_id = from_global_id(asset_id)[1] with ScopedSession() as local_db_session: asset = local_db_session.query(AssetModel).get(asset_id) if asset: code, error, user, timezone = current_user() asset_usage = AssetUsageModel(user_id=user.id, asset_id=asset_id, note=note) if asset.copyright_level == 2: asset_usage.approved = False else: asset_usage.approved = True local_db_session.add(asset_usage) local_db_session.flush() local_db_session.commit() return ConfirmPermission(success=True)
def mutate(self, info, input): if not input.name or not input.file_location: raise Exception('Please fill in all required fields') data = graphql_utils.input_to_dictionary(input) stage = StageModel(**data) stage.owner_id = get_jwt_identity() # Add validation for non-empty passwords, etc. with ScopedSession() as local_db_session: local_db_session.add(stage) local_db_session.flush() stage_id = stage.id local_db_session.commit() stage = DBSession.query(StageModel).filter( StageModel.id == stage_id).first() return CreateStage(stage=stage)
def mutate(self, info, inbound): data = graphql_utils.input_to_dictionary(inbound) code,error,user,timezone = current_user() if not user.role in (ADMIN,SUPER_ADMIN) : raise Exception("Permission denied!") with ScopedSession() as local_db_session: # Delete all existed user's sessions local_db_session.query(UserSession).filter(UserSession.user_id==data['id']).delete() # Delete all stages created by this user local_db_session.query(StageAttributeModel).filter(StageAttributeModel.stage.has(StageModel.owner_id==data['id'])).delete(synchronize_session='fetch') local_db_session.query(StageModel).filter(StageModel.owner_id==data['id']).delete() # Change the owner of media uploaded by this user to the one who process the delete # Because delete the media would cause impact to other stage, this would be a workaround for now local_db_session.query(AssetModel).filter(AssetModel.owner_id==data['id']).update({AssetModel.owner_id: user.id}) # Delete the actual user local_db_session.query(UserModel).filter(UserModel.id==data['id']).delete() local_db_session.commit() return DeleteUser(success=True)
def mutate(self, info, users, stageIds=[]): code,error,user,timezone = current_user() if not user.role in (ADMIN,SUPER_ADMIN) : raise Exception("Permission denied!") ids = [] with ScopedSession() as local_db_session: duplicated = [] for i in range(len(users) - 1): for j in range(i + 1, len(users)): if users[i].username == users[j].username: duplicated.append(users[i].username) if duplicated: raise Exception('Duplicated username: '******', '.join(duplicated)) existed = [user.username for user in DBSession.query(UserModel).filter(UserModel.username.in_([x.username for x in users])).all()] if existed: raise Exception('Username already existed: ' + ', '.join(existed)) for item in users: user = UserModel( username=item.username, active=True, role=GUEST ) # Add validation for non-empty passwords, etc. user.password = encrypt(item.password) local_db_session.add(user) local_db_session.flush() ids.append(user.id) # Now assigns users into stages stages = DBSession.query(StageModel).filter(StageModel.id.in_(stageIds)).all() for stage in stages: player_access = stage.attributes.filter(StageAttributeModel.name == 'playerAccess').first() if player_access: accesses = json.loads(player_access.description) for user_id in ids: if user_id not in accesses[0]: accesses[0].append(user_id) # append user id to player ids player_access.description = json.dumps(accesses) local_db_session.flush() local_db_session.commit() users = DBSession.query(UserModel).filter(UserModel.id.in_(ids)).all() return BatchUserCreation(users=users)
def mutate(self, info, id): with ScopedSession() as local_db_session: scene = local_db_session.query(SceneModel).filter( SceneModel.id == id).first() if scene: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == scene.owner_id: return DeleteScene( success=False, message= "Only scene owner or admin can delete this scene!") scene.active = False local_db_session.flush() local_db_session.commit() else: return DeleteScene(success=False, message="Scene not found!") return DeleteScene(success=True, message="Scene deleted successfully!")
def mutate(self, info, username, otp, password): with ScopedSession() as local_db_session: user = local_db_session.query(User).filter( User.username == username).first() if not user: raise Exception(f"We cannot find any user with this username!") otp_record = local_db_session.query(OneTimeTOTP).filter( OneTimeTOTP.user_id == user.id).first() if not otp_record or otp_record.code != otp: raise Exception(f"Invalid OTP code. Please try again.") local_db_session.query(OneTimeTOTP).filter( OneTimeTOTP.user_id == user.id).delete() user.password = encrypt(password) local_db_session.flush() return PasswordResetMutation( message=f"Password reset successfully.")
def mutate(self, info, inbound): data = graphql_utils.input_to_dictionary(inbound) if not data['email'] and data['role'] != GUEST: raise Exception("Email is required!") user = UserModel(**data) user_id = None # Add validation for non-empty passwords, etc. user.password = encrypt(user.password) if not user.role: user.role = PLAYER with ScopedSession() as local_db_session: local_db_session.add(user) local_db_session.flush() user_id = user.id user = DBSession.query(UserModel).filter(UserModel.id==user_id).first() send(user.email, f"Welcome to UpStage!", user_registration(user)) admin_emails = [admin.email for admin in DBSession.query(UserModel).filter(UserModel.role.in_([SUPER_ADMIN,ADMIN])).all()] approval_url = f"{request.url_root}backstage/admin/player-management" send(','.join(admin_emails), f"Approval required for {user.username}'s registration", admin_registration_notification(user, approval_url)) return CreateUser(user=user)
def mutate(self, info, id, approved): id = from_global_id(id)[1] with ScopedSession() as local_db_session: asset_usage = local_db_session.query(AssetUsageModel).get(id) asset_id = asset_usage.asset_id if asset_usage: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == asset_usage.asset.owner_id: return ConfirmPermission( success=False, message= "Only media owner or admin can delete this media!") if approved: asset_usage.approved = True asset_usage.seen = True else: local_db_session.delete(asset_usage) local_db_session.flush() permissions = DBSession.query(AssetUsageModel).filter( AssetUsageModel.asset_id == asset_id).all() return ConfirmPermission(success=True, permissions=permissions)
def add(self, token): if 'token' in token: orig_token = copy.deepcopy(token['token']) token_type = token['token']['type'] decoded_token = token['token'] token = token['token']['jti'] elif 'type' in token: orig_token = copy.deepcopy(token) token_type = token['type'] decoded_token = token token = token['jti'] else: orig_token = copy.deepcopy(token) decoded_token = jwt_utils.decode_token(token) token_type = decoded_token['type'] token = decoded_token['jti'] if self.check('x', decoded_token): return # Already restricted. if DBSession.query(JWTNoList).filter(JWTNoList.token == token).first(): return if token_type == 'access': remove_after = datetime.utcnow( ) + app.config['JWT_ACCESS_TOKEN_EXPIRES'] else: remove_after = datetime.utcnow( ) + app.config['JWT_REFRESH_TOKEN_EXPIRES'] with ScopedSession() as local_db_session: TokenNo = JWTNoList( token=token, token_type=token_type, remove_after=remove_after, ) local_db_session.add(TokenNo)
def mutate(self, info, id): current_user_id = get_jwt_identity() with ScopedSession() as local_db_session: performance = local_db_session.query(PerformanceModel).filter( PerformanceModel.id == id).first() if performance: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == performance.stage.owner_id: raise Exception( "Only stage owner or Admin can save a recording!") saved_on = datetime.utcnow() events = local_db_session.query(Event)\ .filter(Event.topic.like("%/{}/%".format(performance.stage.file_location)))\ .filter(Event.created > performance.created_on)\ .filter(Event.created < saved_on) if events.count() > 0: # Clone each events that happend between the recording session for event in events.all(): local_db_session.expunge(event) make_transient(event) event.id = None event.performance_id = performance.id local_db_session.add(event) else: raise Exception("Nothing to record!") performance.saved_on = saved_on local_db_session.flush() local_db_session.commit() else: raise Exception("Performance not found!") recording = local_db_session.query(PerformanceModel).filter( PerformanceModel.id == performance.id).first() return SaveRecording(recording=recording)
def mutate(self, info, id): with ScopedSession() as local_db_session: performance = local_db_session.query(PerformanceModel).filter( PerformanceModel.id == id).first() if performance: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == performance.owner_id: raise Exception( "Only stage owner or Admin can delete this record!" ) local_db_session.query(Event).filter( Event.performance_id == id).delete( synchronize_session=False) local_db_session.delete(performance) local_db_session.flush() local_db_session.commit() else: raise Exception("Performance not found!") return DeletePerformance(success=True)
def mutate(self, info, id, name=None, description=None): if not name: raise Exception("Please pick a name!") current_user_id = get_jwt_identity() with ScopedSession() as local_db_session: performance = local_db_session.query(PerformanceModel).filter( PerformanceModel.id == id).first() if performance: code, error, user, timezone = current_user() if not user.role in (ADMIN, SUPER_ADMIN): if not user.id == performance.stage.owner_id: raise Exception( "Only stage owner or Admin can update archived performance information!" ) performance.name = name performance.description = description local_db_session.flush() local_db_session.commit() else: raise Exception("Performance not found!") return UpdatePerformance(success=True)