async def create_protocol( protocol: ProtocolModel, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): protocol_dict = protocol.dict() protocol = Protocol() protocol_version = ProtocolVersion(data=strip_metadata(protocol_dict), server_version=settings.server_version) protocol_version.protocol = protocol protocol.current = protocol_version add_owner(protocol, current_user.username) db.add_all([protocol, protocol_version]) db.commit() add_policy(enforcer, user=current_user.username, path=f"/protocol/{str(protocol.id)}", method="GET") add_policy(enforcer, user=current_user.username, path=f"/protocol/{str(protocol.id)}", method="PUT") add_policy(enforcer, user=current_user.username, path=f"/protocol/{str(protocol.id)}", method="DELETE") return versioned_row_to_dict(protocol, protocol_version)
async def update_run_sample( run_id: int, sample_id: str, sample: SampleResult, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): if not check_access(enforcer, user=current_user.username, path=f"/run/{str(run_id)}", method="PUT"): raise HTTPException(status_code=403, detail='Insufficient Permissions') run = db.query(Run).get(run_id) if not run or run.is_deleted: raise HTTPException(status_code=404, detail='Run Not Found') sample_dict = sample.dict() new_sample = db.query(Sample).filter( Sample.sample_version_id == new_sample.version_id).filter( Sample.sample_id == sample_id).first() if not new_sample or new_sample.is_deleted: raise HTTPException(status_code=404, detail='Sample Not Found') if not change_allowed(run_to_dict(run, run.current), {}): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_sample_version = SampleVersion(data=strip_metadata(sample_dict), server_version=settings.server_version) new_sample_version.sample = new_sample add_updator(new_sample_version, current_user.username) new_sample.current = new_sample_version db.add(new_sample_version) db.commit() return run_to_sample(new_sample)
async def patch_protocol( protocol_id: int, patch: list, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): if not check_access(enforcer, user=current_user.username, path=f"/protocol/{str(protocol_id)}", method="PUT"): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_protocol = db.query(Protocol).get(protocol_id) if not new_protocol or new_protocol.is_deleted: raise HTTPException(status_code=404, detail='Protocol Not Found') protocol_dict = versioned_row_to_dict(new_protocol, new_protocol.current) json_patch = jsonpatch.JsonPatch(patch) protocol_dict = json_patch.apply(protocol_dict) if not change_allowed( versioned_row_to_dict(new_protocol, new_protocol.current), protocol_dict): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_protocol_version = ProtocolVersion( data=strip_metadata(protocol_dict), server_version=settings.server_version) new_protocol_version.protocol = new_protocol add_updator(new_protocol_version, current_user.username) new_protocol.current = new_protocol_version db.add(new_protocol_version) db.commit() return versioned_row_to_dict(new_protocol, new_protocol.current)
async def update_run( run_id: int, run: RunModel, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): if not check_access(enforcer, user=current_user.username, path=f"/run/{str(run_id)}", method="PUT"): raise HTTPException(status_code=403, detail='Insufficient Permissions') run_dict = run.dict() # This field shouldn't be updated by users. run_dict.pop('protocol', None) new_run = db.query(Run).get(run_id) if not new_run or new_run.is_deleted: raise HTTPException(status_code=404, detail='Run Not Found') if not change_allowed(run_to_dict(new_run, new_run.current), run_dict): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_run_version = RunVersion(data=strip_metadata(run_dict), server_version=settings.server_version) new_run_version.run = new_run add_updator(new_run_version, current_user.username) new_run.current = new_run_version db.add(new_run_version) samples = get_samples(new_run_version, new_run.protocol_version) if samples: for sample in samples: db.merge(sample) db.commit() return run_to_dict(new_run, new_run.current)
def post(self): run_dict = request.json protocol_id = extract_protocol_id(run_dict) run_dict.pop('protocol', None) if not protocol_id: abort(400) return protocol = Protocol.query.get(protocol_id) if not protocol: abort(400) return run = Run() run_version = RunVersion(data=strip_metadata(run_dict), server_version=app.config['SERVER_VERSION']) run_version.run = run run.current = run_version run.protocol_version_id = protocol.version_id add_owner(run) db.session.add_all([run, run_version]) samples = get_samples(run, run_version) if samples: for sample in samples: db.session.merge(sample) db.session.commit() add_policy(path=f"/run/{str(run.id)}", method="GET") add_policy(path=f"/run/{str(run.id)}", method="PUT") add_policy(path=f"/run/{str(run.id)}", method="DELETE") return run_to_dict(run, run_version)
async def create_user( user: UserModel, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): user_dict = user.dict() # Drop the roles field if it was provided. user_dict.pop('roles', None) new_user = User(id=current_user.username if current_user.username else 42) new_user_version = UserVersion(data=strip_metadata(user_dict), server_version=settings.server_version) new_user_version.user = new_user new_user.current = new_user_version add_owner(new_user, current_user.username) db.add_all([new_user, new_user_version]) db.commit() add_policy(enforcer, user=current_user.username, path=f"/user/{str(new_user.id)}", method="GET") add_policy(enforcer, user=current_user.username, path=f"/user/{str(new_user.id)}", method="PUT") return add_role(enforcer, versioned_row_to_dict(new_user, new_user_version))
async def update_sample(sample_id: str, sample: SampleResult, db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): sample_dict = sample.dict() new_sample = db.query(Sample).get(sample_id) if not new_sample or new_sample.is_deleted: raise HTTPException(status_code=404, detail='Sample not found') if not change_allowed(run_to_sample(new_sample), sample_dict): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_sample_version = SampleVersion(data=strip_metadata(sample_dict), server_version=settings.server_version) new_sample_version.sample = new_sample add_updator(new_sample_version, current_user.username) new_sample.current = new_sample_version db.session.add(new_sample_version) db.session.commit() return run_to_sample(new_sample)
def post(self): protocol_dict = request.json protocol = Protocol() protocol_version = ProtocolVersion( data=strip_metadata(protocol_dict), server_version=app.config['SERVER_VERSION']) protocol_version.protocol = protocol protocol.current = protocol_version add_owner(protocol) db.session.add_all([protocol, protocol_version]) db.session.commit() add_policy(path=f"/protocol/{str(protocol.id)}", method="GET") add_policy(path=f"/protocol/{str(protocol.id)}", method="PUT") add_policy(path=f"/protocol/{str(protocol.id)}", method="DELETE") return versioned_row_to_dict(api, protocol, protocol_version)
def post(self): user_dict = request.json # Drop the roles field if it was provided. user_dict.pop('roles', None) user = User(id=request.current_user["sub"] if request. current_user["sub"] else 42) user_version = UserVersion(data=strip_metadata(user_dict), server_version=app.config['SERVER_VERSION']) user_version.user = user user.current = user_version add_owner(user) db.session.add_all([user, user_version]) db.session.commit() add_policy(path=f"/user/{str(user.id)}", method="GET") add_policy(path=f"/user/{str(user.id)}", method="PUT") return add_role(versioned_row_to_dict(api, user, user_version))
def put(self, sample_id): sample_dict = request.json sample = Sample.query.get(sample_id) if not sample or sample.is_deleted: abort(404) return if not change_allowed(run_to_sample(sample), sample_dict): abort(403) return sample_version = SampleVersion( data=strip_metadata(sample_dict), server_version=app.config['SERVER_VERSION']) sample_version.sample = sample add_updator(sample_version) sample.current = sample_version db.session.add(sample_version) db.session.commit() return run_to_sample(sample)
def put(self, user_id): user_id = urllib.parse.unquote(user_id) user_dict = request.json # Drop the roles field if it was provided. user_dict.pop('roles', None) user_dict = request.json user = User.query.get(user_id) if not user or user.is_deleted: abort(404) return user_version = UserVersion(data=strip_metadata(user_dict), server_version=app.config['SERVER_VERSION']) user_version.user = user add_updator(user_version) user.current = user_version db.session.add(user_version) db.session.commit() return add_role(versioned_row_to_dict(api, user, user.current))
def put(self, protocol_id): protocol_dict = request.json protocol = Protocol.query.get(protocol_id) if not protocol or protocol.is_deleted: abort(404) return if not change_allowed( versioned_row_to_dict(api, protocol, protocol.current), protocol_dict): abort(403) return protocol_version = ProtocolVersion( data=strip_metadata(protocol_dict), server_version=app.config['SERVER_VERSION']) protocol_version.protocol = protocol add_updator(protocol_version) protocol.current = protocol_version db.session.add(protocol_version) db.session.commit() return versioned_row_to_dict(api, protocol, protocol.current)
async def create_run( run: RunModel, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): run_dict = run.dict() protocol_id = extract_protocol_id(run_dict) run_dict.pop('protocol', None) if not protocol_id: raise HTTPException(status_code=400, detail='Invalid Protocol ID') protocol = db.query(Protocol).get(protocol_id) if not protocol: raise HTTPException(status_code=400, detail='Invalid Protocol (Not Found)') new_run = Run() new_run_version = RunVersion(data=strip_metadata(run_dict), server_version=settings.server_version) new_run_version.run = new_run new_run.current = new_run_version new_run.protocol_version_id = protocol.version_id add_owner(new_run, current_user.username) db.add_all([new_run, new_run_version]) samples = get_samples(new_run_version, protocol.current) if samples: for sample in samples: db.merge(sample) db.commit() add_policy(enforcer, user=current_user.username, path=f"/run/{str(new_run.id)}", method="GET") add_policy(enforcer, user=current_user.username, path=f"/run/{str(new_run.id)}", method="PUT") add_policy(enforcer, user=current_user.username, path=f"/run/{str(new_run.id)}", method="DELETE") return run_to_dict(new_run, new_run_version)
def put(self, run_id, sample_id): sample_dict = request.json # This field shouldn't be updated by users. # sample_dict.pop('protocol', None) sample = Sample.query.filter( Sample.sample_version_id == sample.version_id).filter( Sample.sample_id == sample_id).first() if not sample or sample.is_deleted: abort(404) return if not change_allowed(run_to_dict(run, run.current), {}): abort(403) return sample_version = SampleVersion( data=strip_metadata(sample_dict), server_version=app.config['SERVER_VERSION']) sample_version.sample = sample add_updator(sample_version) sample.current = sample_version db.session.add(sample_version) db.session.commit() return run_to_sample(sample)
async def update_user( user_id: str, user: UserModel, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): user_id = urllib.parse.unquote(user_id) user_dict = user.dict() # Drop the roles field if it was provided. user_dict.pop('roles', None) new_user = db.query(User).get(user_id) if not new_user or new_user.is_deleted: raise HTTPException(status_code=404, detail='User Not Found') new_user_version = UserVersion(data=strip_metadata(user_dict), server_version=settings.server_version) new_user_version.user = new_user add_updator(new_user_version, current_user.username) new_user.current = new_user_version db.add(new_user_version) db.commit() return add_role(enforcer, versioned_row_to_dict(new_user, new_user.current))
def put(self, run_id): run_dict = request.json # This field shouldn't be updated by users. run_dict.pop('protocol', None) run = Run.query.get(run_id) if not run or run.is_deleted: abort(404) return if not change_allowed(run_to_dict(run, run.current), run_dict): abort(403) return run_version = RunVersion(data=strip_metadata(run_dict), server_version=app.config['SERVER_VERSION']) run_version.run = run add_updator(run_version) run.current = run_version db.session.add(run_version) samples = get_samples(run, run_version) if samples: for sample in samples: db.session.merge(sample) db.session.commit() return run_to_dict(run, run.current)
async def patch_run( request: Request, run_id: int, patch: list, enforcer: casbin.Enforcer = Depends(get_enforcer), db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)): if not check_access(enforcer, user=current_user.username, path=f"/run/{str(run_id)}", method="PUT"): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_run = db.query(Run).get(run_id) original_run_version = new_run.current if not new_run or new_run.is_deleted: raise HTTPException(status_code=404, detail='Run Not Found') record_timing(request, note=f"Fetched run {run_id}") run_dict = versioned_row_to_dict(new_run, new_run.current) run_dict.pop('protocol', None) json_patch = jsonpatch.JsonPatch(patch) run_dict.pop('protocol', None) run_dict = json_patch.apply(run_dict) if not change_allowed(run_to_dict(new_run, new_run.current), run_dict): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_run_version = RunVersion(data=strip_metadata(run_dict), server_version=settings.server_version) new_run_version.run = new_run add_updator(new_run_version, current_user.username) original_run_version = new_run.current new_run.current = new_run_version db.add(new_run_version) db.commit() record_timing(request, note=f"Saved changes to run {run_id}") samples_dirty = False for operation in patch: operation_path = operation.get('path', '') # Check for changes to the path: /sections/*/blocks/*/plates if re.search( "^/(sections/([^/]+/(blocks/([^/]+/(plates(/.*)?)?)?)?)?)?$", operation_path): samples_dirty = True break # Check for changes to the path: /sections/*/blocks/*/plateSequencingResults if re.search( "^/(sections/([^/]+/(blocks/([^/]+/(plateSequencingResults(/.*)?)?)?)?)?)?$", operation_path): samples_dirty = True break # Check for changes to the path: /protocol/sections/*/blocks/*/plateMarkers if re.search( "^/(protocol/(sections/([^/]+/(blocks/([^/]+/(plateMarkers(/.*)?)?)?)?)?)?)?$", operation_path): samples_dirty = True break if samples_dirty: logger.info("======================================") logger.info( f"Regenerating samples for run_version: ({new_run.id}, {new_run_version.id})" ) samples = get_samples(new_run_version, new_run.protocol_version) record_timing( request, note=f"Regenerated run {new_run.id} samples (len: {len(samples)})") if samples: for sample in samples: db.merge(sample) logger.info( f"Generated {len(samples)} samples for run_version: ({new_run.id}, {new_run_version.id})" ) logger.info("======================================") record_timing( request, note=f"Saved {len(samples)} regenerated samples to run {new_run.id}" ) else: logger.info("======================================") logger.info( f"Using old samples for run_version: ({new_run.id}, {new_run_version.id})" ) samples = db.query(Sample)\ .filter(Sample.run_version_id == original_run_version.id)\ .distinct() sample_count = 0 for sample in samples: new_sample_version = clone_model(db, sample.current, run_version_id=new_run_version.id) new_sample = clone_model(db, sample, current=new_sample_version, run_version_id=new_run_version.id) db.merge(new_sample) sample_count += 1 logger.info( f"Attached {sample_count} existing samples to run_version: ({new_run.id}, {new_run_version.id})" ) logger.info("======================================") record_timing( request, note=f"Attached {sample_count} existing samples to run {new_run.id}" ) db.commit() return run_to_dict(new_run, new_run.current)