Mercurial > hg > isophonics-drupal-site
comparison core/modules/user/tests/src/Unit/UserAccessControlHandlerTest.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\user\Unit; | |
4 | |
5 use Drupal\Core\Access\AccessResult; | |
6 use Drupal\Core\Cache\Context\CacheContextsManager; | |
7 use Drupal\Core\DependencyInjection\Container; | |
8 use Drupal\Tests\UnitTestCase; | |
9 use Drupal\user\UserAccessControlHandler; | |
10 | |
11 /** | |
12 * Tests the user access controller. | |
13 * | |
14 * @group Drupal | |
15 * @group User | |
16 * | |
17 * @coversDefaultClass \Drupal\user\UserAccessControlHandler | |
18 */ | |
19 class UserAccessControlHandlerTest extends UnitTestCase { | |
20 | |
21 /** | |
22 * The user access controller to test. | |
23 * | |
24 * @var \Drupal\user\UserAccessControlHandler | |
25 */ | |
26 protected $accessControlHandler; | |
27 | |
28 /** | |
29 * The mock user account with view access. | |
30 * | |
31 * @var \Drupal\Core\Session\AccountInterface | |
32 */ | |
33 protected $viewer; | |
34 | |
35 /** | |
36 * The mock user account that is able to change their own account name. | |
37 * | |
38 * @var \Drupal\Core\Session\AccountInterface | |
39 */ | |
40 protected $owner; | |
41 | |
42 /** | |
43 * The mock administrative test user. | |
44 * | |
45 * @var \Drupal\Core\Session\AccountInterface | |
46 */ | |
47 protected $admin; | |
48 | |
49 /** | |
50 * The mocked test field items. | |
51 * | |
52 * @var \Drupal\Core\Field\FieldItemList | |
53 */ | |
54 protected $items; | |
55 | |
56 /** | |
57 * {@inheritdoc} | |
58 */ | |
59 protected function setUp() { | |
60 parent::setUp(); | |
61 | |
62 $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); | |
63 $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); | |
64 $cache_contexts_manager->reveal(); | |
65 $container = new Container(); | |
66 $container->set('cache_contexts_manager', $cache_contexts_manager); | |
67 \Drupal::setContainer($container); | |
68 | |
69 $this->viewer = $this->getMock('\Drupal\Core\Session\AccountInterface'); | |
70 $this->viewer | |
71 ->expects($this->any()) | |
72 ->method('hasPermission') | |
73 ->will($this->returnValue(FALSE)); | |
74 $this->viewer | |
75 ->expects($this->any()) | |
76 ->method('id') | |
77 ->will($this->returnValue(1)); | |
78 | |
79 $this->owner = $this->getMock('\Drupal\Core\Session\AccountInterface'); | |
80 $this->owner | |
81 ->expects($this->any()) | |
82 ->method('hasPermission') | |
83 ->will($this->returnValueMap([ | |
84 ['administer users', FALSE], | |
85 ['change own username', TRUE], | |
86 ])); | |
87 | |
88 $this->owner | |
89 ->expects($this->any()) | |
90 ->method('id') | |
91 ->will($this->returnValue(2)); | |
92 | |
93 $this->admin = $this->getMock('\Drupal\Core\Session\AccountInterface'); | |
94 $this->admin | |
95 ->expects($this->any()) | |
96 ->method('hasPermission') | |
97 ->will($this->returnValue(TRUE)); | |
98 | |
99 $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); | |
100 | |
101 $this->accessControlHandler = new UserAccessControlHandler($entity_type); | |
102 $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); | |
103 $module_handler->expects($this->any()) | |
104 ->method('getImplementations') | |
105 ->will($this->returnValue([])); | |
106 $this->accessControlHandler->setModuleHandler($module_handler); | |
107 | |
108 $this->items = $this->getMockBuilder('Drupal\Core\Field\FieldItemList') | |
109 ->disableOriginalConstructor() | |
110 ->getMock(); | |
111 $this->items | |
112 ->expects($this->any()) | |
113 ->method('defaultAccess') | |
114 ->will($this->returnValue(AccessResult::allowed())); | |
115 } | |
116 | |
117 /** | |
118 * Asserts correct field access grants for a field. | |
119 */ | |
120 public function assertFieldAccess($field, $viewer, $target, $view, $edit) { | |
121 $field_definition = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface'); | |
122 $field_definition->expects($this->any()) | |
123 ->method('getName') | |
124 ->will($this->returnValue($field)); | |
125 | |
126 $this->items | |
127 ->expects($this->any()) | |
128 ->method('getEntity') | |
129 ->will($this->returnValue($this->{$target})); | |
130 | |
131 foreach (['view' => $view, 'edit' => $edit] as $operation => $result) { | |
132 $result_text = !isset($result) ? 'null' : ($result ? 'true' : 'false'); | |
133 $message = "User '$field' field access returns '$result_text' with operation '$operation' for '$viewer' accessing '$target'"; | |
134 $this->assertSame($result, $this->accessControlHandler->fieldAccess($operation, $field_definition, $this->{$viewer}, $this->items), $message); | |
135 } | |
136 } | |
137 | |
138 /** | |
139 * Ensures user name access is working properly. | |
140 * | |
141 * @dataProvider userNameProvider | |
142 */ | |
143 public function testUserNameAccess($viewer, $target, $view, $edit) { | |
144 $this->assertFieldAccess('name', $viewer, $target, $view, $edit); | |
145 } | |
146 | |
147 /** | |
148 * Provides test data for testUserNameAccess(). | |
149 */ | |
150 public function userNameProvider() { | |
151 $name_access = [ | |
152 // The viewer user is allowed to see user names on all accounts. | |
153 [ | |
154 'viewer' => 'viewer', | |
155 'target' => 'viewer', | |
156 'view' => TRUE, | |
157 'edit' => FALSE, | |
158 ], | |
159 [ | |
160 'viewer' => 'owner', | |
161 'target' => 'viewer', | |
162 'view' => TRUE, | |
163 'edit' => FALSE, | |
164 ], | |
165 [ | |
166 'viewer' => 'viewer', | |
167 'target' => 'owner', | |
168 'view' => TRUE, | |
169 'edit' => FALSE, | |
170 ], | |
171 // The owner user is allowed to change its own user name. | |
172 [ | |
173 'viewer' => 'owner', | |
174 'target' => 'owner', | |
175 'view' => TRUE, | |
176 'edit' => TRUE, | |
177 ], | |
178 // The users-administrator user has full access. | |
179 [ | |
180 'viewer' => 'admin', | |
181 'target' => 'owner', | |
182 'view' => TRUE, | |
183 'edit' => TRUE, | |
184 ], | |
185 ]; | |
186 return $name_access; | |
187 } | |
188 | |
189 /** | |
190 * Tests that private user settings cannot be viewed by other users. | |
191 * | |
192 * @dataProvider hiddenUserSettingsProvider | |
193 */ | |
194 public function testHiddenUserSettings($field, $viewer, $target, $view, $edit) { | |
195 $this->assertFieldAccess($field, $viewer, $target, $view, $edit); | |
196 } | |
197 | |
198 /** | |
199 * Provides test data for testHiddenUserSettings(). | |
200 */ | |
201 public function hiddenUserSettingsProvider() { | |
202 $access_info = []; | |
203 | |
204 $fields = [ | |
205 'preferred_langcode', | |
206 'preferred_admin_langcode', | |
207 'timezone', | |
208 'mail', | |
209 ]; | |
210 | |
211 foreach ($fields as $field) { | |
212 $access_info[] = [ | |
213 'field' => $field, | |
214 'viewer' => 'viewer', | |
215 'target' => 'viewer', | |
216 'view' => TRUE, | |
217 'edit' => TRUE, | |
218 ]; | |
219 $access_info[] = [ | |
220 'field' => $field, | |
221 'viewer' => 'viewer', | |
222 'target' => 'owner', | |
223 'view' => FALSE, | |
224 // Anyone with edit access to the user can also edit these fields. In | |
225 // reality edit access will already be checked on entity level and the | |
226 // user without view access will typically not be able to edit. | |
227 'edit' => TRUE, | |
228 ]; | |
229 $access_info[] = [ | |
230 'field' => $field, | |
231 'viewer' => 'owner', | |
232 'target' => 'owner', | |
233 'view' => TRUE, | |
234 'edit' => TRUE, | |
235 ]; | |
236 $access_info[] = [ | |
237 'field' => $field, | |
238 'viewer' => 'admin', | |
239 'target' => 'owner', | |
240 'view' => TRUE, | |
241 'edit' => TRUE, | |
242 ]; | |
243 } | |
244 | |
245 return $access_info; | |
246 } | |
247 | |
248 /** | |
249 * Tests that private user settings cannot be viewed by other users. | |
250 * | |
251 * @dataProvider adminFieldAccessProvider | |
252 */ | |
253 public function testAdminFieldAccess($field, $viewer, $target, $view, $edit) { | |
254 $this->assertFieldAccess($field, $viewer, $target, $view, $edit); | |
255 } | |
256 | |
257 /** | |
258 * Provides test data for testAdminFieldAccess(). | |
259 */ | |
260 public function adminFieldAccessProvider() { | |
261 $access_info = []; | |
262 | |
263 $fields = [ | |
264 'roles', | |
265 'status', | |
266 'access', | |
267 'login', | |
268 'init', | |
269 ]; | |
270 | |
271 foreach ($fields as $field) { | |
272 $access_info[] = [ | |
273 'field' => $field, | |
274 'viewer' => 'viewer', | |
275 'target' => 'viewer', | |
276 'view' => FALSE, | |
277 'edit' => FALSE, | |
278 ]; | |
279 $access_info[] = [ | |
280 'field' => $field, | |
281 'viewer' => 'viewer', | |
282 'target' => 'owner', | |
283 'view' => FALSE, | |
284 'edit' => FALSE, | |
285 ]; | |
286 $access_info[] = [ | |
287 'field' => $field, | |
288 'viewer' => 'admin', | |
289 'target' => 'owner', | |
290 'view' => TRUE, | |
291 'edit' => TRUE, | |
292 ]; | |
293 } | |
294 | |
295 return $access_info; | |
296 } | |
297 | |
298 /** | |
299 * Tests that passwords cannot be viewed, just edited. | |
300 * | |
301 * @dataProvider passwordAccessProvider | |
302 */ | |
303 public function testPasswordAccess($viewer, $target, $view, $edit) { | |
304 $this->assertFieldAccess('pass', $viewer, $target, $view, $edit); | |
305 } | |
306 | |
307 /** | |
308 * Provides test data for passwordAccessProvider(). | |
309 */ | |
310 public function passwordAccessProvider() { | |
311 $pass_access = [ | |
312 [ | |
313 'viewer' => 'viewer', | |
314 'target' => 'viewer', | |
315 'view' => FALSE, | |
316 'edit' => TRUE, | |
317 ], | |
318 [ | |
319 'viewer' => 'viewer', | |
320 'target' => 'owner', | |
321 'view' => FALSE, | |
322 // Anyone with edit access to the user can also edit these fields. In | |
323 // reality edit access will already be checked on entity level and the | |
324 // user without view access will typically not be able to edit. | |
325 'edit' => TRUE, | |
326 ], | |
327 [ | |
328 'viewer' => 'owner', | |
329 'target' => 'viewer', | |
330 'view' => FALSE, | |
331 'edit' => TRUE, | |
332 ], | |
333 [ | |
334 'viewer' => 'admin', | |
335 'target' => 'owner', | |
336 'view' => FALSE, | |
337 'edit' => TRUE, | |
338 ], | |
339 ]; | |
340 return $pass_access; | |
341 } | |
342 | |
343 /** | |
344 * Tests the user created field access. | |
345 * | |
346 * @dataProvider createdAccessProvider | |
347 */ | |
348 public function testCreatedAccess($viewer, $target, $view, $edit) { | |
349 $this->assertFieldAccess('created', $viewer, $target, $view, $edit); | |
350 } | |
351 | |
352 /** | |
353 * Provides test data for testCreatedAccess(). | |
354 */ | |
355 public function createdAccessProvider() { | |
356 $created_access = [ | |
357 [ | |
358 'viewer' => 'viewer', | |
359 'target' => 'viewer', | |
360 'view' => TRUE, | |
361 'edit' => FALSE, | |
362 ], | |
363 [ | |
364 'viewer' => 'owner', | |
365 'target' => 'viewer', | |
366 'view' => TRUE, | |
367 'edit' => FALSE, | |
368 ], | |
369 [ | |
370 'viewer' => 'admin', | |
371 'target' => 'owner', | |
372 'view' => TRUE, | |
373 'edit' => TRUE, | |
374 ], | |
375 ]; | |
376 return $created_access; | |
377 } | |
378 | |
379 /** | |
380 * Tests access to a non-existing base field. | |
381 * | |
382 * @dataProvider NonExistingFieldAccessProvider | |
383 */ | |
384 public function testNonExistingFieldAccess($viewer, $target, $view, $edit) { | |
385 // By default everyone has access to all fields that do not have explicit | |
386 // access control. | |
387 // @see EntityAccessControlHandler::checkFieldAccess() | |
388 $this->assertFieldAccess('some_non_existing_field', $viewer, $target, $view, $edit); | |
389 } | |
390 | |
391 /** | |
392 * Provides test data for testNonExistingFieldAccess(). | |
393 */ | |
394 public function NonExistingFieldAccessProvider() { | |
395 $created_access = [ | |
396 [ | |
397 'viewer' => 'viewer', | |
398 'target' => 'viewer', | |
399 'view' => TRUE, | |
400 'edit' => TRUE, | |
401 ], | |
402 [ | |
403 'viewer' => 'owner', | |
404 'target' => 'viewer', | |
405 'view' => TRUE, | |
406 'edit' => TRUE, | |
407 ], | |
408 [ | |
409 'viewer' => 'admin', | |
410 'target' => 'owner', | |
411 'view' => TRUE, | |
412 'edit' => TRUE, | |
413 ], | |
414 ]; | |
415 return $created_access; | |
416 } | |
417 | |
418 } |