Issue #2485683 by Wim Leers: REST entity resource missing entity & field access cacheability metadata
parent
55e3b42546
commit
ac415b1f5b
|
@ -45,19 +45,24 @@ class EntityResource extends ResourceBase {
|
||||||
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
|
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
|
||||||
*/
|
*/
|
||||||
public function get(EntityInterface $entity) {
|
public function get(EntityInterface $entity) {
|
||||||
if (!$entity->access('view')) {
|
$entity_access = $entity->access('view', NULL, TRUE);
|
||||||
|
if (!$entity_access->isAllowed()) {
|
||||||
throw new AccessDeniedHttpException();
|
throw new AccessDeniedHttpException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$response = new ResourceResponse($entity, 200);
|
||||||
|
$response->addCacheableDependency($entity);
|
||||||
|
$response->addCacheableDependency($entity_access);
|
||||||
foreach ($entity as $field_name => $field) {
|
foreach ($entity as $field_name => $field) {
|
||||||
if (!$field->access('view')) {
|
/** @var \Drupal\Core\Field\FieldItemListInterface $field */
|
||||||
|
$field_access = $field->access('view', NULL, TRUE);
|
||||||
|
$response->addCacheableDependency($field_access);
|
||||||
|
|
||||||
|
if (!$field_access->isAllowed()) {
|
||||||
$entity->set($field_name, NULL);
|
$entity->set($field_name, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = new ResourceResponse($entity, 200);
|
|
||||||
// Make the response use the entity's cacheability metadata.
|
|
||||||
// @todo include access cacheability metadata, for the access checks above.
|
|
||||||
$response->addCacheableDependency($entity);
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ class PageCacheTest extends RESTTestBase {
|
||||||
|
|
||||||
// Create an entity programmatically.
|
// Create an entity programmatically.
|
||||||
$entity = $this->entityCreate('entity_test');
|
$entity = $this->entityCreate('entity_test');
|
||||||
|
$entity->set('field_test_text', 'custom cache tag value');
|
||||||
$entity->save();
|
$entity->save();
|
||||||
// Read it over the REST API.
|
// Read it over the REST API.
|
||||||
$this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET', NULL, $this->defaultMimeType);
|
$this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET', NULL, $this->defaultMimeType);
|
||||||
|
@ -40,6 +41,7 @@ class PageCacheTest extends RESTTestBase {
|
||||||
$this->assertHeader('x-drupal-cache', 'MISS');
|
$this->assertHeader('x-drupal-cache', 'MISS');
|
||||||
$this->assertCacheTag('config:rest.settings');
|
$this->assertCacheTag('config:rest.settings');
|
||||||
$this->assertCacheTag('entity_test:1');
|
$this->assertCacheTag('entity_test:1');
|
||||||
|
$this->assertCacheTag('entity_test_access:field_test_text');
|
||||||
|
|
||||||
// Read it again, should be page-cached now.
|
// Read it again, should be page-cached now.
|
||||||
$this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET', NULL, $this->defaultMimeType);
|
$this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET', NULL, $this->defaultMimeType);
|
||||||
|
@ -47,6 +49,7 @@ class PageCacheTest extends RESTTestBase {
|
||||||
$this->assertHeader('x-drupal-cache', 'HIT');
|
$this->assertHeader('x-drupal-cache', 'HIT');
|
||||||
$this->assertCacheTag('config:rest.settings');
|
$this->assertCacheTag('config:rest.settings');
|
||||||
$this->assertCacheTag('entity_test:1');
|
$this->assertCacheTag('entity_test:1');
|
||||||
|
$this->assertCacheTag('entity_test_access:field_test_text');
|
||||||
|
|
||||||
// Trigger a config save which should clear the page cache, so we should get
|
// Trigger a config save which should clear the page cache, so we should get
|
||||||
// a cache miss now for the same request.
|
// a cache miss now for the same request.
|
||||||
|
@ -56,6 +59,7 @@ class PageCacheTest extends RESTTestBase {
|
||||||
$this->assertHeader('x-drupal-cache', 'MISS');
|
$this->assertHeader('x-drupal-cache', 'MISS');
|
||||||
$this->assertCacheTag('config:rest.settings');
|
$this->assertCacheTag('config:rest.settings');
|
||||||
$this->assertCacheTag('entity_test:1');
|
$this->assertCacheTag('entity_test:1');
|
||||||
|
$this->assertCacheTag('entity_test_access:field_test_text');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,10 +384,13 @@ function entity_test_entity_field_access($operation, FieldDefinitionInterface $f
|
||||||
if ($field_definition->getName() == 'field_test_text') {
|
if ($field_definition->getName() == 'field_test_text') {
|
||||||
if ($items) {
|
if ($items) {
|
||||||
if ($items->value == 'no access value') {
|
if ($items->value == 'no access value') {
|
||||||
return AccessResult::forbidden()->cacheUntilEntityChanges($items->getEntity());
|
return AccessResult::forbidden()->addCacheableDependency($items->getEntity());
|
||||||
|
}
|
||||||
|
elseif ($items->value == 'custom cache tag value') {
|
||||||
|
return AccessResult::allowed()->addCacheableDependency($items->getEntity())->addCacheTags(['entity_test_access:field_test_text']);
|
||||||
}
|
}
|
||||||
elseif ($operation == 'edit' && $items->value == 'no edit access value') {
|
elseif ($operation == 'edit' && $items->value == 'no edit access value') {
|
||||||
return AccessResult::forbidden()->cacheUntilEntityChanges($items->getEntity());
|
return AccessResult::forbidden()->addCacheableDependency($items->getEntity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue