SMART-FHIR Capability & .well-known statement (#4090)
commit7532af23b66bd02ca3717bf0a59ce571aad0b8b9
authorStephen Nielson <stephen@nielson.org>
Wed, 23 Dec 2020 01:23:16 +0000 (22 20:23 -0500)
committerGitHub <noreply@github.com>
Wed, 23 Dec 2020 01:23:16 +0000 (22 20:23 -0500)
treeee5386e621660d33b4ec2da25c839ab586800dcd
parentc772779b230ff0eea8db2c233cfebaa487d9b194
SMART-FHIR Capability & .well-known statement (#4090)

* SMART-FHIR Capability & .well-known statement

SMART requires both the FHIR capability statement and a
.well-known/smart-configuration url to be provided at the root of the
FHIR server.  Implemented this requirement as well as providing the
baseline capabilities that ONC requires for the SMART FHIR.

Implemented the mapping from the capability statement's
read/insert/update statements onto SMART scopes scopes that can be requested
by the SMART app.

* Fixing checkstyle issues.

* SMART launch/patient scope, CORS enabled, logging

Bunch of work to enable the standalone SMART app launch with the
launch/patient scope for SMART.

This replaces the current IdTokenResponse class used in the oauth2
authentication process with an IdTokenSMARTResponse which will be
able to add on context dependent data that is sent back to the client
parallel to the accessToken and idToken. Right now it just grabs
the very first patient available in the system.  It needs to be
wired up so that a provider gets a patient selector or when a
patient logs in it sends that patient information as part of
the external app launch

This also enables CORS support for the browser based oauth2 requests
and sets the OPTIONS requests to bypass any token validation / support.

Implemented a PSR3 logger which wraps around the Monolog logger package.
Wrote a Decorator/Adapter class around the Monolog logger so the system
isn't tightly coupled to Monolog and we can replace it if its ever
needed.

The logging needs to be tied to somekind of global config so we can
decide the log level as needed.  These logs are currently NOT intended
for system level auditing, but writes directly to the error log.
Anything higher than the currently set system log level is treated like
a noop.

The logging helped immensely in tracking down OAUTH2 problems.

* SMART-FHIR Capability & .well-known statement

SMART requires both the FHIR capability statement and a
.well-known/smart-configuration url to be provided at the root of the
FHIR server.  Implemented this requirement as well as providing the
baseline capabilities that ONC requires for the SMART FHIR.

Implemented the mapping from the capability statement's
read/insert/update statements onto SMART scopes scopes that can be requested
by the SMART app.

* Fixing checkstyle issues.

* SMART launch/patient scope, CORS enabled, logging

Bunch of work to enable the standalone SMART app launch with the
launch/patient scope for SMART.

This replaces the current IdTokenResponse class used in the oauth2
authentication process with an IdTokenSMARTResponse which will be
able to add on context dependent data that is sent back to the client
parallel to the accessToken and idToken. Right now it just grabs
the very first patient available in the system.  It needs to be
wired up so that a provider gets a patient selector or when a
patient logs in it sends that patient information as part of
the external app launch

This also enables CORS support for the browser based oauth2 requests
and sets the OPTIONS requests to bypass any token validation / support.

Implemented a PSR3 logger which wraps around the Monolog logger package.
Wrote a Decorator/Adapter class around the Monolog logger so the system
isn't tightly coupled to Monolog and we can replace it if its ever
needed.

The logging needs to be tied to somekind of global config so we can
decide the log level as needed.  These logs are currently NOT intended
for system level auditing, but writes directly to the error log.
Anything higher than the currently set system log level is treated like
a noop.

The logging helped immensely in tracking down OAUTH2 problems.

* Fix wierd merge bug.

Had a wierd merge bug that redeclared a variable.  Should be fixed now.

* Fix PHP7.4, PHP8 broken tests cases.

* Support patch.

* Remove PATCH, fix styles.

Hopefully this fixes all the style problems

* Fix style issues, add log escapes.

Figured out why the case statements weren't working.  The style
checker doesn't like compound brace statements under a case statement.

Refactored the SystemLogger to escape all context variables.  Any
variable needing to be escaped should be put in as a context variable.

* Fix php error.

* Populate Patient id context from session.

* Insertion point for SMART app launch on demographics

* SMART EHR launch context support

Implemented the 'launch' SMART Core Context for in EHR launching with a patient selected.

Added a display of the registered SMART apps as part of the patient demographics.  Right now
this is a placeholder of where we can put it to generate ideas of what we can do to display
the SMART apps.  It filters out from the registered client applications ONLY those that
have registered as a SMART application by providing the 'launch' scope as part of their
initial registration.

It assumes that the registered app has a 'launch.html' file which appears to be pretty widespread
standard.  However, we may need to add a redirect_launch_uri or something.  The spec is vague and
needs to be dug into a bit to see if there is a standard, or if there's an industry best practice
here.

* SMART Core Capability context_style,context_banner

Implemented the two smart core capabilities for the banner and context
style.

Created a basic developer app registration.  Right now it registers
everything as a smart app, will need to provide developers the option of
specifying what permissions they need.  Currently it directly enables
the developer apps, but an admin panel will need to be setup to
enable/disable the dynamic registration for the developer apps.
After a registration is successful the client id is returned to the
registrant.

Implemented pulling up the SMART app in a dialog from the patient
demographics page.

You can test this out by running a modified version of the Growth Charts
open source app hosted at https://adunsulag.github.io/growth-chart-app/

Register a client with the redirect_uri to be:
https://adunsulag.github.io/growth-chart-app/

and the logout uri to be https://adunsulag.github.io/growth-chart-app/logout

Open a patient and at the bottom of the demographics you will now have a
Launch App button.  Launch the app and enter in the Client ID from your
registration process.

If you need to clear the client_id for testing you can do so at
https://adunsulag.github.io/growth-chart-app/deregister.html

* Fix styles

* Cleanup Capability and remove Rest quickfix.

Removed the quickfix on the rest controller helper that I put in until
Jerry's fix was in.

Cleaned up the capability statement here.

* Fix code review requests.

Fixed copyright notices, security escapes, and other stuff.

* Change up the issuer url to be consistent.

* Missing copyright header

* Fix style issue on test file.

Co-authored-by: Stephen Nielson <snielson@discoverandchange.com>
28 files changed:
_rest_config.php
_rest_routes.inc.php
apis/dispatch.php
composer.json
composer.lock
interface/patient_file/summary/demographics.php
interface/smart/register-app.php [new file with mode: 0644]
library/dialog.js
oauth2/authorize.php
public/smart-styles/smart-light.json [new file with mode: 0644]
src/Common/Auth/OpenIDConnect/Entities/ClientEntity.php
src/Common/Auth/OpenIDConnect/IdTokenSMARTResponse.php [new file with mode: 0644]
src/Common/Auth/OpenIDConnect/Repositories/ClientRepository.php
src/Common/Auth/OpenIDConnect/Repositories/ScopeRepository.php
src/Common/Http/HttpRestRouteHandler.php
src/Common/Logging/SystemLogger.php [new file with mode: 0644]
src/Events/PatientDemographics/RenderEvent.php [new file with mode: 0644]
src/FHIR/SMART/Capability.php [new file with mode: 0644]
src/FHIR/SMART/SMARTLaunchToken.php [new file with mode: 0644]
src/FHIR/SMART/SmartLaunchController.php [new file with mode: 0644]
src/RestControllers/AuthorizationController.php
src/RestControllers/FHIR/FhirMetaDataRestController.php
src/RestControllers/SMART/SMARTConfigurationController.php [new file with mode: 0644]
src/Services/PatientService.php
tests/Tests/Api/CapabilityFhirTest.php
tests/Tests/Api/SmartConfigurationTest.php [copied from tests/Tests/Api/CapabilityFhirTest.php with 58% similarity]
tests/Tests/Unit/Common/Auth/OpenIDConnect/Entities/ClientEntityTest.php [new file with mode: 0644]
tests/Tests/Unit/FHIR/SMART/SMARTLaunchTokenTest.php [new file with mode: 0644]