d7644b205954c183012bb6d6905b5562f0440a7e
[yaffs-website] / web / core / tests / Drupal / KernelTests / Core / Entity / EntityAccessControlHandlerTest.php
1 <?php
2
3 namespace Drupal\KernelTests\Core\Entity;
4
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;
15
16 /**
17  * Tests the entity access control handler.
18  *
19  * @group Entity
20  */
21 class EntityAccessControlHandlerTest extends EntityLanguageTestBase {
22
23   /**
24    * Asserts entity access correctly grants or denies access.
25    */
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'),
30         '@op' => $op,
31       ]);
32
33       $this->assertEqual($result, $object->access($op, $account), $message);
34     }
35   }
36
37   /**
38    * Ensures user labels are accessible for everyone.
39    */
40   public function testUserLabelAccess() {
41     // Set up a non-admin user.
42     \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2]));
43
44     $anonymous_user = User::getAnonymousUser();
45     $user = $this->createUser();
46
47     // The current user is allowed to view the anonymous user label.
48     $this->assertEntityAccess([
49       'create' => FALSE,
50       'update' => FALSE,
51       'delete' => FALSE,
52       'view' => FALSE,
53       'view label' => TRUE,
54     ], $anonymous_user);
55
56     // The current user is allowed to view user labels.
57     $this->assertEntityAccess([
58       'create' => FALSE,
59       'update' => FALSE,
60       'delete' => FALSE,
61       'view' => FALSE,
62       'view label' => TRUE,
63     ], $user);
64
65     // Switch to a anonymous user account.
66     $account_switcher = \Drupal::service('account_switcher');
67     $account_switcher->switchTo(new AnonymousUserSession());
68
69     // The anonymous user is allowed to view the anonymous user label.
70     $this->assertEntityAccess([
71       'create' => FALSE,
72       'update' => FALSE,
73       'delete' => FALSE,
74       'view' => FALSE,
75       'view label' => TRUE,
76     ], $anonymous_user);
77
78     // The anonymous user is allowed to view user labels.
79     $this->assertEntityAccess([
80       'create' => FALSE,
81       'update' => FALSE,
82       'delete' => FALSE,
83       'view' => FALSE,
84       'view label' => TRUE,
85     ], $user);
86
87     // Restore user account.
88     $account_switcher->switchBack();
89   }
90
91   /**
92    * Ensures entity access is properly working.
93    */
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']));
97
98     // Use the 'entity_test_label' entity type in order to test the 'view label'
99     // access operation.
100     $entity = EntityTestLabel::create([
101       'name' => 'test',
102     ]);
103
104     // The current user is allowed to view entities.
105     $this->assertEntityAccess([
106       'create' => FALSE,
107       'update' => FALSE,
108       'delete' => FALSE,
109       'view' => TRUE,
110       'view label' => TRUE,
111     ], $entity);
112
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([
117       'create' => FALSE,
118       'update' => FALSE,
119       'delete' => FALSE,
120       'view' => FALSE,
121       'view label' => TRUE,
122     ], $entity, $custom_user);
123   }
124
125   /**
126    * Ensures default entity access is checked when necessary.
127    *
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().
133    *
134    * @see \Drupal\entity_test\EntityTestAccessControlHandler::checkAccess()
135    * @see entity_test_entity_access()
136    */
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',
142       ]);
143
144     // The user is denied access to the entity.
145     $this->assertEntityAccess([
146         'create' => FALSE,
147         'update' => FALSE,
148         'delete' => FALSE,
149         'view' => FALSE,
150       ], $entity);
151   }
152
153   /**
154    * Ensures that the default handler is used as a fallback.
155    */
156   public function testEntityAccessDefaultController() {
157     // The implementation requires that the global user id can be loaded.
158     \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2]));
159
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.');
164
165     $entity = EntityTestDefaultAccess::create();
166     $this->assertEntityAccess([
167       'create' => FALSE,
168       'update' => FALSE,
169       'delete' => FALSE,
170       'view' => FALSE,
171     ], $entity);
172   }
173
174   /**
175    * Ensures entity access for entity translations is properly working.
176    */
177   public function testEntityTranslationAccess() {
178
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']));
181
182     // Create two test languages.
183     foreach (['foo', 'bar'] as $langcode) {
184       ConfigurableLanguage::create([
185         'id' => $langcode,
186         'label' => $this->randomString(),
187       ])->save();
188     }
189
190     $entity = EntityTest::create([
191       'name' => 'test',
192       'langcode' => 'foo',
193     ]);
194     $entity->save();
195
196     $translation = $entity->addTranslation('bar');
197     $this->assertEntityAccess([
198       'view' => TRUE,
199     ], $translation);
200   }
201
202   /**
203    * Tests hook invocations.
204    */
205   public function testHooks() {
206     $state = $this->container->get('state');
207     $entity = EntityTest::create([
208       'name' => 'test',
209     ]);
210
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,
217     ]);
218     $this->assertEqual($state->get('entity_test_entity_test_create_access'), TRUE);
219
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);
224   }
225
226 }