diff --git a/src/Controller/EntityResource.php b/src/Controller/EntityResource.php index 0b87d60..ba0aec6 100644 --- a/src/Controller/EntityResource.php +++ b/src/Controller/EntityResource.php @@ -214,24 +214,19 @@ class EntityResource { // by the user. Field access makes no distinction between 'create' and // 'update', so the 'edit' operation is used here. $document = Json::decode($request->getContent()); - if (isset($document['data']['attributes'])) { - $received_attributes = array_keys($document['data']['attributes']); - foreach ($received_attributes as $field_name) { - $internal_field_name = $resource_type->getInternalName($field_name); - $field_access = $parsed_entity->get($internal_field_name) - ->access('edit', NULL, TRUE); - if (!$field_access->isAllowed()) { - throw new EntityAccessDeniedHttpException(NULL, $field_access, '/data/attributes/' . $field_name, sprintf('The current user is not allowed to POST the selected field (%s).', $field_name)); - } - } - } - if (isset($document['data']['relationships'])) { - $received_relationships = array_keys($document['data']['relationships']); - foreach ($received_relationships as $field_name) { - $internal_field_name = $resource_type->getInternalName($field_name); - $field_access = $parsed_entity->get($internal_field_name)->access('edit', NULL, TRUE); - if (!$field_access->isAllowed()) { - throw new EntityAccessDeniedHttpException(NULL, $field_access, '/data/relationships/' . $field_name, sprintf('The current user is not allowed to POST the selected field (%s).', $field_name)); + foreach (['attributes', 'relationships'] as $data_member_name) { + if (isset($document['data'][$data_member_name])) { + $valid_names = array_filter(array_map(function ($public_field_name) use ($resource_type) { + return $resource_type->getInternalName($public_field_name); + }, array_keys($document['data'][$data_member_name])), function ($internal_field_name) use ($resource_type) { + return $resource_type->hasField($internal_field_name); + }); + foreach ($valid_names as $field_name) { + $field_access = $parsed_entity->get($field_name)->access('edit', NULL, TRUE); + if (!$field_access->isAllowed()) { + $public_field_name = $resource_type->getPublicName($field_name); + throw new EntityAccessDeniedHttpException(NULL, $field_access, "/data/$data_member_name/$public_field_name", sprintf('The current user is not allowed to POST the selected field (%s).', $public_field_name)); + } } } } diff --git a/src/Normalizer/ContentEntityDenormalizer.php b/src/Normalizer/ContentEntityDenormalizer.php index 6d5bbc9..aecb6a2 100644 --- a/src/Normalizer/ContentEntityDenormalizer.php +++ b/src/Normalizer/ContentEntityDenormalizer.php @@ -52,7 +52,7 @@ final class ContentEntityDenormalizer extends EntityDenormalizerBase { // Skip any disabled field, except the always required bundle key and // required-in-case-of-PATCHing uuid key. // @see \Drupal\jsonapi\ResourceType\ResourceTypeRepository::getFieldMapping() - if (!$resource_type->isFieldEnabled($internal_name) && $bundle_key !== $internal_name && $uuid_key !== $internal_name) { + if ($resource_type->hasField($internal_name) && !$resource_type->isFieldEnabled($internal_name) && $bundle_key !== $internal_name && $uuid_key !== $internal_name) { continue; }