Beispiel #1
0
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)
Beispiel #2
0
async def get_protocols(
    run: Optional[int] = None,
    plate: Optional[str] = None,
    reagent: Optional[str] = None,
    sample: Optional[str] = None,
    creator: Optional[str] = None,
    archived: Optional[bool] = None,
    page: Optional[int] = None,
    per_page: Optional[int] = None,
    enforcer: casbin.Enforcer = Depends(get_enforcer),
    db: Session = Depends(get_db),
    current_user: Auth0ClaimsPatched = Depends(get_current_user)):
    return crud_get_protocols(
        item_to_dict=lambda protocol: versioned_row_to_dict(
            protocol, protocol.current, include_large_fields=False),
        enforcer=enforcer,
        db=db,
        current_user=current_user,
        run=run,
        plate=plate,
        reagent=reagent,
        sample=sample,
        creator=creator,
        archived=archived,
        page=page,
        per_page=per_page,
    )
Beispiel #3
0
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))
Beispiel #4
0
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)
Beispiel #5
0
 def get_node(cls, info: ResolveInfo, id):
     db = get_session(info)
     row = db.query(cls._meta.db_model)\
         .filter(and_(
             cls._meta.db_model.is_deleted != True,
             cls._meta.db_model.id == id,
         ))\
         .first()
     return cls._meta.model.parse_obj(versioned_row_to_dict(row, row.current))
Beispiel #6
0
    def resolve_all_users(
        root,
        info: ResolveInfo,

        # Search parameters
        archived: Optional[bool] = None,
        
        # Paging parameters
        page: Optional[int] = None,
        per_page: Optional[int] = None,

        # Currently unused
        before: Optional[str] = None,
        after: Optional[str] = None,
        first: Optional[int] = None,
        last: Optional[int] = None,
    ):
        enforcer = get_enforcer_from_request(info.context['request'])
        current_user = get_current_user_from_request(info.context['request'])
        if current_user is None:
            raise HTTPException(401, "Unauthorized")

        db = get_session(info)
        pagination_dict = crud_get_users(
            item_to_dict=lambda user: add_ids(versioned_row_to_dict(user, user.current), user_id=user.id),

            enforcer=enforcer,
            db=db,
            current_user=current_user,

            archived=archived,

            page=page,
            per_page=per_page,
        )

        return UserConnection(
            page=pagination_dict.get('page', None),
            pageCount=pagination_dict.get('pageCount', None),
            edges=[
                UserConnection.Edge(
                    node=UserModel.parse_obj(r),
                    cursor=f"{pagination_dict.get('page', 1)}.{i}",
                )
                for i, r
                in enumerate(pagination_dict['users'])
            ],
            page_info=relay.PageInfo(
                has_next_page=pagination_dict.get('page', 1) < pagination_dict.get('pageCount', 1),
                has_previous_page=pagination_dict.get('page', 1) > pagination_dict.get('pageCount', 1),
                start_cursor="1.0",
                end_cursor=f"1.{len(pagination_dict['users'])}" if pagination_dict.get('pageCount', None) is None else f"{pagination_dict['pageCount']}.{len(pagination_dict['users'])}",
            ),
        )
Beispiel #7
0
 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)
Beispiel #8
0
    def get(self, protocol_id):
        version_id = int(request.args.get('version_id')) if request.args.get(
            'version_id') else None

        if version_id:
            protocol_version = ProtocolVersion.query\
                .filter(ProtocolVersion.id == version_id)\
                .filter(Protocol.id == protocol_id)\
                .first()
            if (not protocol_version) or protocol_version.protocol.is_deleted:
                abort(404)
                return
            return versioned_row_to_dict(api, protocol_version.protocol,
                                         protocol_version)

        protocol = Protocol.query.get(protocol_id)
        if (not protocol) or protocol.is_deleted:
            abort(404)
            return
        return versioned_row_to_dict(api, protocol, protocol.current)
