Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openemr inferno fixes for #5827 #5828 #5829 #5830 #5831 #5833 #5834 #5836

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ This is a listing of scopes:
- `api:fhir` (fhir which are the /fhir/ endpoints)
- `patient/AllergyIntolerance.read`
- `patient/Appointment.read`
- `patient/Binary.read`
- `patient/CarePlan.read`
- `patient/CareTeam.read`
- `patient/Condition.read`
- `patient/Coverage.read`
- `patient/Device.read`
- `patient/DiagnosticReport.read`
- `patient/Document.read`
- `patient/DocumentReference.read`
- `patient/DocumentReference.$docref`
- `patient/Encounter.read`
Expand All @@ -90,13 +90,13 @@ This is a listing of scopes:
- `patient/Procedure.read`
- `patient/Provenance.read`
- `system/AllergyIntolerance.read`
- `system/Binary.read`
- `system/CarePlan.read`
- `system/CareTeam.read`
- `system/Condition.read`
- `system/Coverage.read`
- `system/Device.read`
- `system/DiagnosticReport.read`
- `system/Document.read`
- `system/DocumentReference.read`
- `system/DocumentReference.$docref`
- `system/Encounter.read`
Expand All @@ -119,13 +119,13 @@ This is a listing of scopes:
- `system/*.$bulkdata-status`
- `system/*.$export`
- `user/AllergyIntolerance.read`
- `user/Binary.read`
- `user/CarePlan.read`
- `user/CareTeam.read`
- `user/Condition.read`
- `user/Coverage.read`
- `user/Device.read`
- `user/DiagnosticReport.read`
- `user/Document.read`
- `user/DocumentReference.read`
- `user/DocumentReference.$docref`
- `user/Encounter.read`
Expand Down
16 changes: 8 additions & 8 deletions FHIR_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ A status Query will return a result like the following:
"requiresAccessToken": true,
"output": [
{
"url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/97552\/Binary",
"url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Binary\/97552",
"type": "Patient"
},
{
"url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/105232\/Binary",
"url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Binary\/105232",
"type": "Encounter"
}
],
Expand All @@ -145,15 +145,15 @@ A status Query will return a result like the following:

You can download the exported documents which are formatted in Newline Delimited JSON (NDJSON) by making a call to:
```sh
curl -X GET 'https://localhost:9300/apis/default/fhir/Document/105232/Binary'
curl -X GET 'https://localhost:9300/apis/default/fhir/Binary/105232'
```

In order to download the documents you will need the **system/Document.read** scope.
In order to download the documents you will need the **system/Binary.read** scope.

#### Bulk FHIR Scope Reference
- All System export - **system/\*.$export system\*.$bulkdata-status system/Document.read**
- Group System export - **system/Group.$export system\*.$bulkdata-status system/Document.read**
- Patient System export - **system/Patient.$export system\*.$bulkdata-status system/Document.read**
- All System export - **system/\*.$export system\*.$bulkdata-status system/Binary.read**
- Group System export - **system/Group.$export system\*.$bulkdata-status system/Binary.read**
- Patient System export - **system/Patient.$export system\*.$bulkdata-status system/Binary.read**

