871de06191c15866c07f284b26eda4e181dcc74f
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Authentication / BackendUserAuthenticationTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Authentication;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 Oliver Klee (typo3-coding@oliverklee.de)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 /**
28 * Testcase for \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
29 *
30 * @author Oliver Klee <typo3-coding@oliverklee.de>
31 */
32 class BackendUserAuthenticationTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
33 /**
34 * @var array
35 */
36 protected $defaultFilePermissions = array(
37 // File permissions
38 'addFile' => FALSE,
39 'readFile' => FALSE,
40 'writeFile' => FALSE,
41 'copyFile' => FALSE,
42 'moveFile' => FALSE,
43 'renameFile' => FALSE,
44 'unzipFile' => FALSE,
45 'deleteFile' => FALSE,
46 // Folder permissions
47 'addFolder' => FALSE,
48 'readFolder' => FALSE,
49 'writeFolder' => FALSE,
50 'copyFolder' => FALSE,
51 'moveFolder' => FALSE,
52 'renameFolder' => FALSE,
53 'deleteFolder' => FALSE,
54 'recursivedeleteFolder' => FALSE
55 );
56
57 public function setUp() {
58 // reset hooks
59 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'] = array();
60 }
61
62 public function tearDown() {
63 \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::purgeInstances();
64 parent::tearDown();
65 }
66
67 /////////////////////////////////////////
68 // Tests concerning the form protection
69 /////////////////////////////////////////
70 /**
71 * @test
72 */
73 public function logoffCleansFormProtectionIfBackendUserIsLoggedIn() {
74 $formProtection = $this->getMock(
75 'TYPO3\\CMS\\Core\\FormProtection\\BackendFormProtection',
76 array('clean'),
77 array(),
78 '',
79 FALSE
80 );
81 $formProtection->expects($this->once())->method('clean');
82
83 \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::set(
84 'TYPO3\\CMS\\Core\\FormProtection\\BackendFormProtection',
85 $formProtection
86 );
87
88 // logoff() call the static factory that has a dependency to a valid BE_USER object. Mock this away
89 $GLOBALS['BE_USER'] = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array(), array(), '', FALSE);
90 $GLOBALS['BE_USER']->user = array('uid' => uniqid());
91 $GLOBALS['TYPO3_DB'] = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection', array(), array(), '', FALSE);
92
93 $subject = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array('dummy'), array(), '', FALSE);
94 $subject->_set('db', $GLOBALS['TYPO3_DB']);
95 $subject->logoff();
96 }
97
98 /**
99 * @return array
100 */
101 public function getTSConfigDataProvider() {
102 $completeConfiguration = array(
103 'value' => 'oneValue',
104 'value.' => array('oneProperty' => 'oneValue'),
105 'permissions.' => array(
106 'file.' => array(
107 'default.' => array('readAction' => '1'),
108 '1.' => array('writeAction' => '1'),
109 '0.' => array('readAction' => '0'),
110 ),
111 )
112 );
113
114 return array(
115 'single level string' => array(
116 $completeConfiguration,
117 'permissions',
118 array(
119 'value' => NULL,
120 'properties' =>
121 array(
122 'file.' => array(
123 'default.' => array('readAction' => '1'),
124 '1.' => array('writeAction' => '1'),
125 '0.' => array('readAction' => '0'),
126 ),
127 ),
128 ),
129 ),
130 'two levels string' => array(
131 $completeConfiguration,
132 'permissions.file',
133 array(
134 'value' => NULL,
135 'properties' =>
136 array(
137 'default.' => array('readAction' => '1'),
138 '1.' => array('writeAction' => '1'),
139 '0.' => array('readAction' => '0'),
140 ),
141 ),
142 ),
143 'three levels string' => array(
144 $completeConfiguration,
145 'permissions.file.default',
146 array(
147 'value' => NULL,
148 'properties' =>
149 array('readAction' => '1'),
150 ),
151 ),
152 'three levels string with integer property' => array(
153 $completeConfiguration,
154 'permissions.file.1',
155 array(
156 'value' => NULL,
157 'properties' => array('writeAction' => '1'),
158 ),
159 ),
160 'three levels string with integer zero property' => array(
161 $completeConfiguration,
162 'permissions.file.0',
163 array(
164 'value' => NULL,
165 'properties' => array('readAction' => '0'),
166 ),
167 ),
168 'four levels string with integer zero property, value, no properties' => array(
169 $completeConfiguration,
170 'permissions.file.0.readAction',
171 array(
172 'value' => '0',
173 'properties' => NULL,
174 ),
175 ),
176 'four levels string with integer property, value, no properties' => array(
177 $completeConfiguration,
178 'permissions.file.1.writeAction',
179 array(
180 'value' => '1',
181 'properties' => NULL,
182 ),
183 ),
184 'one level, not existant string' => array(
185 $completeConfiguration,
186 'foo',
187 array(
188 'value' => NULL,
189 'properties' => NULL,
190 ),
191 ),
192 'two level, not existant string' => array(
193 $completeConfiguration,
194 'foo.bar',
195 array(
196 'value' => NULL,
197 'properties' => NULL,
198 ),
199 ),
200 'two level, where second level does not exist' => array(
201 $completeConfiguration,
202 'permissions.bar',
203 array(
204 'value' => NULL,
205 'properties' => NULL,
206 ),
207 ),
208 'three level, where third level does not exist' => array(
209 $completeConfiguration,
210 'permissions.file.foo',
211 array(
212 'value' => NULL,
213 'properties' => NULL,
214 ),
215 ),
216 'three level, where second and third level does not exist' => array(
217 $completeConfiguration,
218 'permissions.foo.bar',
219 array(
220 'value' => NULL,
221 'properties' => NULL,
222 ),
223 ),
224 'value and properties' => array(
225 $completeConfiguration,
226 'value',
227 array(
228 'value' => 'oneValue',
229 'properties' => array('oneProperty' => 'oneValue'),
230 ),
231 ),
232 );
233 }
234
235 /**
236 * @param array $completeConfiguration
237 * @param string $objectString
238 * @param array $expectedConfiguration
239 * @dataProvider getTSConfigDataProvider
240 * @test
241 */
242 public function getTSConfigReturnsCorrectArrayForGivenObjectString(array $completeConfiguration, $objectString, array $expectedConfiguration) {
243 $subject = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array('dummy'), array(), '', FALSE);
244 $subject->userTS = $completeConfiguration;
245
246 $actualConfiguration = $subject->getTSConfig($objectString);
247 $this->assertSame($expectedConfiguration, $actualConfiguration);
248 }
249
250 /**
251 * @return array
252 */
253 public function getFilePermissionsTakesUserDefaultAndStoragePermissionsIntoAccountIfUserIsNotAdminDataProvider() {
254 return array(
255 'Only read permissions' => array(
256 array(
257 'addFile' => 0,
258 'readFile' => 1,
259 'writeFile' => 0,
260 'copyFile' => 0,
261 'moveFile' => 0,
262 'renameFile' => 0,
263 'unzipFile' => 0,
264 'deleteFile' => 0,
265 'addFolder' => 0,
266 'readFolder' => 1,
267 'copyFolder' => 0,
268 'moveFolder' => 0,
269 'renameFolder' => 0,
270 'writeFolder' => 0,
271 'deleteFolder' => 0,
272 'recursivedeleteFolder' => 0,
273 )
274 ),
275 'Uploading allowed' => array(
276 array(
277 'addFile' => 1,
278 'readFile' => 1,
279 'writeFile' => 1,
280 'copyFile' => 1,
281 'moveFile' => 1,
282 'renameFile' => 1,
283 'unzipFile' => 0,
284 'deleteFile' => 1,
285 'addFolder' => 0,
286 'readFolder' => 1,
287 'copyFolder' => 0,
288 'moveFolder' => 0,
289 'renameFolder' => 0,
290 'writeFolder' => 0,
291 'deleteFolder' => 0,
292 'recursivedeleteFolder' => 0
293 )
294 ),
295 'One value is enough' => array(
296 array(
297 'addFile' => 1,
298 )
299 ),
300 );
301 }
302
303 /**
304 * @param array $userTsConfiguration
305 * @test
306 * @dataProvider getFilePermissionsTakesUserDefaultAndStoragePermissionsIntoAccountIfUserIsNotAdminDataProvider
307 */
308 public function getFilePermissionsTakesUserDefaultPermissionsFromTsConfigIntoAccountIfUserIsNotAdmin(array $userTsConfiguration) {
309 $subject = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array('isAdmin'));
310
311 $subject
312 ->expects($this->any())
313 ->method('isAdmin')
314 ->will($this->returnValue(FALSE));
315
316 $subject->userTS = array(
317 'permissions.' => array(
318 'file.' => array(
319 'default.' => $userTsConfiguration
320 ),
321 )
322 );
323
324 $expectedPermissions = array_merge($this->defaultFilePermissions, $userTsConfiguration);
325 array_walk(
326 $expectedPermissions,
327 function(&$value) {
328 $value = (bool) $value;
329 }
330 );
331
332 $this->assertEquals($expectedPermissions, $subject->getFilePermissions());
333 }
334
335 /**
336 * @return array
337 */
338 public function getFilePermissionsFromStorageDataProvider() {
339 $defaultPermissions = array(
340 'addFile' => TRUE,
341 'readFile' => TRUE,
342 'writeFile' => TRUE,
343 'copyFile' => TRUE,
344 'moveFile' => TRUE,
345 'renameFile' => TRUE,
346 'unzipFile' => TRUE,
347 'deleteFile' => TRUE,
348 'addFolder' => TRUE,
349 'readFolder' => TRUE,
350 'copyFolder' => TRUE,
351 'moveFolder' => TRUE,
352 'renameFolder' => TRUE,
353 'writeFolder' => TRUE,
354 'deleteFolder' => TRUE,
355 'recursivedeleteFolder' => TRUE
356 );
357
358 return array(
359 'Overwrites given storage permissions with default permissions' => array(
360 $defaultPermissions,
361 1,
362 array(
363 'addFile' => 0,
364 'recursivedeleteFolder' =>0
365 ),
366 array(
367 'addFile' => 0,
368 'readFile' => 1,
369 'writeFile' => 1,
370 'copyFile' => 1,
371 'moveFile' => 1,
372 'renameFile' => 1,
373 'unzipFile' => 1,
374 'deleteFile' => 1,
375 'addFolder' => 1,
376 'readFolder' => 1,
377 'copyFolder' => 1,
378 'moveFolder' => 1,
379 'renameFolder' => 1,
380 'writeFolder' => 1,
381 'deleteFolder' => 1,
382 'recursivedeleteFolder' => 0
383 )
384 ),
385 'Overwrites given storage 0 permissions with default permissions' => array(
386 $defaultPermissions,
387 0,
388 array(
389 'addFile' => 0,
390 'recursivedeleteFolder' =>0
391 ),
392 array(
393 'addFile' => FALSE,
394 'readFile' => TRUE,
395 'writeFile' => TRUE,
396 'copyFile' => TRUE,
397 'moveFile' => TRUE,
398 'renameFile' => TRUE,
399 'unzipFile' => TRUE,
400 'deleteFile' => TRUE,
401 'addFolder' => TRUE,
402 'readFolder' => TRUE,
403 'copyFolder' => TRUE,
404 'moveFolder' => TRUE,
405 'renameFolder' => TRUE,
406 'writeFolder' => TRUE,
407 'deleteFolder' => TRUE,
408 'recursivedeleteFolder' => FALSE
409 )
410 ),
411 'Returns default permissions if no storage permissions are found' => array(
412 $defaultPermissions,
413 1,
414 array(),
415 array(
416 'addFile' => TRUE,
417 'readFile' => TRUE,
418 'writeFile' => TRUE,
419 'copyFile' => TRUE,
420 'moveFile' => TRUE,
421 'renameFile' => TRUE,
422 'unzipFile' => TRUE,
423 'deleteFile' => TRUE,
424 'addFolder' => TRUE,
425 'readFolder' => TRUE,
426 'copyFolder' => TRUE,
427 'moveFolder' => TRUE,
428 'renameFolder' => TRUE,
429 'writeFolder' => TRUE,
430 'deleteFolder' => TRUE,
431 'recursivedeleteFolder' => TRUE
432 )
433 ),
434 );
435 }
436
437 /**
438 * @param array $defaultPermissions
439 * @param integer $storageUid
440 * @param array $storagePermissions
441 * @param array $expectedPermissions
442 * @test
443 * @dataProvider getFilePermissionsFromStorageDataProvider
444 */
445 public function getFilePermissionsFromStorageOverwritesDefaultPermissions(array $defaultPermissions, $storageUid, array $storagePermissions, array $expectedPermissions) {
446 $subject = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array('isAdmin', 'getFilePermissions'));
447 $storageMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
448 $storageMock->expects($this->any())->method('getUid')->will($this->returnValue($storageUid));
449
450 $subject
451 ->expects($this->any())
452 ->method('isAdmin')
453 ->will($this->returnValue(FALSE));
454
455 $subject
456 ->expects($this->any())
457 ->method('getFilePermissions')
458 ->will($this->returnValue($defaultPermissions));
459
460 $subject->userTS = array(
461 'permissions.' => array(
462 'file.' => array(
463 'storage.' => array(
464 $storageUid . '.' => $storagePermissions
465 ),
466 ),
467 )
468 );
469
470 $this->assertEquals($expectedPermissions, $subject->getFilePermissionsForStorage($storageMock));
471 }
472
473 /**
474 * @param array $defaultPermissions
475 * @param $storageUid
476 * @param array $storagePermissions
477 * @test
478 * @dataProvider getFilePermissionsFromStorageDataProvider
479 */
480 public function getFilePermissionsFromStorageAlwaysReturnsDefaultPermissionsForAdmins(array $defaultPermissions, $storageUid, array $storagePermissions) {
481 $subject = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array('isAdmin', 'getFilePermissions'));
482 $storageMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
483 $storageMock->expects($this->any())->method('getUid')->will($this->returnValue($storageUid));
484
485 $subject
486 ->expects($this->any())
487 ->method('isAdmin')
488 ->will($this->returnValue(TRUE));
489
490 $subject
491 ->expects($this->any())
492 ->method('getFilePermissions')
493 ->will($this->returnValue($defaultPermissions));
494
495 $subject->userTS = array(
496 'permissions.' => array(
497 'file.' => array(
498 'storage.' => array(
499 $storageUid . '.' => $storagePermissions
500 ),
501 ),
502 )
503 );
504
505 $this->assertEquals($defaultPermissions, $subject->getFilePermissionsForStorage($storageMock));
506 }
507
508 /**
509 * @return array
510 */
511 public function getFilePermissionsTakesUserDefaultPermissionsFromRecordIntoAccountIfUserIsNotAdminDataProvider() {
512 return array(
513 'No permission' => array(
514 '',
515 array(
516 'addFile' => FALSE,
517 'readFile' => FALSE,
518 'writeFile' => FALSE,
519 'copyFile' => FALSE,
520 'moveFile' => FALSE,
521 'renameFile' => FALSE,
522 'unzipFile' => FALSE,
523 'deleteFile' => FALSE,
524 'addFolder' => FALSE,
525 'readFolder' => FALSE,
526 'copyFolder' => FALSE,
527 'moveFolder' => FALSE,
528 'renameFolder' => FALSE,
529 'writeFolder' => FALSE,
530 'deleteFolder' => FALSE,
531 'recursivedeleteFolder' => FALSE
532 )
533 ),
534 'Standard file permissions' => array(
535 'addFile,readFile,writeFile,copyFile,moveFile,renameFile,deleteFile',
536 array(
537 'addFile' => TRUE,
538 'readFile' => TRUE,
539 'writeFile' => TRUE,
540 'copyFile' => TRUE,
541 'moveFile' => TRUE,
542 'renameFile' => TRUE,
543 'unzipFile' => FALSE,
544 'deleteFile' => TRUE,
545 'addFolder' => FALSE,
546 'readFolder' => FALSE,
547 'copyFolder' => FALSE,
548 'moveFolder' => FALSE,
549 'renameFolder' => FALSE,
550 'writeFolder' => FALSE,
551 'deleteFolder' => FALSE,
552 'recursivedeleteFolder' => FALSE
553 )
554 ),
555 'Unzip allowed' => array(
556 'readFile,unzipFile',
557 array(
558 'addFile' => FALSE,
559 'readFile' => TRUE,
560 'writeFile' => FALSE,
561 'copyFile' => FALSE,
562 'moveFile' => FALSE,
563 'renameFile' => FALSE,
564 'unzipFile' => TRUE,
565 'deleteFile' => FALSE,
566 'addFolder' => FALSE,
567 'readFolder' => FALSE,
568 'writeFolder' => FALSE,
569 'copyFolder' => FALSE,
570 'moveFolder' => FALSE,
571 'renameFolder' => FALSE,
572 'deleteFolder' => FALSE,
573 'recursivedeleteFolder' => FALSE
574 )
575 ),
576 'Standard folder permissions' => array(
577 'addFolder,readFolder,moveFolder,renameFolder,writeFolder,deleteFolder',
578 array(
579 'addFile' => FALSE,
580 'readFile' => FALSE,
581 'writeFile' => FALSE,
582 'copyFile' => FALSE,
583 'moveFile' => FALSE,
584 'renameFile' => FALSE,
585 'unzipFile' => FALSE,
586 'deleteFile' => FALSE,
587 'addFolder' => TRUE,
588 'readFolder' => TRUE,
589 'writeFolder' => TRUE,
590 'copyFolder' => FALSE,
591 'moveFolder' => TRUE,
592 'renameFolder' => TRUE,
593 'deleteFolder' => TRUE,
594 'recursivedeleteFolder' => FALSE
595 )
596 ),
597 'Copy folder allowed' => array(
598 'readFolder,copyFolder',
599 array(
600 'addFile' => FALSE,
601 'readFile' => FALSE,
602 'writeFile' => FALSE,
603 'copyFile' => FALSE,
604 'moveFile' => FALSE,
605 'renameFile' => FALSE,
606 'unzipFile' => FALSE,
607 'deleteFile' => FALSE,
608 'addFolder' => FALSE,
609 'readFolder' => TRUE,
610 'writeFolder' => FALSE,
611 'copyFolder' => TRUE,
612 'moveFolder' => FALSE,
613 'renameFolder' => FALSE,
614 'deleteFolder' => FALSE,
615 'recursivedeleteFolder' => FALSE
616 )
617 ),
618 'Copy folder and remove subfolders allowed' => array(
619 'readFolder,copyFolder,recursivedeleteFolder',
620 array(
621 'addFile' => FALSE,
622 'readFile' => FALSE,
623 'writeFile' => FALSE,
624 'copyFile' => FALSE,
625 'moveFile' => FALSE,
626 'renameFile' => FALSE,
627 'unzipFile' => FALSE,
628 'deleteFile' => FALSE,
629 'addFolder' => FALSE,
630 'readFolder' => TRUE,
631 'writeFolder' => FALSE,
632 'copyFolder' => TRUE,
633 'moveFolder' => FALSE,
634 'renameFolder' => FALSE,
635 'deleteFolder' => FALSE,
636 'recursivedeleteFolder' => TRUE
637 )
638 ),
639 );
640 }
641
642 /**
643 * @test
644 * @dataProvider getFilePermissionsTakesUserDefaultPermissionsFromRecordIntoAccountIfUserIsNotAdminDataProvider
645 */
646 public function getFilePermissionsTakesUserDefaultPermissionsFromRecordIntoAccountIfUserIsNotAdmin($permissionValue, $expectedPermissions) {
647 $subject = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array('isAdmin'));
648
649 $subject
650 ->expects($this->any())
651 ->method('isAdmin')
652 ->will($this->returnValue(FALSE));
653
654 $subject->userTS = array();
655 $subject->groupData['file_permissions'] = $permissionValue;
656 $this->assertEquals($expectedPermissions, $subject->getFilePermissions());
657 }
658
659 /**
660 * @test
661 */
662 public function getFilePermissionsGrantsAllPermissionsToAdminUsers() {
663 $subject = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication', array('isAdmin'));
664
665 $subject
666 ->expects($this->any())
667 ->method('isAdmin')
668 ->will($this->returnValue(TRUE));
669
670 $expectedPermissions = array(
671 'addFile' => TRUE,
672 'readFile' => TRUE,
673 'writeFile' => TRUE,
674 'copyFile' => TRUE,
675 'moveFile' => TRUE,
676 'renameFile' => TRUE,
677 'unzipFile' => TRUE,
678 'deleteFile' => TRUE,
679 'addFolder' => TRUE,
680 'readFolder' => TRUE,
681 'writeFolder' => TRUE,
682 'copyFolder' => TRUE,
683 'moveFolder' => TRUE,
684 'renameFolder' => TRUE,
685 'deleteFolder' => TRUE,
686 'recursivedeleteFolder' => TRUE
687 );
688
689 $this->assertEquals($expectedPermissions, $subject->getFilePermissions());
690 }
691
692 }