Beispiel #9
0
    def get(self, user_id):
        user_id = urllib.parse.unquote(user_id)
        version_id = int(request.args.get('version_id')) if request.args.get(
            'version_id') else None

        if version_id:
            user_version = UserVersion.query\
                .filter(UserVersion.id == version_id)\
                .filter(User.id == user_id)\
                .first()
            if (not user_version) or user_version.user.is_deleted:
                abort(404)
                return
            return add_role(
                versioned_row_to_dict(api, user_version.user, user_version))

        user = User.query.get(user_id)
        if (not user) or user.is_deleted:
            abort(404)
            return
        return add_role(versioned_row_to_dict(api, user, user.current))
Beispiel #10
0
async def get_user(
    user_id: str,
    version_id: Optional[int] = None,
    enforcer: casbin.Enforcer = Depends(get_enforcer),
    db: Session = Depends(get_db),
    current_user: Auth0ClaimsPatched = Depends(get_current_user)):
    return crud_get_user(
        item_to_dict=lambda user: add_role(
            enforcer, versioned_row_to_dict(user, user.current)),
        enforcer=enforcer,
        db=db,
        current_user=current_user,
        user_id=user_id,
        version_id=version_id,
    )
Beispiel #11
0
 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)
Beispiel #12
0
async def get_protocol(
    protocol_id: int,
    version_id: Optional[int] = None,
    enforcer: casbin.Enforcer = Depends(get_enforcer),
    db: Session = Depends(get_db),
    current_user: Auth0ClaimsPatched = Depends(get_current_user)):
    return crud_get_protocol(
        item_to_dict=lambda protocol: versioned_row_to_dict(
            protocol, protocol.current),
        enforcer=enforcer,
        db=db,
        current_user=current_user,
        protocol_id=protocol_id,
        version_id=version_id,
    )
Beispiel #13
0
    def resolve_owner(root, info):
        enforcer = get_enforcer_from_request(info.context['request'])
        current_user = get_current_user_from_request(info.context['request'])
        if current_user is None:
            raise HTTPException(401, "Unauthorized")

        db = get_session(info)
        return UserModel.parse_obj(
            crud_get_user(
                item_to_dict=lambda user: add_ids(versioned_row_to_dict(user, user.current), user_id=user.id),
                enforcer=enforcer,
                db=db,
                current_user=current_user,
                user_id=root.created_by,
            ),
        )
Beispiel #14
0
 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))
Beispiel #15
0
async def get_users(
        page: Optional[int] = None,
        per_page: Optional[int] = None,
        enforcer: casbin.Enforcer = Depends(get_enforcer),
        db: Session = Depends(get_db),
        current_user: Auth0ClaimsPatched = Depends(get_current_user),
):
    return crud_get_users(
        item_to_dict=lambda user: add_role(
            enforcer, versioned_row_to_dict(user, user.current)),
        enforcer=enforcer,
        db=db,
        current_user=current_user,
        archived=False,
        page=page,
        per_page=per_page,
    )
Beispiel #16
0
    def resolve_samples(
        root,
        info: ResolveInfo,

        # Paging parameters
        page: Optional[int] = None,
        per_page: Optional[int] = None,
    ):
        enforcer = get_enforcer_from_request(info.context['request'])
        current_user = get_current_user_from_request(info.context['request'])
        if current_user is None:
            raise HTTPException(401, "Unauthorized")

        db = get_session(info)
        pagination_dict = crud_get_run_samples(
            item_to_dict=lambda sample: versioned_row_to_dict(sample, sample.current),

            enforcer=enforcer,
            db=db,
            current_user=current_user,

            run_id=root.run_id,

            page=page,
            per_page=per_page,
        )

        return SampleConnection(
            page=pagination_dict.get('page', None),
            pageCount=pagination_dict.get('pageCount', None),
            edges=[
                SampleConnection.Edge(
                    node=SampleResult.parse_obj(r),
                    cursor=f"{pagination_dict.get('page', 1)}.{i}",
                )
                for i, r
                in enumerate(pagination_dict['samples'])
            ],
            page_info=relay.PageInfo(
                has_next_page=pagination_dict.get('page', 1) < pagination_dict.get('pageCount', 1),
                has_previous_page=pagination_dict.get('page', 1) > pagination_dict.get('pageCount', 1),
                start_cursor="1.0",
                end_cursor=f"1.{len(pagination_dict['samples'])}" if pagination_dict.get('pageCount', None) is None else f"{pagination_dict['pageCount']}.{len(pagination_dict['samples'])}",
            ),
        )
