diff --git a/core/modules/file/src/FileAccessControlHandler.php b/core/modules/file/src/FileAccessControlHandler.php index 6745969..c1ae102 100644 --- a/core/modules/file/src/FileAccessControlHandler.php +++ b/core/modules/file/src/FileAccessControlHandler.php @@ -50,6 +50,16 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter } } + if ($operation == 'delete') { + $account = $this->prepareUser($account); + $file_uid = $entity->get('uid')->getValue(); + // Only admin users and the file owner can delete the file entity. + if ($account->hasPermission('administer nodes') || $account->id() == $file_uid[0]['target_id']) { + return AccessResult::allowed(); + } + return AccessResult::forbidden(); + } + // No opinion. return AccessResult::neutral(); } diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php index 6a28b3c..8fdcf1d 100644 --- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php +++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php @@ -151,7 +151,7 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity if ($entity->getEntityTypeId() != $definition['entity_type']) { throw new BadRequestHttpException('Invalid entity type'); } - if (!$original_entity->access('update')) { + if (!$original_entity->access('update', NULL, TRUE)) { throw new AccessDeniedHttpException(); } diff --git a/core/modules/rest/src/Tests/FileTest.php b/core/modules/rest/src/Tests/FileTest.php index 84ce5c6..65fb925 100644 --- a/core/modules/rest/src/Tests/FileTest.php +++ b/core/modules/rest/src/Tests/FileTest.php @@ -42,7 +42,18 @@ public function testCrudFile() { // Enables the REST service for 'file' entity type. $this->enableService('entity:' . $entity_type, 'POST', 'hal_json'); $this->enableService('entity:' . $entity_type, 'GET', 'hal_json'); - //$this->enableService('entity:' . $entity_type, 'PATCH'); + $this->enableService('entity:' . $entity_type, 'PATCH'); + $this->enableService('entity:' . $entity_type, 'DELETE'); + + // POST method must be allowed for the current entity type. + $permissions[] = 'restful post entity:' . $entity_type; + $permissions[] = 'restful get entity:' . $entity_type; + $permissions[] = 'restful patch entity:' . $entity_type; + $permissions[] = 'restful delete entity:' . $entity_type; + + // Create the user. + $account = $this->drupalCreateUser($permissions); + $file_contents = 'hello world'; $data = base64_encode($file_contents); @@ -50,6 +61,7 @@ public function testCrudFile() { $file = File::create([ 'filename' => 'default.txt', 'filemime' => 'text/plain', + 'uid' => $account->id(), ]); $normalized_data = $this->serializer->normalize($file, 'hal_json'); @@ -61,13 +73,6 @@ public function testCrudFile() { $serialized = $this->serializer->serialize($normalized_data, 'hal_json'); - // POST method must be allowed for the current entity type. - $permissions[] = 'restful post entity:' . $entity_type; - $permissions[] = 'restful get entity:' . $entity_type; - - // Create the user. - $account = $this->drupalCreateUser($permissions); - // Create the file. $this->drupalLogin($account); $this->httpRequest('entity/' . $entity_type, 'POST', $serialized, 'application/hal+json'); @@ -76,6 +81,20 @@ public function testCrudFile() { // Get the file. $this->httpRequest(Url::fromUri('base://entity/file/1', ['query' => ['_format' => 'hal_json']]), 'GET', NULL, 'application/hal+json'); $this->assertResponse(200); + + // Update the file entity. + $normalized_data['filename'][0]['value'] = 'default2.txt'; + $serialized = $this->serializer->serialize($normalized_data, 'hal_json'); + $this->httpRequest('entity/' . $entity_type . '/1', 'PATCH', $serialized, 'application/hal+json'); + $this->assertResponse(204); + + // Verify that the new name is correct. + $file = File::load(1); + $this->assertEqual('default2.txt', $file->getFilename(), 'The name was updated as expected'); + + // Delete. + $this->httpRequest('entity/' . $entity_type . '/1', 'DELETE', NULL, 'application/hal+json'); + $this->assertResponse(204); } }