async def get_ehr_by_id(conn, client_key, ehr_id):
    client = await get_client(conn, client_key)
    ehr_list = {}
    if Permission(type=Permission.READ_PATIENT_DATA) in client.permissions:
        # ehr_list_address = ehr_helper.make_ehr_list_address()
        ehr_address = ehr_helper.make_ehr_address(ehr_id)
        LOGGER.debug('has READ_PATIENT_DATA permission: ' + str(client_key))
        # Get Consent
        access = await get_data_processing_access(conn, client_key)
        patient_list = {}
        for address, pt in access.items():
            LOGGER.debug('patient access: ' + str(pt))
            patient = await get_patient(conn, pt.src_pkey)
            patient_list[pt.src_pkey] = patient
        #
        ehr_resources = await messaging.get_state_by_address(conn, ehr_address)
        for entity in ehr_resources.entries:
            cl = EHRWithUser()
            cl.ParseFromString(entity.data)

            ehr_list[entity.address] = cl
            LOGGER.debug('ehr: ' + str(cl))
        # Apply Consent
        for patient_address, pt in patient_list.items():
            LOGGER.debug('patient: ' + str(pt))
            for claim_address, e in ehr_list.items():
                LOGGER.debug('ehr: ' + str(e))
                if patient_address == e.client_pkey:
                    LOGGER.debug('match!')
                    pt_local = patient_list[patient_address]
                    e.name = pt_local.name
                    e.surname = pt_local.surname
                    ehr_list[claim_address] = e
        if not ehr_list:
            raise ApiForbidden("Cat not get EHR having '" + str(ehr_id) + "' id")
        return list(ehr_list.values())[0]
    elif Permission(type=Permission.READ_OWN_PATIENT_DATA) in client.permissions:
        # ehr_list_ids_address = ehr_helper.make_ehr_list_by_patient_address(client_key)
        LOGGER.debug('has READ_OWN_PATIENT_DATA permission: ' + str(client_key))
        # ehr_list_ids = await messaging.get_state_by_address(conn, ehr_list_ids_address)
        # for entity in ehr_list_ids.entries:
        #     ehr_id = entity.data.decode()
        ehr_address = ehr_helper.make_ehr_address(ehr_id)
        LOGGER.debug('get ehr: ' + str(ehr_address))
        ehr_resources = await messaging.get_state_by_address(conn, ehr_address)
        for entity in ehr_resources.entries:
            LOGGER.debug('get ehr entity: ' + str(entity.address))
            e = EHRWithUser()
            e.ParseFromString(entity.data)
            ehr_list[entity.address] = e
        if not ehr_list:
            raise ApiForbidden("Cat not get EHR having '" + str(ehr_id) + "' id")
        return list(ehr_list.values())[0]
    else:
        LOGGER.debug('neither READ_PATIENT_DATA nor READ_OWN_PATIENT_DATA permissions')
    raise ApiForbidden("Insufficient permission")
async def get_consent_request_list(conn, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.GET_REQUESTS_LIST) in client.permissions:
        LOGGER.debug('has GET_REQUESTS_LIST permission: ' + str(client_key))
        consent_request_list = await get_consent_request(conn, client_key)
        return consent_request_list
    raise ApiForbidden("Insufficient permission")
async def get_inform_consent_request_list(conn, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.READ_INFORM_CONSENT_REQUEST) in client.permissions and \
            Permission(type=Permission.READ_SIGNED_INFORM_CONSENT) in client.permissions:
        LOGGER.debug('has READ_INFORM_CONSENT_REQUEST and READ_SIGNED_INFORM_CONSENT permission: ' + str(client_key))
        inform_consent_request_list = await get_inform_consent_request(conn, client_key)
        return inform_consent_request_list
    raise ApiForbidden("Insufficient permission")
