[BUGFIX] Show correct label for IRRE records
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Form / FormDataProvider / DatabaseUserPermissionCheckTest.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Prophecy\Argument;
18 use Prophecy\Prophecy\ObjectProphecy;
19 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedContentEditException;
20 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedEditInternalsException;
21 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedHookException;
22 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedPageEditException;
23 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedPageNewException;
24 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedRootNodeException;
25 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedTableModifyException;
26 use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseUserPermissionCheck;
27 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
28 use TYPO3\CMS\Core\Tests\UnitTestCase;
29 use TYPO3\CMS\Core\Type\Bitmask\Permission;
30
31 /**
32 * Test case
33 */
34 class DatabaseUserPermissionCheckTest extends UnitTestCase
35 {
36 /**
37 * @var DatabaseUserPermissionCheck
38 */
39 protected $subject;
40
41 /**
42 * @var BackendUserAuthentication | ObjectProphecy
43 */
44 protected $beUserProphecy;
45
46 protected function setUp()
47 {
48 $this->subject = new DatabaseUserPermissionCheck();
49
50 $this->beUserProphecy = $this->prophesize(BackendUserAuthentication::class);
51 $GLOBALS['BE_USER'] = $this->beUserProphecy->reveal();
52 $GLOBALS['BE_USER']->user['uid'] = 42;
53 }
54
55 /**
56 * @test
57 */
58 public function addDataSetsUserPermissionsOnPageForAdminUser()
59 {
60 $this->beUserProphecy->isAdmin()->willReturn(true);
61
62 $result = $this->subject->addData(array());
63
64 $this->assertSame(Permission::ALL, $result['userPermissionOnPage']);
65 }
66
67 /**
68 * @test
69 */
70 public function addDataThrowsExceptionIfUserHasNoTablesModifyPermissionForGivenTable()
71 {
72 $input = [
73 'tableName' => 'tt_content',
74 ];
75 $this->beUserProphecy->isAdmin()->willReturn(false);
76 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(false);
77
78 $this->setExpectedException(AccessDeniedTableModifyException::class, $this->anything(), 1437683248);
79
80 $this->subject->addData($input);
81 }
82
83 /**
84 * @test
85 */
86 public function addDataThrowsExceptionIfUserHasNoContentEditPermissionsOnPage()
87 {
88 $input = [
89 'tableName' => 'tt_content',
90 'command' => 'edit',
91 'vanillaUid' => 123,
92 'parentPageRow' => [
93 'pid' => 321,
94 ],
95 ];
96 $this->beUserProphecy->isAdmin()->willReturn(false);
97 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
98 $this->beUserProphecy->calcPerms(['pid' => 321])->willReturn(Permission::NOTHING);
99
100 $this->setExpectedException(AccessDeniedContentEditException::class, 1437679657);
101
102 $this->subject->addData($input);
103 }
104
105 /**
106 * @test
107 */
108 public function addDataAddsUserPermissionsOnPageForContentIfUserHasCorrespondingPermissions()
109 {
110 $input = [
111 'tableName' => 'tt_content',
112 'command' => 'edit',
113 'vanillaUid' => 123,
114 'parentPageRow' => [
115 'pid' => 321,
116 ],
117 ];
118 $this->beUserProphecy->isAdmin()->willReturn(false);
119 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
120 $this->beUserProphecy->calcPerms(['pid' => 321])->willReturn(Permission::CONTENT_EDIT);
121 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::any())->willReturn(true);
122
123 $result = $this->subject->addData($input);
124
125 $this->assertSame(Permission::CONTENT_EDIT, $result['userPermissionOnPage']);
126 }
127
128 /**
129 * @test
130 */
131 public function addDataThrowsExceptionIfCommandIsEditTableIsPagesAndUserHasNoPagePermissions()
132 {
133 $input = [
134 'tableName' => 'pages',
135 'command' => 'edit',
136 'vanillaUid' => 123,
137 'databaseRow' => [
138 'uid' => 123,
139 'pid' => 321
140 ],
141 ];
142 $this->beUserProphecy->isAdmin()->willReturn(false);
143 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
144 $this->beUserProphecy->calcPerms($input['databaseRow'])->willReturn(Permission::NOTHING);
145
146 $this->setExpectedException(AccessDeniedPageEditException::class, 1437679336);
147
148 $this->subject->addData($input);
149 }
150
151 /**
152 * @test
153 */
154 public function addDataAddsUserPermissionsOnPageIfTableIsPagesAndUserHasPagePermissions()
155 {
156 $input = [
157 'tableName' => 'pages',
158 'command' => 'edit',
159 'vanillaUid' => 123,
160 'databaseRow' => [
161 'uid' => 123,
162 'pid' => 321
163 ],
164 ];
165 $this->beUserProphecy->isAdmin()->willReturn(false);
166 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
167 $this->beUserProphecy->calcPerms($input['databaseRow'])->willReturn(Permission::PAGE_EDIT);
168 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(true);
169
170 $result = $this->subject->addData($input);
171
172 $this->assertSame(Permission::PAGE_EDIT, $result['userPermissionOnPage']);
173 }
174
175 /**
176 * @test
177 */
178 public function addDataSetsPermissionsToAllIfRootLevelRestrictionForTableIsIgnored()
179 {
180 $input = [
181 'tableName' => 'tt_content',
182 'command' => 'edit',
183 'vanillaUid' => 123,
184 'databaseRow' => [
185 'uid' => 123,
186 'pid' => 0,
187 ],
188 ];
189 $this->beUserProphecy->isAdmin()->willReturn(false);
190 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
191 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(true);
192 $GLOBALS['TCA'][$input['tableName']]['ctrl']['security']['ignoreRootLevelRestriction'] = true;
193
194 $result = $this->subject->addData($input);
195
196 $this->assertSame(Permission::ALL, $result['userPermissionOnPage']);
197 }
198
199 /**
200 * @test
201 */
202 public function addDataThrowsExceptionIfRootNodeShouldBeEditedWithoutPermissions()
203 {
204 $input = [
205 'tableName' => 'tt_content',
206 'command' => 'edit',
207 'vanillaUid' => 123,
208 'databaseRow' => [
209 'uid' => 123,
210 'pid' => 0,
211 ],
212 ];
213 $this->beUserProphecy->isAdmin()->willReturn(false);
214 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
215 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(true);
216
217 $this->setExpectedException(AccessDeniedRootNodeException::class, $this->anything(), 1437679856);
218
219 $this->subject->addData($input);
220 }
221
222 /**
223 * @test
224 */
225 public function addDataThrowsExceptionIfRecordEditAccessInternalsReturnsFalse()
226 {
227 $input = [
228 'tableName' => 'tt_content',
229 'command' => 'edit',
230 'vanillaUid' => 123,
231 'parentPageRow' => [
232 'uid' => 123,
233 'pid' => 321,
234 ],
235 ];
236 $this->beUserProphecy->isAdmin()->willReturn(false);
237 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
238 $this->beUserProphecy->calcPerms($input['parentPageRow'])->willReturn(Permission::ALL);
239 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(false);
240
241 $this->setExpectedException(AccessDeniedEditInternalsException::class, $this->anything(), 1437687404);
242
243 $this->subject->addData($input);
244 }
245
246 /**
247 * @test
248 */
249 public function addDataThrowsExceptionForNewContentRecordWithoutPermissions()
250 {
251 $input = [
252 'tableName' => 'tt_content',
253 'command' => 'new',
254 'vanillaUid' => 123,
255 'parentPageRow' => [
256 'uid' => 123,
257 'pid' => 321,
258 ],
259 ];
260 $this->beUserProphecy->isAdmin()->willReturn(false);
261 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
262 $this->beUserProphecy->calcPerms($input['parentPageRow'])->willReturn(Permission::NOTHING);
263
264 $this->setExpectedException(AccessDeniedContentEditException::class, $this->anything(), 1437745759);
265
266 $this->subject->addData($input);
267 }
268
269 /**
270 * @test
271 */
272 public function addDataThrowsExceptionForNewPageWithoutPermissions()
273 {
274 $input = [
275 'tableName' => 'pages',
276 'command' => 'new',
277 'vanillaUid' => 123,
278 'parentPageRow' => [
279 'uid' => 123,
280 'pid' => 321,
281 ],
282 ];
283 $this->beUserProphecy->isAdmin()->willReturn(false);
284 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
285 $this->beUserProphecy->calcPerms($input['parentPageRow'])->willReturn(Permission::NOTHING);
286
287 $this->setExpectedException(AccessDeniedPageNewException::class, $this->anything(), 1437745640);
288
289 $this->subject->addData($input);
290 }
291
292 /**
293 * @test
294 */
295 public function addDataThrowsExceptionIfHookDeniesAccess()
296 {
297 $input = [
298 'tableName' => 'tt_content',
299 'command' => 'edit',
300 'vanillaUid' => 123,
301 'parentPageRow' => [
302 'uid' => 123,
303 'pid' => 321,
304 ],
305 ];
306 $this->beUserProphecy->isAdmin()->willReturn(false);
307 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
308 $this->beUserProphecy->calcPerms($input['parentPageRow'])->willReturn(Permission::ALL);
309 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(true);
310
311 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_doc.php']['makeEditForm_accessCheck'] = array(
312 'unitTest' => function () {
313 return false;
314 }
315 );
316
317 $this->setExpectedException(AccessDeniedHookException::class, $this->anything(), 1437689705);
318
319 $this->subject->addData($input);
320 }
321
322 /**
323 * @test
324 */
325 public function addDataSetsUserPermissionsOnPageForNewPageIfPageNewIsDeniedAndHookAllowsAccess()
326 {
327 $input = [
328 'tableName' => 'pages',
329 'command' => 'new',
330 'vanillaUid' => 123,
331 'parentPageRow' => [
332 'uid' => 123,
333 'pid' => 321,
334 ],
335 ];
336 $this->beUserProphecy->isAdmin()->willReturn(false);
337 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
338 $this->beUserProphecy->calcPerms($input['parentPageRow'])->willReturn(Permission::CONTENT_EDIT);
339 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(true);
340
341 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_doc.php']['makeEditForm_accessCheck'] = array(
342 'unitTest' => function () {
343 return true;
344 }
345 );
346
347 $result = $this->subject->addData($input);
348
349 $this->assertSame(Permission::CONTENT_EDIT, $result['userPermissionOnPage']);
350 }
351
352 /**
353 * @test
354 */
355 public function addDataSetsUserPermissionsOnPageForNewPage()
356 {
357 $input = [
358 'tableName' => 'pages',
359 'command' => 'new',
360 'vanillaUid' => 123,
361 'parentPageRow' => [
362 'uid' => 123,
363 'pid' => 321,
364 ],
365 ];
366 $this->beUserProphecy->isAdmin()->willReturn(false);
367 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
368 $this->beUserProphecy->calcPerms($input['parentPageRow'])->willReturn(Permission::PAGE_NEW);
369 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(true);
370
371 $result = $this->subject->addData($input);
372
373 $this->assertSame(Permission::PAGE_NEW, $result['userPermissionOnPage']);
374 }
375
376 /**
377 * @test
378 */
379 public function addDataSetsUserPermissionsOnPageForNewContentRecord()
380 {
381 $input = [
382 'tableName' => 'tt_content',
383 'command' => 'new',
384 'vanillaUid' => 123,
385 'parentPageRow' => [
386 'uid' => 123,
387 'pid' => 321,
388 ],
389 ];
390 $this->beUserProphecy->isAdmin()->willReturn(false);
391 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
392 $this->beUserProphecy->calcPerms($input['parentPageRow'])->willReturn(Permission::CONTENT_EDIT);
393 $this->beUserProphecy->recordEditAccessInternals($input['tableName'], Argument::cetera())->willReturn(true);
394
395 $result = $this->subject->addData($input);
396
397 $this->assertSame(Permission::CONTENT_EDIT, $result['userPermissionOnPage']);
398 }
399
400 /**
401 * @test
402 */
403 public function addDataThrowsExceptionForNewRecordsOnRootLevelWithoutAdminPermissions()
404 {
405 $input = [
406 'tableName' => 'pages',
407 'command' => 'new',
408 'vanillaUid' => 123,
409 'parentPageRow' => null,
410 ];
411
412 $this->beUserProphecy->isAdmin()->willReturn(false);
413 $this->beUserProphecy->check('tables_modify', $input['tableName'])->willReturn(true);
414
415 $this->setExpectedException(\RuntimeException::class, $this->anything(), 1437745221);
416
417 $this->subject->addData($input);
418 }
419 }