diff --git a/src/Controller/EntityResource.php b/src/Controller/EntityResource.php index 627ef48..2eb4fe0 100644 --- a/src/Controller/EntityResource.php +++ b/src/Controller/EntityResource.php @@ -389,7 +389,7 @@ class EntityResource { $field_access = $field_list->access('edit', NULL, TRUE); if (!$field_access->isAllowed()) { $field_name = $field_list->getName(); - throw new EntityAccessDeniedHttpException($entity, $field_access, '/data/attributes/' . $field_name, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name)); + throw new EntityAccessDeniedHttpException($entity, $field_access, '/data/relationships/' . $field_name, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name)); } // Time to save the relationship. foreach ($parsed_field_list as $field_item) { @@ -467,7 +467,7 @@ class EntityResource { $field_name = $parsed_field_list->getName(); $field_access = $parsed_field_list->access('edit', NULL, TRUE); if (!$field_access->isAllowed()) { - throw new SerializableHttpException(403, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name)); + throw new EntityAccessDeniedHttpException($entity, $field_access, '/data/relationships/' . $field_name, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name)); } $entity->{$field_name} = $parsed_field_list; } @@ -504,7 +504,7 @@ class EntityResource { $field_name = $parsed_field_list->getName(); $field_access = $parsed_field_list->access('edit', NULL, TRUE); if (!$field_access->isAllowed()) { - throw new EntityAccessDeniedHttpException($entity, $field_access, '/data/attributes/' . $field_name, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name)); + throw new EntityAccessDeniedHttpException($entity, $field_access, '/data/relationships/' . $field_name, sprintf('The current user is not allowed to PATCH the selected field (%s).', $field_name)); } /* @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $field_list */ $field_list = $entity->{$related_field}; @@ -730,11 +730,7 @@ class EntityResource { ]; if ($entity instanceof AccessibleInterface && !$access->isAllowed()) { // Pass an exception to the list of things to normalize. - $output['entity'] = new SerializableHttpException(403, sprintf( - 'Access checks failed for entity %s:%s.', - $entity->getEntityTypeId(), - $entity->id() - )); + $output['entity'] = new EntityAccessDeniedHttpException($entity, $access, '/data', 'The current user is not allowed to GET the selected resource.'); } return $output; diff --git a/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php b/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php index d5aedfd..9626f74 100644 --- a/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php +++ b/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php @@ -32,7 +32,12 @@ class EntityAccessDeniedHttpExceptionNormalizer extends HttpExceptionNormalizer $pointer = $error['pointer']; $reason = $error['reason']; - $errors[0]['id'] = $entity->uuid(); + $errors[0]['id'] = sprintf( + '/%s--%s/%s', + $entity->getEntityTypeId(), + $entity->bundle(), + $entity->uuid() + ); $errors[0]['source']['pointer'] = $pointer; if ($reason) { diff --git a/tests/src/Functional/JsonApiFunctionalTest.php b/tests/src/Functional/JsonApiFunctionalTest.php index 315e4e3..6c28a2b 100644 --- a/tests/src/Functional/JsonApiFunctionalTest.php +++ b/tests/src/Functional/JsonApiFunctionalTest.php @@ -62,7 +62,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase { $this->assertSession()->statusCodeEquals(403); $this->assertEquals('/data', $single_output['errors'][0]['source']['pointer']); - $this->assertEquals($this->nodes[60]->uuid(), $single_output['errors'][0]['id']); + $this->assertEquals('/node--article/' . $this->nodes[60]->uuid(), $single_output['errors'][0]['id']); // 6. Single relationship item. $single_output = Json::decode($this->drupalGet('/jsonapi/node/article/' . $uuid . '/relationships/type')); @@ -138,6 +138,8 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase { $this->assertEquals(1, count($single_output['data'])); $this->assertEquals(1, count($single_output['meta']['errors'])); $this->assertEquals(403, $single_output['meta']['errors'][0]['status']); + $this->assertEquals('/node--article/' . $this->nodes[1]->uuid(), $single_output['meta']['errors'][0]['id']); + $this->assertFalse(empty($single_output['meta']['errors'][0]['source']['pointer'])); $this->nodes[1]->set('status', TRUE); $this->nodes[1]->save(); // 13. Test filtering when using short syntax. diff --git a/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php b/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php index 9316bcf..f896ab5 100644 --- a/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php +++ b/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php @@ -220,7 +220,7 @@ class JsonApiDocumentTopLevelNormalizerTest extends JsonapiKernelTestBase { ], ], $normalized['data']['relationships']['uid']); $this->assertEquals( - 'Access checks failed for entity user:' . $this->user->id() . '.', + 'The current user is not allowed to GET the selected resource.', $normalized['meta']['errors'][0]['detail'] ); $this->assertEquals(403, $normalized['meta']['errors'][0]['status']);