7 * @link http://www.open-emr.org
8 * @author Matthew Vita <matthewvita48@gmail.com>
9 * @author Jerry Padgett <sjpadgett@gmail.com>
10 * @author Brady Miller <brady.g.miller@gmail.com>
11 * @copyright Copyright (c) 2018 Matthew Vita <matthewvita48@gmail.com>
12 * @copyright Copyright (c) 2018 Jerry Padgett <sjpadgett@gmail.com>
13 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
14 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
17 require_once("./../_rest_config.php");
19 $gbl = RestConfig
::GetInstance();
20 $base_path = $gbl::$ROOT_URL;
24 // Parse needed information from Redirect or REQUEST_URI
25 if (!empty($_REQUEST['_REWRITE_COMMAND'])) {
26 $resource = "/" . $_REQUEST['_REWRITE_COMMAND'];
27 } elseif (!empty($_SERVER['REDIRECT_QUERY_STRING'])) {
28 $resource = str_replace('_REWRITE_COMMAND=', '/', $_SERVER['REDIRECT_QUERY_STRING']);
30 if (!empty($_SERVER['REQUEST_URI'])) {
31 if (strpos($_SERVER['REQUEST_URI'], '?') > 0) {
32 $resource = strstr($_SERVER['REQUEST_URI'], '?', true);
34 $resource = str_replace("$base_path", '', $_SERVER['REQUEST_URI']);
38 $GLOBALS['resource'] = $resource;
40 if (!empty($_SERVER['HTTP_APICSRFTOKEN'])) {
41 // Calling api from within the same session (ie. isLocalApi) since a apicsrftoken header was passed
45 } elseif ($gbl::is_authentication($resource)) {
46 // Get a site id from initial login authentication.
48 $data = (array) $gbl::getPostData((file_get_contents("php://input")));
49 $site = empty($data['scope']) ?
"default" : $data['scope'];
50 $_GET['site'] = $site;
54 $token = $gbl::get_bearer_token();
55 $token_decoded = base64_decode($token, true);
56 if (!empty($token_decoded)) {
57 $tokenParts = json_decode($token_decoded, true);
61 // token needs to have be an array and have something, api needs to be 4 characters, site id needs to be something.
63 (is_array($tokenParts)) &&
64 (!empty($tokenParts)) &&
65 (!empty($tokenParts['token'])) &&
66 (!empty($tokenParts['api'])) &&
67 (strlen($tokenParts['api']) == 4) &&
68 (!empty($tokenParts['site_id']))
70 $gbl::verify_api_request($resource, $tokenParts['api']);
71 $_SERVER["HTTP_X_API_TOKEN"] = $tokenParts['token']; // set token to further the adventure.
72 $_GET['site'] = $tokenParts['site_id']; // site id
75 // something not right, so exit
76 http_response_code(401);
80 $GLOBALS['is_local_api'] = $isLocalApi;
82 // Set $sessionAllowWrite to true here for following reasons:
83 // 1. !$isLocalApi - in this case setting sessions far downstream and no benefit to set to false since single process
84 // 2. $isLocalApi - in this case, basically setting this to true downstream after some session sets via session_write_close() call
85 $sessionAllowWrite = true;
86 require_once("./../interface/globals.php");
88 use OpenEMR\Common\Csrf\CsrfUtils
;
89 use OpenEMR\Common\Http\HttpRestRouteHandler
;
90 use OpenEMR\Events\RestApiExtend\RestApiCreateEvent
;
93 //Extend API using RestApiCreateEvent
94 $restApiCreateEvent = new RestApiCreateEvent($gbl::$ROUTE_MAP, $gbl::$FHIR_ROUTE_MAP, $gbl::$PORTAL_ROUTE_MAP, $gbl::$PORTAL_FHIR_ROUTE_MAP);
95 $restApiCreateEvent = $GLOBALS["kernel"]->getEventDispatcher()->dispatch(RestApiCreateEvent
::EVENT_HANDLE
, $restApiCreateEvent, 10);
96 $gbl::$ROUTE_MAP = $restApiCreateEvent->getRouteMap();
97 $gbl::$FHIR_ROUTE_MAP = $restApiCreateEvent->getFHIRRouteMap();
98 $gbl::$PORTAL_ROUTE_MAP = $restApiCreateEvent->getPortalRouteMap();
99 $gbl::$PORTAL_FHIR_ROUTE_MAP = $restApiCreateEvent->getPortalFHIRRouteMap();
102 // need to check for csrf match when using api locally
105 if (empty($_SERVER['HTTP_APICSRFTOKEN'])) {
106 error_log("OpenEMR Error: internal api failed because csrf token not received");
110 if ((!$csrfFail) && (!CsrfUtils
::verifyCsrfToken($_SERVER['HTTP_APICSRFTOKEN'], 'api'))) {
111 error_log("OpenEMR Error: internal api failed because csrf token did not match");
116 http_response_code(401);
121 // api flag must be four chars
122 // Pass only routes for current api.
123 // Also check to ensure route is turned on in globals
124 if ($gbl::is_fhir_request($resource)) {
125 if (!$GLOBALS['rest_fhir_api'] && !$isLocalApi) {
126 // if the external fhir api is turned off and this is not a local api call, then exit
127 http_response_code(501);
130 $_SESSION['api'] = 'fhir';
131 $routes = $gbl::$FHIR_ROUTE_MAP;
132 } elseif ($gbl::is_portal_request($resource)) {
133 if (!$GLOBALS['rest_portal_api'] && !$isLocalApi) {
134 // if the external portal api is turned off and this is not a local api call, then exit
135 http_response_code(501);
138 $_SESSION['api'] = 'port';
139 $routes = $gbl::$PORTAL_ROUTE_MAP;
140 } elseif ($gbl::is_portal_fhir_request($resource)) {
141 if (!$GLOBALS['rest_portal_fhir_api'] && !$isLocalApi) {
142 // if the external portal fhir api is turned off and this is not a local api call, then exit
143 http_response_code(501);
146 $_SESSION['api'] = 'pofh';
147 $routes = $gbl::$PORTAL_FHIR_ROUTE_MAP;
148 } elseif ($gbl::is_api_request($resource)) {
149 if (!$GLOBALS['rest_api'] && !$isLocalApi) {
150 // if the external api is turned off and this is not a local api call, then exit
151 http_response_code(501);
154 $_SESSION['api'] = 'oemr';
155 $routes = $gbl::$ROUTE_MAP;
157 // somebody is up to no good
158 http_response_code(501);
163 // Ensure that a local process does not hold up other processes
164 // Note can not do this for !$isLocalApi since need to be able to set
165 // session variables and it won't help performance anyways.
166 session_write_close();
170 $gbl::authentication_check($resource);
172 // dispatch $routes called by ref.
173 $hasRoute = HttpRestRouteHandler
::dispatch($routes, $resource, $_SERVER["REQUEST_METHOD"]);
174 // Tear down session for security.
176 $gbl::destroySession();
178 // prevent 200 if route doesn't exist
180 http_response_code(404);