Beispiel #17
0
    def resolve_protocol(root, info: ResolveInfo, id: int, version_id: Optional[int]):
        enforcer = get_enforcer_from_request(info.context['request'])
        current_user = get_current_user_from_request(info.context['request'])
        if current_user is None:
            raise HTTPException(401, "Unauthorized")

        db = get_session(info)
        model_dict = crud_get_protocol(
            item_to_dict=lambda protocol: add_ids(versioned_row_to_dict(protocol, protocol.current), protocol_id=protocol.id),

            enforcer=enforcer,
            db=db,
            current_user=current_user,

            protocol_id=id,
            version_id=version_id,
        )
        return ProtocolModel.parse_obj(model_dict)
Beispiel #18
0
    def resolve_user(root, info: ResolveInfo, id: str, version_id: Optional[int]):
        enforcer = get_enforcer_from_request(info.context['request'])
        current_user = get_current_user_from_request(info.context['request'])
        if current_user is None:
            raise HTTPException(401, "Unauthorized")

        db = get_session(info)
        model_dict = crud_get_user(
            item_to_dict=lambda user: add_ids(versioned_row_to_dict(user, user.current), user_id=user.id),

            enforcer=enforcer,
            db=db,
            current_user=current_user,

            user_id=id,
            version_id=version_id,
        )
        return UserModel.parse_obj(model_dict)
Beispiel #19
0
    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))
Beispiel #20
0
    def resolve_sample(root, info: ResolveInfo, sample_id: str, plate_id: str, run_version_id: int, protocol_version_id: int, version_id: Optional[int]):
        enforcer = get_enforcer_from_request(info.context['request'])
        current_user = get_current_user_from_request(info.context['request'])
        if current_user is None:
            raise HTTPException(401, "Unauthorized")

        db = get_session(info)
        model_dict = crud_get_sample(
            item_to_dict=lambda sample: versioned_row_to_dict(sample, sample.current),

            enforcer=enforcer,
            db=db,
            current_user=current_user,

            sample_id=sample_id,
            plate_id=plate_id,
            run_version_id=run_version_id,
            protocol_version_id=protocol_version_id,
            version_id=version_id,
        )
        return SampleResult.parse_obj(model_dict)
Beispiel #21
0
    def get(self):
        results = {}
        if request.args.get('page') is not None or request.args.get(
                'per_page') is not None:
            page = int(
                request.args.get('page')) if request.args.get('page') else 1
            per_page = int(request.args.get('per_page')) if request.args.get(
                'per_page') else 20
            page_query = User.query.filter(User.is_deleted != True).paginate(
                page=page, per_page=per_page)
            results['page'] = page_query.page
            results['pageCount'] = page_query.pages
            query = page_query.items
        else:
            query = User.query.filter(User.is_deleted != True).all()

        results['users'] = [
            add_role(versioned_row_to_dict(api, user, user.current))
            for user in query
            if check_access(path=f"/user/{user.id}", method="GET")
        ]
        return results
