From ca906ec74c9c6b31db2663d6e2d95bd5db842183 Mon Sep 17 00:00:00 2001 From: Michael Miscampbell Date: Wed, 30 Jan 2019 10:16:58 +0000 Subject: [PATCH 1/4] Fix for issue with RestApiHandler not returning the response object created from the Middleware layer --- src/UrlHandlers/RestApiHandler.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/UrlHandlers/RestApiHandler.php b/src/UrlHandlers/RestApiHandler.php index e355092..ce658af 100644 --- a/src/UrlHandlers/RestApiHandler.php +++ b/src/UrlHandlers/RestApiHandler.php @@ -150,8 +150,13 @@ protected function generateResponseForRequest($request = null) } $payload = $endpoint->processRequest($matches, $request); - $response = new JsonResponse(); - $response->setContent($payload); + + if ($payload instanceof Response) { + $response = $payload; + } else { + $response = new JsonResponse(); + $response->setContent($payload); + } } catch (ResourceNotFoundException $er){ $response = new NotFoundResponse(); $response->setContent("The resource could not be located."); From a70f68e7c0ef43dc5d03f048627907f5718ea90f Mon Sep 17 00:00:00 2001 From: Michael Miscampbell Date: Wed, 30 Jan 2019 14:53:35 +0000 Subject: [PATCH 2/4] Agreed with Rob this resource and payload 'id' check is not required because any put request should specify the id to update in the url --- src/Adapters/ResourceAdapter.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Adapters/ResourceAdapter.php b/src/Adapters/ResourceAdapter.php index e0d9205..c657e5a 100644 --- a/src/Adapters/ResourceAdapter.php +++ b/src/Adapters/ResourceAdapter.php @@ -22,10 +22,6 @@ public function put($payload, $params, ?WebRequest $request) { $resource = $this->get($params, $request); - if ($resource->id != $payload["id"]){ - throw new ResourceNotFoundException(); - } - $this->putResource($payload); return $this->get($params, $request); From a3aea390001ffea4dac60dfa4e2264fcb1fdea95 Mon Sep 17 00:00:00 2001 From: Michael Miscampbell Date: Wed, 30 Jan 2019 16:47:22 +0000 Subject: [PATCH 3/4] Adding delete method to support the delete method from RestApiHandler --- src/Adapters/ModelResourceAdapter.php | 4 ++++ src/Adapters/ResourceAdapter.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/Adapters/ModelResourceAdapter.php b/src/Adapters/ModelResourceAdapter.php index ca03490..0240932 100644 --- a/src/Adapters/ModelResourceAdapter.php +++ b/src/Adapters/ModelResourceAdapter.php @@ -164,4 +164,8 @@ public function post($payload, $params, WebRequest $request) return $this->makeResourceFromData($model); } + + public function delete($payload, $params, ?WebRequest $request) + { + } } \ No newline at end of file diff --git a/src/Adapters/ResourceAdapter.php b/src/Adapters/ResourceAdapter.php index c657e5a..5bf9c0b 100644 --- a/src/Adapters/ResourceAdapter.php +++ b/src/Adapters/ResourceAdapter.php @@ -59,6 +59,8 @@ public function list($params, ?WebRequest $request = null) public abstract function post($payload, $params, WebRequest $request); + public abstract function delete($payload, $params, ?WebRequest $request); + protected abstract function countItems($rangeStart, $rangeEnd, $params, ?WebRequest $request); protected abstract function getItems($rangeStart, $rangeEnd, $params, ?WebRequest $request); From f945fba8cbea737249697df3489b2bfc5f36666e Mon Sep 17 00:00:00 2001 From: Michael Miscampbell Date: Wed, 30 Jan 2019 19:56:45 +0000 Subject: [PATCH 4/4] Addressing the issue where the id for a model is not sent as part of the body. Added Validation for an empty payload being sent. --- src/Adapters/ModelResourceAdapter.php | 14 +++++++++ src/Adapters/ResourceAdapter.php | 29 +++++++++++++++++++ .../RequestPayloadValidationException.php | 10 +++++++ src/UrlHandlers/RestApiHandler.php | 5 ++++ 4 files changed, 58 insertions(+) create mode 100644 src/Exceptions/RequestPayloadValidationException.php diff --git a/src/Adapters/ModelResourceAdapter.php b/src/Adapters/ModelResourceAdapter.php index 0240932..732a564 100644 --- a/src/Adapters/ModelResourceAdapter.php +++ b/src/Adapters/ModelResourceAdapter.php @@ -110,6 +110,11 @@ protected function applyResourceToModel($resource, Model $model) public function putResource($resource) { $modelClass = $this->modelClassName; + + if (!isset($resource["id"])) { + throw new ResourceNotFoundException(); + } + /** * @var $model Model */ @@ -122,6 +127,15 @@ public function putResource($resource) return $model; } + protected function applyParamsToPayload($payload, $params) + { + if (isset($params["id"])) { + $payload["id"] = $params["id"]; + } + + return parent::applyParamsToPayload($payload, $params); + } + protected function filterCollection(Collection $collection, $params, ?WebRequest $request = null) { diff --git a/src/Adapters/ResourceAdapter.php b/src/Adapters/ResourceAdapter.php index 5bf9c0b..627ec05 100644 --- a/src/Adapters/ResourceAdapter.php +++ b/src/Adapters/ResourceAdapter.php @@ -4,6 +4,7 @@ use Rhubarb\Crown\Request\WebRequest; use Rhubarb\RestApi\Exceptions\ResourceNotFoundException; +use Rhubarb\RestApi\Exceptions\RequestPayloadValidationException; use Rhubarb\RestApi\Resources\ListResource; /** @@ -20,6 +21,10 @@ abstract class ResourceAdapter */ public function put($payload, $params, ?WebRequest $request) { + $payload = $this->validatePutRequestPayload($payload); + + $payload = $this->applyParamsToPayload($payload, $params); + $resource = $this->get($params, $request); $this->putResource($payload); @@ -27,6 +32,13 @@ public function put($payload, $params, ?WebRequest $request) return $this->get($params, $request); } + protected function validatePutRequestPayload($payload) + { + $this->validateRequestPayload($payload); + + return $payload; + } + public function get($params, ?WebRequest $request) { $id = $params["id"]; @@ -59,9 +71,26 @@ public function list($params, ?WebRequest $request = null) public abstract function post($payload, $params, WebRequest $request); + protected function validatePostRequestPayload($payload) + { + $this->validateRequestPayload($payload); + } + public abstract function delete($payload, $params, ?WebRequest $request); protected abstract function countItems($rangeStart, $rangeEnd, $params, ?WebRequest $request); protected abstract function getItems($rangeStart, $rangeEnd, $params, ?WebRequest $request); + + protected function applyParamsToPayload($payload, $params) + { + return $payload; + } + + private final function validateRequestPayload($payload) + { + if (!is_array($payload)) { + throw new RequestPayloadValidationException("POST and PUT options require a JSON encoded resource object in the body of the request."); + } + } } \ No newline at end of file diff --git a/src/Exceptions/RequestPayloadValidationException.php b/src/Exceptions/RequestPayloadValidationException.php new file mode 100644 index 0000000..6597d1d --- /dev/null +++ b/src/Exceptions/RequestPayloadValidationException.php @@ -0,0 +1,10 @@ +setContent("The resource could not be located."); + } catch (RequestPayloadValidationException $er){ + $response = new NotAuthorisedResponse(); + $response->setContent($er->getMessage()); } catch (\Throwable $er){ $response = new Response(); $response->setResponseCode(500);