View source
<?php
namespace Drupal\KernelTests\Core\Entity;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessibleInterface;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Session\AnonymousUserSession;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\entity_test\Entity\EntityTestStringId;
use Drupal\entity_test\Entity\EntityTestDefaultAccess;
use Drupal\entity_test\Entity\EntityTestNoUuid;
use Drupal\entity_test\Entity\EntityTestLabel;
use Drupal\entity_test\Entity\EntityTestRev;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\user\Entity\User;
class EntityAccessControlHandlerTest extends EntityLanguageTestBase {
public function setUp() {
parent::setUp();
$this
->installEntitySchema('entity_test_no_uuid');
$this
->installEntitySchema('entity_test_rev');
$this
->installEntitySchema('entity_test_string_id');
}
public function assertEntityAccess($ops, AccessibleInterface $object, AccountInterface $account = NULL) {
foreach ($ops as $op => $result) {
$message = new FormattableMarkup("Entity access returns @result with operation '@op'.", [
'@result' => !isset($result) ? 'null' : ($result ? 'true' : 'false'),
'@op' => $op,
]);
$this
->assertEqual($result, $object
->access($op, $account), $message);
}
}
public function testUserLabelAccess() {
\Drupal::currentUser()
->setAccount($this
->createUser([
'uid' => 2,
]));
$anonymous_user = User::getAnonymousUser();
$user = $this
->createUser();
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => FALSE,
'view label' => TRUE,
], $anonymous_user);
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => FALSE,
'view label' => TRUE,
], $user);
$account_switcher = \Drupal::service('account_switcher');
$account_switcher
->switchTo(new AnonymousUserSession());
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => FALSE,
'view label' => TRUE,
], $anonymous_user);
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => FALSE,
'view label' => TRUE,
], $user);
$account_switcher
->switchBack();
}
public function testEntityAccess() {
\Drupal::currentUser()
->setAccount($this
->createUser([
'uid' => 2,
], [
'view test entity',
]));
$entity = EntityTestLabel::create([
'name' => 'test',
]);
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => TRUE,
'view label' => TRUE,
], $entity);
$custom_user = $this
->createUser();
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => FALSE,
'view label' => TRUE,
], $entity, $custom_user);
}
public function testDefaultEntityAccess() {
\Drupal::currentUser()
->setAccount($this
->createUser([
'uid' => 2,
], [
'view test entity',
]));
$entity = EntityTest::create([
'name' => 'forbid_access',
]);
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => FALSE,
], $entity);
}
public function testEntityAccessDefaultController() {
\Drupal::currentUser()
->setAccount($this
->createUser([
'uid' => 2,
]));
$handler = $this->container
->get('entity_type.manager')
->getAccessControlHandler('entity_test_default_access');
$this
->assertInstanceOf(EntityAccessControlHandler::class, $handler);
$entity = EntityTestDefaultAccess::create();
$this
->assertEntityAccess([
'create' => FALSE,
'update' => FALSE,
'delete' => FALSE,
'view' => FALSE,
], $entity);
}
public function testEntityTranslationAccess() {
\Drupal::currentUser()
->setAccount($this
->createUser([
'uid' => 2,
], [
'view test entity translations',
]));
foreach ([
'foo',
'bar',
] as $langcode) {
ConfigurableLanguage::create([
'id' => $langcode,
'label' => $this
->randomString(),
])
->save();
}
$entity = EntityTest::create([
'name' => 'test',
'langcode' => 'foo',
]);
$entity
->save();
$translation = $entity
->addTranslation('bar');
$this
->assertEntityAccess([
'view' => TRUE,
], $translation);
}
public function testEntityWithoutUuidAccessCache() {
$account = $this
->createUser();
$entity1 = EntityTestNoUuid::create([
'name' => 'Accessible',
]);
$entity1
->save();
$entity2 = EntityTestNoUuid::create([
'name' => 'Inaccessible',
]);
$entity2
->save();
$this
->assertTrue($entity1
->access('delete', $account), 'Entity 1 can be deleted.');
$this
->assertFalse($entity2
->access('delete', $account), 'Entity 2 CANNOT be deleted.');
$entity1
->setName('Inaccessible')
->setNewRevision();
$entity1
->save();
$this
->assertFalse($entity1
->access('delete', $account), 'Entity 1 revision 2 CANNOT be deleted.');
}
public function testEntityWithUuidAccessCache() {
$account = $this
->createUser();
$entity1 = EntityTestRev::create([
'name' => 'Accessible',
]);
$entity1
->save();
$entity2 = EntityTestRev::create([
'name' => 'Inaccessible',
]);
$entity2
->save();
$this
->assertTrue($entity1
->access('delete', $account), 'Entity 1 can be deleted.');
$this
->assertFalse($entity2
->access('delete', $account), 'Entity 2 CANNOT be deleted.');
$entity1
->setName('Inaccessible')
->setNewRevision();
$entity1
->save();
$this
->assertFalse($entity1
->access('delete', $account), 'Entity 1 revision 2 CANNOT be deleted.');
}
public function testHooks() {
$state = $this->container
->get('state');
$entity = EntityTest::create([
'name' => 'test',
]);
$entity
->access('create');
$this
->assertEqual($state
->get('entity_test_entity_create_access'), TRUE);
$this
->assertIdentical($state
->get('entity_test_entity_create_access_context'), [
'entity_type_id' => 'entity_test',
'langcode' => LanguageInterface::LANGCODE_DEFAULT,
]);
$this
->assertEqual($state
->get('entity_test_entity_test_create_access'), TRUE);
$entity
->access('view');
$this
->assertEqual($state
->get('entity_test_entity_access'), TRUE);
$this
->assertEqual($state
->get('entity_test_entity_test_access'), TRUE);
}
public function testFieldAccess($entity_class, array $entity_create_values, $expected_id_create_access) {
\Drupal::currentUser()
->setAccount($this
->createUser([
'uid' => 2,
], [
'administer entity_test content',
]));
$entity = $entity_class::create($entity_create_values);
$this
->assertTrue($entity
->get('uuid')
->access('edit'));
$this
->assertTrue($entity
->get('uuid')
->access('edit', NULL, TRUE)
->isAllowed());
$this
->assertEquals($expected_id_create_access, $entity
->get('id')
->access('edit'));
$this
->assertEquals($expected_id_create_access, $entity
->get('id')
->access('edit', NULL, TRUE)
->isAllowed());
$entity
->save();
if (isset($entity_create_values['id'])) {
$this
->assertSame($entity_create_values['id'], $entity
->id());
}
$this
->assertSame('60e3a179-79ed-4653-ad52-5e614c8e8fbe', $entity
->uuid());
$this
->assertFalse($entity
->get('uuid')
->access('edit'));
$access_result = $entity
->get('uuid')
->access('edit', NULL, TRUE);
$this
->assertTrue($access_result
->isForbidden());
$this
->assertEquals('The entity UUID cannot be changed.', $access_result
->getReason());
$this
->assertFalse($entity
->get('id')
->access('edit'));
$access_result = $entity
->get('id')
->access('edit', NULL, TRUE);
$this
->assertTrue($access_result
->isForbidden());
$this
->assertEquals('The entity ID cannot be changed.', $access_result
->getReason());
}
public function providerTestFieldAccess() {
return [
'serial ID entity' => [
EntityTest::class,
[
'name' => 'A test entity',
'uuid' => '60e3a179-79ed-4653-ad52-5e614c8e8fbe',
],
FALSE,
],
'string ID entity' => [
EntityTestStringId::class,
[
'id' => 'a_test_entity',
'name' => 'A test entity',
'uuid' => '60e3a179-79ed-4653-ad52-5e614c8e8fbe',
],
TRUE,
],
];
}
}