async def revoke_investigator_access(conn, timeout, batches, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.REVOKE_INVESTIGATOR_ACCESS) in client.permissions:
        LOGGER.debug('has permission: True')
        await _send(conn, timeout, batches)
        return
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def import_screening_data(conn, timeout, batches, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.IMPORT_TRIAL_DATA) in client.permissions:
        LOGGER.debug('has IMPORT_TRIAL_DATA permission: True')
        await _send(conn, timeout, batches)
        return
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def decline_request(conn, timeout, batches, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.DECLINE_CONSENT) in client.permissions:
        LOGGER.debug('has permission: True')
        await _send(conn, timeout, batches)
        return
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def add_ehr(conn, timeout, batches, dest_pkey, src_pkey):
    client = await get_client(conn, dest_pkey)
    if Permission(type=Permission.WRITE_PATIENT_DATA) in client.permissions:
        LOGGER.debug('has WRITE_PATIENT_DATA permission: True')
        # Has consent from patient
        access = await has_data_processing_access(conn, dest_pkey, src_pkey)
        if not access:
            LOGGER.debug('no data processing access')
            raise ApiForbidden("Insufficient permission")
        #
        await _send(conn, timeout, batches)
        return
        # LOGGER.debug('has permission: True')
        # await _send(conn, timeout, batches)
        # return
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def sign_inform_document_consent(conn, timeout, batches, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.SIGN_INFORM_CONSENT) in client.permissions:
        LOGGER.debug('has permission: True')
        await _send(conn, timeout, batches)
        return
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def update_investigator(conn, timeout, batches, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.UPDATE_TRIAL_DATA) in client.permissions:
        LOGGER.debug('has UPDATE_TRIAL_DATA permission: True')
        await _send(conn, timeout, batches)
        return
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def revoke_data_processing(conn, timeout, batches, client_key):
    client = await get_client(conn, client_key)
    if Permission(type=Permission.REVOKE_READ_DATA_ACCESS) in client.permissions and \
            Permission(type=Permission.REVOKE_WRITE_DATA_ACCESS) in client.permissions:
        LOGGER.debug('has permission: True')
        await _send(conn, timeout, batches)
        return
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def get_pre_screening_data(conn, investigator_pkey, inc_excl_criteria):
    client = await get_client(conn, investigator_pkey)
    if Permission(type=Permission.READ_PATIENT_DATA) in client.permissions:
        ehr_list = await get_shared_ehrs(conn, investigator_pkey)
        ehr_screening_list = {}
        for address, ehr in ehr_list.items():
            if _match_incl_excl_criteria(ehr, inc_excl_criteria):
                ehr_screening_list[address] = ehr
        return ehr_screening_list
    else:
        LOGGER.debug('has permission: False')
    raise ApiForbidden("Insufficient permission")
async def get_patients(ehr_conn, consent_conn, client_key):
    client = await get_client(consent_conn, client_key)
    patient_list = {}
    if Permission(type=Permission.READ_PATIENT) in client.permissions:
        LOGGER.debug('has READ_PATIENT permission: ' + str(client_key))
        list_patient_address = ehr_helper.make_patient_list_address()
        # Get Data Processing Access
        data_processing_access = await get_data_processing_access(
            consent_conn, client_key)
        data_processing_access_list = {}
        for address, pt in data_processing_access.items():
            LOGGER.debug('data_processing_access: ' + str(pt))
            patient = await get_patient(ehr_conn, pt.src_pkey)
            data_processing_access_list[pt.src_pkey] = patient

        # consent = await get_read_ehr_consent(conn, client_key)
        # consent_list = {}
        # for address, pt in consent.items():
        #     LOGGER.debug('consent: ' + str(pt))
        #     patient = await get_patient(conn, pt.src_pkey)
        #     consent_list[pt.src_pkey] = patient
        #
        patient_list_resources = await messaging.get_state_by_address(
            ehr_conn, list_patient_address)
        for entity in patient_list_resources.entries:
            pat = Patient()
            pat.ParseFromString(entity.data)
            patient_list[entity.address] = pat
            LOGGER.debug('patient: ' + str(pat))
        # Apply Access
        for patient_address, pt in patient_list.items():
            LOGGER.debug('patient: ' + str(pt))
            if Permission(
                    type=Permission.READ_OWN_PATIENT
            ) in client.permissions and pt.public_key == client_key:
                pass
            elif pt.public_key not in data_processing_access_list:
                pat2 = Patient()
                patient_list[patient_address] = pat2
        return patient_list
    elif Permission(type=Permission.READ_OWN_PATIENT) in client.permissions:
        LOGGER.debug('has READ_OWN_PATIENT: ' + str(client_key))
        # Get Data Processing Access
        data_processing_access = await get_data_processing_access(
            consent_conn, client_key)
        data_processing_access_list = {}
        for address, pt in data_processing_access.items():
            LOGGER.debug('data_processing_access: ' + str(pt))
            patient = await get_patient(ehr_conn, pt.src_pkey)
            data_processing_access_list[pt.src_pkey] = patient
        return data_processing_access_list
    raise ApiForbidden("Insufficient permission")
