Commit b6861fef authored by alexpott's avatar alexpott

Issue #2310307 by marthinal, tedbow, clemens.tolboom, queenvictoria,...

Issue #2310307 by marthinal, tedbow, clemens.tolboom, queenvictoria, vivekvpandya, juampynr, Berdir, dawehner, Damien Tournoud, stefan.r, Wim Leers: File needs CRUD permissions to make REST work on entity/file/{id}
parent 0f3964dd
......@@ -6,6 +6,8 @@
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountInterface;
/**
......@@ -43,6 +45,16 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter
}
}
if ($operation == 'delete' || $operation == 'update') {
$account = $this->prepareUser($account);
$file_uid = $entity->get('uid')->getValue();
// Only the file owner can delete and update the file entity.
if ($account->id() == $file_uid[0]['target_id']) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
// No opinion.
return AccessResult::neutral();
}
......@@ -63,4 +75,30 @@ protected function getFileReferences(FileInterface $file) {
return file_get_file_references($file, NULL, EntityStorageInterface::FIELD_LOAD_REVISION, NULL);
}
/**
* {@inheritdoc}
*/
protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
// No user can edit the status of a file. Prevents saving a new file as
// persistent before even validating it.
if ($field_definition->getName() === 'status' && $operation === 'edit') {
return AccessResult::forbidden();
}
return parent::checkFieldAccess($operation, $field_definition, $account, $items);
}
/**
* {@inheritdoc}
*/
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
// The file entity has no "create" permission because by default Drupal core
// does not allow creating file entities independently. It allows you to
// create file entities that are referenced from another entity
// (e.g. an image for a article). A contributed module is free to alter
// this to allow file entities to be created directly.
// @todo Update comment to mention REST module when
// https://www.drupal.org/node/1927648 is fixed.
return AccessResult::neutral();
}
}
<?php
namespace Drupal\Tests\file\Kernel;
use Drupal\file\Entity\File;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\User;
/**
* Tests for the File access control.
*
* @group file
*/
class AccessTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['file', 'system', 'user'];
/**
* An authenticated user.
*
* @var \Drupal\user\UserInterface
*/
protected $user1;
/**
* An authenticated user.
*
* @var \Drupal\user\UserInterface
*/
protected $user2;
/**
* The file object used in the test.
*
* @var \Drupal\file\FileInterface
*/
protected $file;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('file');
$this->installEntitySchema('user');
$this->installSchema('file', array('file_usage'));
$this->installSchema('system', 'sequences');
$this->user1 = User::create([
'name' => 'user1',
'status' => 1,
]);
$this->user1->save();
$this->user2 = User::create([
'name' => 'user2',
'status' => 1,
]);
$this->user2->save();
$this->file = File::create(array(
'uid' => $this->user1->id(),
'filename' => 'druplicon.txt',
'filemime' => 'text/plain',
));
}
/**
* Tests that only the file owner can delete or update a file.
*/
public function testOnlyOwnerCanDeleteUpdateFile() {
\Drupal::currentUser()->setAccount($this->user2);
$this->assertFalse($this->file->access('delete'));
$this->assertFalse($this->file->access('update'));
\Drupal::currentUser()->setAccount($this->user1);
$this->assertTrue($this->file->access('delete'));
$this->assertTrue($this->file->access('update'));
}
/**
* Tests that the status field is not editable.
*/
public function testStatusFieldIsNotEditable() {
\Drupal::currentUser()->setAccount($this->user1);
$this->assertFalse($this->file->get('status')->access('edit'));
}
/**
* Tests create access checks.
*/
public function testCreateAccess() {
// Anonymous users can create a file by default.
$this->assertFalse($this->file->access('create'));
// Authenticated users can create a file by default.
\Drupal::currentUser()->setAccount($this->user1);
$this->assertFalse($this->file->access('create'));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment