3 namespace Drupal\KernelTests\Core\Entity;
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\Core\Session\AccountInterface;
7 use Drupal\Core\Access\AccessibleInterface;
8 use Drupal\Core\Entity\EntityAccessControlHandler;
9 use Drupal\Core\Session\AnonymousUserSession;
10 use Drupal\entity_test\Entity\EntityTest;
11 use Drupal\entity_test\Entity\EntityTestDefaultAccess;
12 use Drupal\entity_test\Entity\EntityTestLabel;
13 use Drupal\language\Entity\ConfigurableLanguage;
14 use Drupal\user\Entity\User;
17 * Tests the entity access control handler.
21 class EntityAccessControlHandlerTest extends EntityLanguageTestBase {
24 * Asserts entity access correctly grants or denies access.
26 public function assertEntityAccess($ops, AccessibleInterface $object, AccountInterface $account = NULL) {
27 foreach ($ops as $op => $result) {
28 $message = format_string("Entity access returns @result with operation '@op'.", [
29 '@result' => !isset($result) ? 'null' : ($result ? 'true' : 'false'),
33 $this->assertEqual($result, $object->access($op, $account), $message);
38 * Ensures user labels are accessible for everyone.
40 public function testUserLabelAccess() {
41 // Set up a non-admin user.
42 \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2]));
44 $anonymous_user = User::getAnonymousUser();
45 $user = $this->createUser();
47 // The current user is allowed to view the anonymous user label.
48 $this->assertEntityAccess([
56 // The current user is allowed to view user labels.
57 $this->assertEntityAccess([
65 // Switch to a anonymous user account.
66 $account_switcher = \Drupal::service('account_switcher');
67 $account_switcher->switchTo(new AnonymousUserSession());
69 // The anonymous user is allowed to view the anonymous user label.
70 $this->assertEntityAccess([
78 // The anonymous user is allowed to view user labels.
79 $this->assertEntityAccess([
87 // Restore user account.
88 $account_switcher->switchBack();
92 * Ensures entity access is properly working.
94 public function testEntityAccess() {
95 // Set up a non-admin user that is allowed to view test entities.
96 \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2], ['view test entity']));
98 // Use the 'entity_test_label' entity type in order to test the 'view label'
100 $entity = EntityTestLabel::create([
104 // The current user is allowed to view entities.
105 $this->assertEntityAccess([
110 'view label' => TRUE,
113 // The custom user is not allowed to perform any operation on test entities,
114 // except for viewing their label.
115 $custom_user = $this->createUser();
116 $this->assertEntityAccess([
121 'view label' => TRUE,
122 ], $entity, $custom_user);
126 * Ensures default entity access is checked when necessary.
128 * This ensures that the default checkAccess() implementation of the
129 * entity access control handler is considered if hook_entity_access() has not
130 * explicitly forbidden access. Therefore the default checkAccess()
131 * implementation can forbid access, even after access was already explicitly
132 * allowed by hook_entity_access().
134 * @see \Drupal\entity_test\EntityTestAccessControlHandler::checkAccess()
135 * @see entity_test_entity_access()
137 public function testDefaultEntityAccess() {
138 // Set up a non-admin user that is allowed to view test entities.
139 \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2], ['view test entity']));
140 $entity = EntityTest::create([
141 'name' => 'forbid_access',
144 // The user is denied access to the entity.
145 $this->assertEntityAccess([
154 * Ensures that the default handler is used as a fallback.
156 public function testEntityAccessDefaultController() {
157 // The implementation requires that the global user id can be loaded.
158 \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2]));
160 // Check that the default access control handler is used for entities that don't
161 // have a specific access control handler defined.
162 $handler = $this->container->get('entity.manager')->getAccessControlHandler('entity_test_default_access');
163 $this->assertTrue($handler instanceof EntityAccessControlHandler, 'The default entity handler is used for the entity_test_default_access entity type.');
165 $entity = EntityTestDefaultAccess::create();
166 $this->assertEntityAccess([
175 * Ensures entity access for entity translations is properly working.
177 public function testEntityTranslationAccess() {
179 // Set up a non-admin user that is allowed to view test entity translations.
180 \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2], ['view test entity translations']));
182 // Create two test languages.
183 foreach (['foo', 'bar'] as $langcode) {
184 ConfigurableLanguage::create([
186 'label' => $this->randomString(),
190 $entity = EntityTest::create([
196 $translation = $entity->addTranslation('bar');
197 $this->assertEntityAccess([
203 * Tests hook invocations.
205 public function testHooks() {
206 $state = $this->container->get('state');
207 $entity = EntityTest::create([
211 // Test hook_entity_create_access() and hook_ENTITY_TYPE_create_access().
212 $entity->access('create');
213 $this->assertEqual($state->get('entity_test_entity_create_access'), TRUE);
214 $this->assertIdentical($state->get('entity_test_entity_create_access_context'), [
215 'entity_type_id' => 'entity_test',
216 'langcode' => LanguageInterface::LANGCODE_DEFAULT,
218 $this->assertEqual($state->get('entity_test_entity_test_create_access'), TRUE);
220 // Test hook_entity_access() and hook_ENTITY_TYPE_access().
221 $entity->access('view');
222 $this->assertEqual($state->get('entity_test_entity_access'), TRUE);
223 $this->assertEqual($state->get('entity_test_entity_test_access'), TRUE);