bed28bd021bad818c7cc3c918ecb037581853937
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / FormProtection / BackendFormProtectionTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\FormProtection;
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 the \TYPO3\CMS\Core\FormProtection\BackendFormProtection class.
29 *
30 * @author Oliver Klee <typo3-coding@oliverklee.de>
31 */
32 class BackendFormProtectionTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
33
34 /**
35 * @var \TYPO3\CMS\Core\FormProtection\BackendFormProtection
36 */
37 private $fixture;
38
39 public function setUp() {
40 $GLOBALS['BE_USER'] = $this->getMock(
41 't3lib_beUserAuth',
42 array('getSessionData', 'setAndSaveSessionData')
43 );
44 $GLOBALS['BE_USER']->user['uid'] = 1;
45
46 $className = $this->createAccessibleProxyClass();
47 $this->fixture = $this->getMock($className, array('acquireLock', 'releaseLock'));
48 }
49
50 public function tearDown() {
51 $this->fixture->__destruct();
52 unset($this->fixture);
53 \TYPO3\CMS\Core\Messaging\FlashMessageQueue::getAllMessagesAndFlush();
54 }
55
56
57 //////////////////////
58 // Utility functions
59 //////////////////////
60
61 /**
62 * Creates a subclass \TYPO3\CMS\Core\FormProtection\BackendFormProtection with retrieveTokens made
63 * public.
64 *
65 * @return string the name of the created class, will not be empty
66 */
67 private function createAccessibleProxyClass() {
68 $namespace = 'TYPO3\\CMS\\Core\\FormProtection';
69 $className = 'BackendFormProtectionAccessibleProxy';
70 if (!class_exists($namespace . '\\' .$className)) {
71 eval(
72 'namespace ' . $namespace . ';' .
73 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\FormProtection\\BackendFormProtection {' .
74 ' public function createValidationErrorMessage() {' .
75 ' parent::createValidationErrorMessage();' .
76 ' }' .
77 ' public function retrieveSessionToken() {' .
78 ' return parent::retrieveSessionToken();' .
79 ' }' .
80 ' public function setSessionToken($sessionToken) {' .
81 ' $this->sessionToken = $sessionToken;' .
82 ' }' .
83 '}'
84 );
85 }
86 $className = $namespace . '\\' . $className;
87 return $className;
88 }
89
90 /**
91 * Mock session methods in t3lib_beUserAuth
92 *
93 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication Instance of BE_USER object with mocked session storage methods
94 */
95 private function createBackendUserSessionStorageStub() {
96 $namespace = 'TYPO3\\CMS\\Core\\Authentication';
97 $className = 'BackendUserAuthenticationMocked';
98 if (!class_exists($namespace . '\\' .$className)) {
99 eval(
100 'namespace ' . $namespace . ';' .
101 'class ' . $className . ' extends \\TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication {' .
102 ' protected $session=array();' .
103 ' public function getSessionData($key) {' .
104 ' return $this->session[$key];' .
105 ' }' .
106 ' public function setAndSaveSessionData($key, $data) {' .
107 ' $this->session[$key] = $data;' .
108 ' }' .
109 '}'
110 );
111 }
112 $className = $namespace . '\\' . $className;
113 return $this->getMock($className, array('foo'));// $className;
114 }
115
116 ////////////////////////////////////
117 // Tests for the utility functions
118 ////////////////////////////////////
119
120 /**
121 * @test
122 */
123 public function createAccessibleProxyCreatesBackendFormProtectionSubclass() {
124 $className = $this->createAccessibleProxyClass();
125
126 $this->assertTrue(
127 (new $className()) instanceof \TYPO3\CMS\Core\FormProtection\BackendFormProtection
128 );
129 }
130
131 /**
132 * @test
133 */
134 public function createBackendUserSessionStorageStubWorkProperly() {
135 $GLOBALS['BE_USER'] = $this->createBackendUserSessionStorageStub();
136
137 $allTokens = array(
138 '12345678' => array(
139 'formName' => 'foo',
140 'action' => 'edit',
141 'formInstanceName' => '42'
142 ),
143 );
144
145 $GLOBALS['BE_USER']->setAndSaveSessionData('tokens', $allTokens);
146
147 $this->assertEquals($GLOBALS['BE_USER']->getSessionData('tokens'), $allTokens);
148 }
149
150
151 //////////////////////////////////////////////////////////
152 // Tests concerning the reading and saving of the tokens
153 //////////////////////////////////////////////////////////
154
155 /**
156 * @test
157 */
158 public function retrieveTokenReadsTokenFromSessionData() {
159 $GLOBALS['BE_USER']->expects($this->once())->method('getSessionData')
160 ->with('formSessionToken')->will($this->returnValue(array()));
161
162 $this->fixture->retrieveSessionToken();
163 }
164
165 /**
166 * @test
167 */
168 public function tokenFromSessionDataIsAvailableForValidateToken() {
169 $sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
170 $formName = 'foo';
171 $action = 'edit';
172 $formInstanceName = '42';
173
174 $tokenId = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac($formName . $action . $formInstanceName . $sessionToken);
175
176 $GLOBALS['BE_USER']->expects($this->atLeastOnce())->method('getSessionData')
177 ->with('formSessionToken')
178 ->will($this->returnValue($sessionToken));
179
180 $this->fixture->retrieveSessionToken();
181
182 $this->assertTrue(
183 $this->fixture->validateToken($tokenId, $formName, $action, $formInstanceName)
184 );
185 }
186
187 /**
188 * @expectedException UnexpectedValueException
189 * @test
190 */
191 public function restoreSessionTokenFromRegistryThrowsExceptionIfSessionTokenIsEmpty() {
192 $this->fixture->injectRegistry(
193 $this->getMock('t3lib_Registry')
194 );
195 $this->fixture->setSessionTokenFromRegistry();
196 }
197
198 /**
199 * @test
200 */
201 public function persistSessionTokenWritesTokenToSession() {
202 $sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
203 $this->fixture->setSessionToken($sessionToken);
204
205 $GLOBALS['BE_USER']->expects($this->once())
206 ->method('setAndSaveSessionData')->with('formSessionToken', $sessionToken);
207
208 $this->fixture->persistSessionToken();
209 }
210
211
212 //////////////////////////////////////////////////
213 // Tests concerning createValidationErrorMessage
214 //////////////////////////////////////////////////
215
216 /**
217 * @test
218 */
219 public function createValidationErrorMessageAddsErrorFlashMessage() {
220 $GLOBALS['BE_USER'] = $this->createBackendUserSessionStorageStub();
221 $this->fixture->createValidationErrorMessage();
222
223 $messages = \TYPO3\CMS\Core\Messaging\FlashMessageQueue::getAllMessagesAndFlush();
224
225 $this->assertNotEmpty($messages);
226 $this->assertContains(
227 $GLOBALS['LANG']->sL(
228 'LLL:EXT:lang/locallang_core.xml:error.formProtection.tokenInvalid'
229 ),
230 $messages[0]->render()
231 );
232 }
233
234 /**
235 * @test
236 */
237 public function createValidationErrorMessageAddsErrorFlashMessageButNotInSessionInAjaxRequest() {
238 $GLOBALS['BE_USER'] = $this->createBackendUserSessionStorageStub();
239 $GLOBALS['TYPO3_AJAX'] = TRUE;
240 $this->fixture->createValidationErrorMessage();
241
242 $messages = \TYPO3\CMS\Core\Messaging\FlashMessageQueue::getAllMessages();
243
244 $this->assertNotEmpty($messages);
245 $this->assertContains(
246 $GLOBALS['LANG']->sL(
247 'LLL:EXT:lang/locallang_core.xml:error.formProtection.tokenInvalid'
248 ),
249 $messages[0]->render()
250 );
251 }
252 }
253 ?>