async def get_hospitals(conn, client_key):
    client = await get_client(conn, client_key)
    hospital_list = {}
    if Permission(type=Permission.READ_HOSPITAL) in client.permissions:
        list_hospital_address = ehr_helper.make_hospital_list_address()
        list_hospital_resources = await messaging.get_state_by_address(conn, list_hospital_address)
        for entity in list_hospital_resources.entries:
            hp = Hospital()
            hp.ParseFromString(entity.data)
            LOGGER.debug('hospital: ' + str(hp))
            hospital_list[entity.address] = hp
        return hospital_list
    raise ApiForbidden("Insufficient permission")
async def get_consumers(conn, client_key):
    client = await get_client(conn, client_key)
    consumers_list = {}
    if Permission(type=Permission.GET_CONSUMERS_LIST) in client.permissions:
        list_consumer_address = data_helper.make_consumer_list_address()
        list_consumer_resources = await messaging.get_state_by_address(
            conn, list_consumer_address)
        for entity in list_consumer_resources.entries:
            cn = Consumer()
            cn.ParseFromString(entity.data)
            LOGGER.debug('consumer: ' + str(cn))
            consumers_list[entity.address] = cn
        return consumers_list
    raise ApiForbidden("Insufficient permission")
async def get_academics(conn, client_key):
    client = await get_client(conn, client_key)
    academic_list = {}
    if Permission(type=Permission.GET_ACADEMICS_LIST) in client.permissions:
        LOGGER.debug('has GET_ACADEMICS_LIST permission: ' + str(client_key))
        list_academic_address = data_helper.make_academic_list_address()
        # Get Data Processing Access
        # data_processing_access = await get_consent_by_consumer(consent_conn, client_key)
        # data_processing_access_list = {}
        # for address, pt in data_processing_access.items():
        #     LOGGER.debug('data_processing_access: ' + str(pt))
        #     patient = await get_patient(ehr_conn, pt.src_pkey)
        #     data_processing_access_list[pt.src_pkey] = patient

        # consent = await get_read_ehr_consent(conn, client_key)
        # consent_list = {}
        # for address, pt in consent.items():
        #     LOGGER.debug('consent: ' + str(pt))
        #     patient = await get_patient(conn, pt.src_pkey)
        #     consent_list[pt.src_pkey] = patient
        #
        academic_list_resources = await messaging.get_state_by_address(
            conn, list_academic_address)
        for entity in academic_list_resources.entries:
            ac = Academic()
            ac.ParseFromString(entity.data)
            academic_list[entity.address] = ac
            LOGGER.debug('academic: ' + str(ac))
        # Apply Access
        # for patient_address, pt in academic_list.items():
        #     LOGGER.debug('patient: ' + str(pt))
        #     if Permission(type=Permission.READ_OWN_PATIENT) in client.permissions and pt.public_key == client_key:
        #         pass
        #     elif pt.public_key not in data_processing_access_list:
        #         pat2 = Patient()
        #         patient_list[patient_address] = pat2
        return academic_list
    # elif Permission(type=Permission.READ_OWN_PATIENT) in client.permissions:
    #     LOGGER.debug('has READ_OWN_PATIENT: ' + str(client_key))
    #     # Get Data Processing Access
    #     data_processing_access = await get_consent_by_consumer(consent_conn, client_key)
    #     data_processing_access_list = {}
    #     for address, pt in data_processing_access.items():
    #         LOGGER.debug('data_processing_access: ' + str(pt))
    #         patient = await get_patient(ehr_conn, pt.src_pkey)
    #         data_processing_access_list[pt.src_pkey] = patient
    #     return data_processing_access_list
    raise ApiForbidden("Insufficient permission")