####
## 3rd Party SMART Apps
Expand Down Expand Up @@ -205,7 +205,7 @@ It is recommended that native applications follow best practices for native clie
### Generate CCDA
- [Tutorial to Generate CCDA (with Screenshots)](https://github.com/openemr/openemr/issues/5284#issuecomment-1155678620)
### Details Docref
- Requires <context>/DocumentReference.$docref, <context>/DocumentReference.read, and <context>/Document.read scopes
- Requires <context>/DocumentReference.$docref, <context>/DocumentReference.read, and <context>/Binary.read scopes
- Start and end date filter encounter related events for the following sections:
- History of Procedures
- Relevant DX Tests / LAB Data
Expand Down
10 changes: 8 additions & 2 deletions _rest_config.php
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,15 @@ public static function skipApiAuth($resource): bool
exit();
}
// let the capability statement for FHIR or the SMART-on-FHIR through
$resource = str_replace('/' . self::$SITE, '', $resource);
if (
$resource === ("/" . self::$SITE . "/fhir/metadata") ||
$resource === ("/" . self::$SITE . "/fhir/.well-known/smart-configuration")
// TODO: @adunsulag we need to centralize our auth skipping logic... as we have this duplicated in HttpRestRouteHandler
// however, at the point of this method we don't have the resource identified and haven't gone through our parsing
// routine to handle that logic...
$resource === ("/fhir/metadata") ||
$resource === ("/fhir/.well-known/smart-configuration") ||
// skip list and single instance routes
0 === strpos("/fhir/OperationDefinition", $resource)
) {
return true;
} else {
Expand Down
125 changes: 110 additions & 15 deletions _rest_routes.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
* "api:fhir": "FHIR R4 API",
* "patient/AllergyIntolerance.read": "Read allergy intolerance resources for the current patient (api:fhir)",
* "patient/Appointment.read": "Read appointment resources for the current patient (api:fhir)",
* "patient/Binary.read": "Read binary document resources for the current patient (api:fhir)",
* "patient/CarePlan.read": "Read care plan resources for the current patient (api:fhir)",
* "patient/CareTeam.read": "Read care team resources for the current patient (api:fhir)",
* "patient/Condition.read": "Read condition resources for the current patient (api:fhir)",
* "patient/Coverage.read": "Read coverage resources for the current patient (api:fhir)",
* "patient/Device.read": "Read device resources for the current patient (api:fhir)",
* "patient/DiagnosticReport.read": "Read diagnostic report resources for the current patient (api:fhir)",
* "patient/Document.read": "Read document resources for the current patient (api:fhir)",
* "patient/DocumentReference.read": "Read document reference resources for the current patient (api:fhir)",
* "patient/DocumentReference.$docref" : "Generate a document for the current patient or returns the most current Clinical Summary of Care Document (CCD)",
* "patient/Encounter.read": "Read encounter resources for the current patient (api:fhir)",
Expand All @@ -58,13 +58,13 @@
* "patient/Procedure.read": "Read procedure resources for the current patient (api:fhir)",
* "patient/Provenance.read": "Read provenance resources for the current patient (api:fhir)",
* "system/AllergyIntolerance.read": "Read all allergy intolerance resources in the system (api:fhir)",
* "system/Binary.read": "Read all binary document resources in the system (api:fhir)",
* "system/CarePlan.read": "Read all care plan resources in the system (api:fhir)",
* "system/CareTeam.read": "Read all care team resources in the system (api:fhir)",
* "system/Condition.read": "Read all condition resources in the system (api:fhir)",
* "system/Coverage.read": "Read all coverage resources in the system (api:fhir)",
* "system/Device.read": "Read all device resources in the system (api:fhir)",
* "system/DiagnosticReport.read": "Read all diagnostic report resources in the system (api:fhir)",
* "system/Document.read": "Read all document resources in the system (api:fhir)",
* "system/DocumentReference.read": "Read all document reference resources in the system (api:fhir)",
* "system/DocumentReference.$docref" : "Generate a document for any patient in the system or returns the most current Clinical Summary of Care Document (CCD)",
* "system/Encounter.read": "Read all encounter resources in the system (api:fhir)",
Expand All @@ -83,13 +83,13 @@
* "system/Procedure.read": "Read all procedure resources in the system (api:fhir)",
* "system/Provenance.read": "Read all provenance resources in the system (api:fhir)",
* "user/AllergyIntolerance.read": "Read all allergy intolerance resources the user has access to (api:fhir)",
* "user/Binary.read" : "Read all binary documents the user has access to (api:fhir)",
* "user/CarePlan.read": "Read all care plan resources the user has access to (api:fhir)",
* "user/CareTeam.read": "Read all care team resources the user has access to (api:fhir)",
* "user/Condition.read": "Read all condition resources the user has access to (api:fhir)",
* "user/Coverage.read": "Read all coverage resources the user has access to (api:fhir)",
* "user/Device.read": "Read all device resources the user has access to (api:fhir)",
* "user/DiagnosticReport.read": "Read all diagnostic report resources the user has access to (api:fhir)",
* "user/Document.read" : "Read all documents the user has access to (api:fhir)",
* "user/DocumentReference.read": "Read all document reference resources the user has access to (api:fhir)",
* "user/DocumentReference.$docref" : "Generate a document for any patient the user has access to or returns the most current Clinical Summary of Care Document (CCD) (api:fhir)",
* "user/Encounter.read": "Read all encounter resources the user has access to (api:fhir)",
Expand Down Expand Up @@ -7094,6 +7094,7 @@
use OpenEMR\RestControllers\FHIR\FhirMetaDataRestController;
use OpenEMR\RestControllers\FHIR\Operations\FhirOperationExportRestController;
use OpenEMR\RestControllers\FHIR\Operations\FhirOperationDocRefRestController;
use OpenEMR\RestControllers\FHIR\Operations\FhirOperationDefinitionRestController;

// Note that the fhir route includes both user role and patient role
// (there is a mechanism in place to ensure patient role is binded
Expand Down Expand Up @@ -8732,7 +8733,7 @@
* {
* "attachment": {
* "contentType": "image/gif",
* "url": "https://localhost:9300/apis/default/fhir/Document/7/Binary"
* "url": "https://localhost:9300/apis/default/fhir/Binary/7"
* },
* "format": {
* "system": "http://ihe.net/fhir/ValueSet/IHE.FormatCode.codesystem",
Expand Down Expand Up @@ -8775,7 +8776,7 @@

/**
* @OA\Get(
* path="/fhir/Document/{id}/Binary",
* path="/fhir/Binary/{id}",
* description="Used for downloading binary documents generated either with BULK FHIR Export or with the $docref CCD export operation. Documentation can be found at <a href='https://www.open-emr.org/wiki/index.php/OpenEMR_Wiki_Home_Page#API' target='_blank' rel='noopener'>https://www.open-emr.org/wiki/index.php/OpenEMR_Wiki_Home_Page#API</a>",
* tags={"fhir"},
* @OA\Parameter(
Expand All @@ -8802,15 +8803,16 @@
* security={{"openemr_auth":{}}}
* )
*/
'GET /fhir/Document/:id/Binary' => function ($documentId, HttpRestRequest $request) {
// TODO: @adunsulag we need to be able to retrieve our CCDA documents this way...
// currently only allow users with the same permissions as export to take a file out
// this could be relaxed to allow other types of files ie such as patient access etc.
RestConfig::authorization_check("admin", "users");

// Grab the document id
'GET /fhir/Binary/:id' => function ($documentId, HttpRestRequest $request) {
$docController = new \OpenEMR\RestControllers\FHIR\FhirDocumentRestController($request);
$response = $docController->downloadDocument($documentId);

if ($request->isPatientRequest()) {
$response = $docController->downloadDocument($documentId, $request->getPatientUUIDString());
} else {
RestConfig::authorization_check("admin", "users");
$response = $docController->downloadDocument($documentId);
}

return $response;
},

Expand Down Expand Up @@ -11584,8 +11586,20 @@
* )
*/
"GET /fhir/Person/:uuid" => function ($uuid, HttpRestRequest $request) {
RestConfig::authorization_check("admin", "users");
$return = (new FhirPersonRestController())->getOne($uuid);
// if the api user is requesting their own user we need to let it through
// this is because the /Person endpoint needs to be responsive to the fhirUser return value
// for the currently logged in user
if ($request->getRequestUserUUIDString() == $uuid) {
$return = (new FhirPersonRestController())->getOne($uuid);
} else if (!$request->isPatientRequest()) {
// not a patient ,make sure we have access to the users ACL
RestConfig::authorization_check("admin", "users");
$return = (new FhirPersonRestController())->getOne($uuid);
} else {
// if we are a patient bound request we need to make sure we are only bound to the patient
$return = (new FhirPersonRestController())->getOne($uuid, $request->getPatientUUIDString());
}

RestConfig::apiLog($return);
return $return;
},
Expand Down Expand Up @@ -12541,6 +12555,87 @@
return $return;
},

/**
* @OA\Get(
* path="/fhir/OperationDefinition",
* description="Returns a list of the OperationDefinition resources that are specific to this OpenEMR installation",
* tags={"fhir"},
* @OA\Response(
* response="200",
* description="Return list of OperationDefinition resources"
* )
* )
*/
"GET /fhir/OperationDefinition" => function (HttpRestRequest $request) {
// for now we will just hard code the custom resources
$operationDefinitionController = new FhirOperationDefinitionRestController();
$return = $operationDefinitionController->getAll($request->getQueryParams());
RestConfig::apiLog($return);
return $return;
},

/**
* @OA\Get(
* path="/fhir/OperationDefinition/{operation}",
* description="Returns a single OperationDefinition resource that is specific to this OpenEMR installation",
* tags={"fhir"},
* @OA\Parameter(
* name="operation",
* in="path",
* description="The name of the operation to query. For example $bulkdata-status",
* required=true,
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Response(
* response="200",
* description="Standard Response",
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="json object",
* description="FHIR Json object.",
* type="object"
* ),
* example={
* "resourceType": "OperationDefinition",
* "name": "$bulkdata-status",
* "status": "active",
* "kind": "operation",
* "parameter": {
* {
* "name": "job",
* "use": "in",
* "min": 1,
* "max": 1,
* "type": {
* "system": "http://hl7.org/fhir/data-types",
* "code": "string",
* "display": "string"
* },
* "searchType": {
* "system": "http://hl7.org/fhir/ValueSet/search-param-type",
* "code": "string",
* "display": "string"
* }
* }
* }
* }
* )
* )
* ),
* )
*/
"GET /fhir/OperationDefinition/:operation" => function ($operation, HttpRestRequest $request) {
// for now we will just hard code the custom resources
$operationDefinitionController = new FhirOperationDefinitionRestController();
$return = $operationDefinitionController->getOne($operation);
RestConfig::apiLog($return);
return $return;
},

// FHIR root level operations

/**
Expand Down
Loading