Beispiel #22
0
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))
Beispiel #23
0
    def resolve_run(
        root,
        info: ResolveInfo,
        
        id: int,
        version_id: int,
    ):
        enforcer = get_enforcer_from_request(info.context['request'])
        current_user = get_current_user_from_request(info.context['request'])
        if current_user is None:
            raise HTTPException(401, "Unauthorized")

        db = get_session(info)
        model_dict = crud_get_run(
            item_to_dict=lambda run: add_ids(versioned_row_to_dict(run, run.current), run_id=run.id),

            enforcer=enforcer,
            db=db,
            current_user=current_user,

            run_id=id,
            version_id=version_id,
        )
        return RunModel.parse_obj(model_dict)
Beispiel #24
0
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)
Beispiel #25
0
def run_to_dict(run, run_version):
    run_dict = versioned_row_to_dict(api, run, run_version)
    run_dict['protocol'] = versioned_row_to_dict(api,
                                                 run.protocol_version.protocol,
                                                 run.protocol_version)
    return run_dict
Beispiel #26
0
def run_to_dict(run, run_version, include_large_fields=True):
    run_dict = versioned_row_to_dict(run, run_version, include_large_fields)
    run_dict['protocol'] = versioned_row_to_dict(run.protocol_version.protocol,
                                                 run.protocol_version,
                                                 include_large_fields)
    return run_dict
Beispiel #27
0
    def get(self):
        run = int(request.args.get('run')) if request.args.get('run') else None
        plate = request.args.get('plate')
        reagent = request.args.get('reagent')
        sample = request.args.get('sample')
        creator = request.args.get('creator')
        archived = request.args.get('archived') == 'true' if request.args.get(
            'archived') else False

        protocols_queries = []
        if run:
            protocols_queries.append(
                all_protocols(archived)\
                    .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\
                    .join(Run, Run.protocol_version_id == ProtocolVersion.id)\
                    .filter(Run.id == run)
            )
        if plate:
            run_version_query = all_protocols(archived)\
                .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\
                .join(Run, Run.protocol_version_id == ProtocolVersion.id)\
                .join(RunVersion, RunVersion.id == Run.version_id)
            protocols_subquery = filter_by_plate_label(run_version_query,
                                                       plate)
            protocols_queries.append(protocols_subquery)
        if reagent:
            run_version_query = all_protocols(archived)\
                .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\
                .join(Run, Run.protocol_version_id == ProtocolVersion.id)\
                .join(RunVersion, RunVersion.id == Run.version_id)
            protocols_subquery = filter_by_reagent_label(
                run_version_query, reagent)
            protocols_queries.append(protocols_subquery)
        if sample:
            run_version_query = all_protocols(archived)\
                .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\
                .join(Run, Run.protocol_version_id == ProtocolVersion.id)\
                .join(RunVersion, RunVersion.id == Run.version_id)
            protocols_subquery = filter_by_sample_label(
                run_version_query, sample)
            protocols_queries.append(protocols_subquery)
        if creator:
            protocols_queries.append(
                all_protocols(archived)\
                    # .filter(Protocol.id == protocol)\
                    .filter(Protocol.created_by == creator)
            )

        # Add a basic non-deleted items query if no filters were specified.
        if len(protocols_queries) == 0:
            protocols_queries.append(all_protocols(archived))

        # Only return the intersection of all queries.
        protocols_query = reduce(lambda a, b: a.intersect(b),
                                 protocols_queries)

        results = {}
        if request.args.get('page') is not None or request.args.get(
                'per_page') is not None:
            page = int(
                request.args.get('page')) if request.args.get('page') else 1
            per_page = int(request.args.get('per_page')) if request.args.get(
                'per_page') else 20
            page_query = protocols_query.distinct().order_by(
                Protocol.created_on.desc()).paginate(page=page,
                                                     per_page=per_page)
            results['page'] = page_query.page
            results['pageCount'] = page_query.pages
            query = page_query.items
        else:
            query = protocols_query.distinct().order_by(
                Protocol.created_on.desc())

        results['protocols'] = [
            versioned_row_to_dict(api, protocol, protocol.current)
            for protocol in query
            if check_access(path=f"/protocol/{str(protocol.id)}", method="GET")
            and protocol and protocol.current
        ]
        return results