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

Add Rest API metadata event. Added swagger doc #4817

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
4 changes: 4 additions & 0 deletions FHIR_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ _Example:_ `https://localhost:9300/apis/default/fhir/Patient` returns a Patient'

The Bearer token is required for each OpenEMR FHIR request (except for the Capability Statement), and is conveyed using an Authorization header. Note that the Bearer token is the access_token that is obtained in the [Authorization](API_README.md#authorization) section.

When registering an API client to use with Swagger the following for the redirect url and launch url for the client.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor typo but could add "enter the following ..."

- Redirect URL -> <base_site_address>/swagger/oauth2-redirect.html
- Launch URL -> <base_site_address>/swagger/index.html

Request:

```sh
Expand Down
63 changes: 63 additions & 0 deletions src/Events/RestApiExtend/RestApiResourceServiceEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace OpenEMR\Events\RestApiExtend;

class RestApiResourceServiceEvent
{
/**
* Used whenever the service for a rest api resource needs to be returned for metadata or other kind of resource purposes
*/
const EVENT_HANDLE = 'restapi.service.get';

/**
* @var string The API resource that we need to locate a service for
*/
private $resource;

/**
* @var string The original system resource for service
*/
private $serviceClass;

public function __construct($resource, $serviceClass)
{
$this->resource = $resource;
$this->serviceClass = $serviceClass;
}

/**
* @return string
*/
public function getResource(): string
{
return $this->resource;
}

/**
* @param string $resource
* @return RestApiResourceServiceEvent
*/
public function setResource(string $resource): RestApiResourceServiceEvent
{
$this->resource = $resource;
return $this;
}

/**
* @return string
*/
public function getServiceClass(): ?string
{
return $this->serviceClass;
}

/**
* @param string $serviceClass
* @return RestApiResourceServiceEvent
*/
public function setServiceClass(?string $serviceClass): RestApiResourceServiceEvent
{
$this->serviceClass = $serviceClass;
return $this;
}
}
6 changes: 5 additions & 1 deletion src/RestControllers/AuthorizationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,11 @@ public function oauthAuthorizationFlow(): void
} catch (OAuthServerException $exception) {
$this->logger->error(
"AuthorizationController->oauthAuthorizationFlow() OAuthServerException",
["hint" => $exception->getHint(), "message" => $exception->getMessage(), 'hint' => $exception->getHint(), 'trace' => $exception->getTraceAsString()]
["hint" => $exception->getHint(), "message" => $exception->getMessage()
, 'payload' => $exception->getPayload()
, 'trace' => $exception->getTraceAsString()
, 'redirectUri' => $exception->getRedirectUri()
, 'errorType' => $exception->getErrorType()]
);
SessionUtil::oauthSessionCookieDestroy();
$this->emitResponse($exception->generateHttpResponse($response));
Expand Down
23 changes: 23 additions & 0 deletions src/RestControllers/RestControllerHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
namespace OpenEMR\RestControllers;

use OpenEMR\Common\Logging\SystemLogger;
use OpenEMR\Events\RestApiExtend\RestApiCreateEvent;
use OpenEMR\Events\RestApiExtend\RestApiResourceServiceEvent;
use OpenEMR\Events\RestApiExtend\RestApiScopeEvent;
use OpenEMR\Services\FHIR\IResourceSearchableService;
use OpenEMR\Services\Search\FhirSearchParameterDefinition;
use OpenEMR\Services\Search\SearchFieldType;
Expand Down Expand Up @@ -309,9 +312,11 @@ public function getCapabilityRESTObject($routes, $serviceClassNameSpace = self::
if (!in_array($resource, self::IGNORE_ENDPOINT_RESOURCES)) {
$service = null;
$serviceClass = $this->getFullyQualifiedServiceClassForResource($resource, $serviceClassNameSpace);
$serviceClass = self::filterServiceClassForResource($resource, $serviceClass);
if (!empty($serviceClass)) {
$service = new $serviceClass();
}

if (!array_key_exists($resource, $resourcesHash)) {
$capResource = new FHIRCapabilityStatementResource();
$capResource->setType(new FHIRCode($resource));
Expand All @@ -336,4 +341,22 @@ public function getCapabilityRESTObject($routes, $serviceClassNameSpace = self::
}
return $restItem;
}

/**
* Fires off a system event for the given API resource to filter the serviceClass. This gives module writers
* the opportunity to extend the api, add / remove Implementation Guide profiles and declare different API conformance
* @param $resource The api resource that was parsed
* @param $serviceClass The service class that was found by default in the system or null if none was found
* @return string|null The filtered service class property
*/
private static function filterServiceClassForResource(string $resource, ?string $serviceClass)
{
if (!empty($GLOBALS['kernel'])) {
$dispatcher = $GLOBALS['kernel']->getEventDispatcher();
$event = $dispatcher->dispatch(new RestApiResourceServiceEvent($resource, $serviceClass), RestApiResourceServiceEvent::EVENT_HANDLE);
return $event->getServiceClass();
}

return $serviceClass;
}
}