async def get_data_from_investigators(conn, client_key):
    client = await get_client(conn, client_key)
    data_list = {}
    if Permission(type=Permission.READ_TRIAL_DATA) in client.permissions:
        data_list_address = ehr_helper.make_investigator_data_list_address()
        LOGGER.debug('has READ_DATA permission: ' + str(client_key))
        data_list_resources = await messaging.get_state_by_address(conn, data_list_address)
        for entity in data_list_resources.entries:
            data = Data()
            data.ParseFromString(entity.data)
            data_list[entity.address] = data
            LOGGER.debug('data: ' + str(data))
        return data_list
    else:
        LOGGER.debug('no READ_DATA permissions')
    raise ApiForbidden("Insufficient permission")
def _match_incl_excl_criteria(data, inc_excl_criteria):
    for criteria, value in inc_excl_criteria.items():
        LOGGER.debug('_match_incl_excl_criteria -> criteria: ' + criteria + '; value: ' + value + ';')
        v = _get_int(value)
        if criteria == "excl_height_less":
            if _get_int(data.height) < v:
                return False
        elif criteria == "excl_height_more":
            if _get_int(data.height) > v:
                return False
        elif criteria == "incl_height_less":
            if _get_int(data.height) > v:
                return False
        elif criteria == "incl_height_more":
            if _get_int(data.height) < v:
                return False
        else:
            raise ApiForbidden("Invalid excl/incl criteria specified. "
                               "Only {excl_height_less,excl_height_more,incl_height_less,incl_height_more} allowed")
    return True
async def get_investigators(conn, client_key):
    client = await get_client(conn, client_key)
    investigator_list = {}
    if Permission(type=Permission.READ_INVESTIGATOR) in client.permissions:
        list_investigator_address = ehr_helper.make_investigator_list_address()
        list_investigator_resources = await messaging.get_state_by_address(conn, list_investigator_address)
        for entity in list_investigator_resources.entries:
            dp = Investigator()
            dp.ParseFromString(entity.data)
            LOGGER.debug('investigator: ' + str(dp))
            investigator_list[entity.address] = dp
        return investigator_list
    elif Permission(type=Permission.READ_OWN_INVESTIGATOR) in client.permissions:
        list_investigator_address = ehr_helper.make_investigator_address(client_key)
        list_investigator_resources = await messaging.get_state_by_address(conn, list_investigator_address)
        for entity in list_investigator_resources.entries:
            dp = Investigator()
            dp.ParseFromString(entity.data)
            LOGGER.debug('investigator: ' + str(dp))
            investigator_list[entity.address] = dp
        return investigator_list
    raise ApiForbidden("Insufficient permission")
Example #19
0
def get_request_key_header(request):
    if 'ClientKey' not in request.headers:
        raise ApiForbidden('Client key not specified')
    return request.headers['ClientKey']
async def get_data(conn, client_key):
    client = await get_client(conn, client_key)
    data_list = {}
    if Permission(type=Permission.READ_DATA) in client.permissions:
        LOGGER.debug('has READ_DATA permission: ' + str(client_key))
        # Get Consumers with Consent
        consumers_with_consent = await get_consent_by_consumer(
            conn, client_key)
        for address, cn in consumers_with_consent.items():
            LOGGER.debug('consumer with consent: ' + str(cn))

            data_id_list_address = data_helper.make_data_list_by_consumer_address(
                cn.src_pkey)
            data_id_list_resources = await messaging.get_state_by_address(
                conn, data_id_list_address)
            for entity in data_id_list_resources.entries:
                data_id = entity.data.decode()
                data_address = data_helper.make_data_address(data_id)
                LOGGER.debug('get data: ' + str(data_address))
                data_resources = await messaging.get_state_by_address(
                    conn, data_address)
                for entity2 in data_resources.entries:
                    entity_data_decode = entity2.data.decode()
                    LOGGER.debug('entity_data_decode: ' +
                                 str(entity_data_decode))
                    cde = ConsumerDataExt()
                    cde.ParseFromString(entity2.data)
                    LOGGER.debug('data: ' + str(cde))
                    data_list[entity2.address] = cde

        # data_list_resources = await messaging.get_state_by_address(conn, data_list_address)
        # for entity in data_list_resources.entries:
        #     cde = ConsumerDataExt()
        #     cde.ParseFromString(entity.data)
        #
        #     data_list[entity.address] = cde
        #     LOGGER.debug('data: ' + str(cde))
        # # Apply Consent
        # for patient_address, pt in patient_list.items():
        #     LOGGER.debug('patient: ' + str(pt))
        #     for claim_address, e in ehr_list.items():
        #         LOGGER.debug('ehr: ' + str(e))
        #         if patient_address == e.client_pkey:
        #             LOGGER.debug('match!')
        #             pt_local = patient_list[patient_address]
        #             e.name = pt_local.name
        #             e.surname = pt_local.surname
        #             ehr_list[claim_address] = e
        return data_list
    elif Permission(type=Permission.READ_OWN_DATA) in client.permissions:
        data_id_list_address = data_helper.make_data_list_by_consumer_address(
            client_key)
        LOGGER.debug('has READ_OWN_DATA permission: ' + str(client_key))
        data_id_list_resources = await messaging.get_state_by_address(
            conn, data_id_list_address)
        for entity in data_id_list_resources.entries:
            data_id = entity.data.decode()
            data_address = data_helper.make_data_address(data_id)
            LOGGER.debug('get data: ' + str(data_address))
            data_resources = await messaging.get_state_by_address(
                conn, data_address)
            for entity2 in data_resources.entries:
                entity_data_decode = entity2.data.decode()
                LOGGER.debug('entity_data_decode: ' + str(entity_data_decode))
                cde = ConsumerDataExt()
                cde.ParseFromString(entity2.data)
                LOGGER.debug('data: ' + str(cde))
                data_list[entity2.address] = cde
        return data_list
    # elif Permission(type=Permission.READ_OWN_PATIENT_DATA) in client.permissions:
    #     ehr_list_ids_address = ehr_helper.make_ehr_list_by_patient_address(client_key)
    #     LOGGER.debug('has READ_OWN_PATIENT_DATA permission: ' + str(ehr_list_ids_address))
    #     ehr_list_ids = await messaging.get_state_by_address(ehr_conn, ehr_list_ids_address)
    #     for entity in ehr_list_ids.entries:
    #         ehr_id = entity.data.decode()
    #         ehr_address = ehr_helper.make_ehr_address(ehr_id)
    #         LOGGER.debug('get ehr: ' + str(ehr_address))
    #         ehr_resources = await messaging.get_state_by_address(ehr_conn, ehr_address)
    #         for entity2 in ehr_resources.entries:
    #             LOGGER.debug('get ehr entity2: ' + str(entity2.address))
    #             e = EHRWithUser()
    #             e.ParseFromString(entity2.data)
    #             ehr_list[entity2.address] = e
    #     return ehr_list
    else:
        LOGGER.debug('neither READ_DATA permissions')
    raise ApiForbidden("Insufficient permission")