Raised DBAL version from 1.1.5 to 1.1.6
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Security / Channel / RequestHashService_testcase.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Sebastian Kurfürst <sebastian@typo3.org>
6 * All rights reserved
7 *
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * Testcase for the Request Hash Service
30 *
31 * @version $Id: RequestHashService_testcase.php 1729 2009-11-25 21:37:20Z stucki $
32 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser Public License, version 3 or later
33 */
34 class Tx_Extbase_Security_Channel_RequestHashService_testcase extends Tx_Extbase_BaseTestCase {
35
36 public function dataProviderForGenerateRequestHash() {
37 return array(
38 // Simple cases
39 array(
40 array(),
41 array(),
42 ),
43 array(
44 array('field1'),
45 array('field1' => 1),
46 ),
47 array(
48 array('field1', 'field2'),
49 array(
50 'field1' => 1,
51 'field2' => 1
52 ),
53 ),
54 // recursion
55 array(
56 array('field1', 'field[subfield1]', 'field[subfield2]'),
57 array(
58 'field1' => 1,
59 'field' => array(
60 'subfield1' => 1,
61 'subfield2' => 1
62 )
63 ),
64 ),
65 // recursion with duplicated field name
66 array(
67 array('field1', 'field[subfield1]', 'field[subfield2]', 'field1'),
68 array(
69 'field1' => 1,
70 'field' => array(
71 'subfield1' => 1,
72 'subfield2' => 1
73 )
74 ),
75 ),
76 // Recursion with un-named fields at the end (...[]). There, they should be made explicit by increasing the counter
77 array(
78 array('field1', 'field[subfield1][]', 'field[subfield1][]', 'field[subfield2]'),
79 array(
80 'field1' => 1,
81 'field' => array(
82 'subfield1' => array(
83 0 => 1,
84 1 => 1
85 ),
86 'subfield2' => 1
87 )
88 ),
89 ),
90 );
91 }
92
93 // Data provider for error cases which should throw an exception
94 public function dataProviderForGenerateRequestHashWithUnallowedValues() {
95 return array(
96 // Overriding form fields (string overridden by array)
97 array(
98 array('field1', 'field2', 'field2[bla]', 'field2[blubb]'),
99 ),
100 array(
101 array('field1', 'field2[bla]', 'field2[bla][blubb][blubb]'),
102 ),
103 // Overriding form fields (array overridden by string)
104 array(
105 array('field1', 'field2[bla]', 'field2[blubb]', 'field2'),
106 ),
107 array(
108 array('field1', 'field2[bla][blubb][blubb]', 'field2[bla]'),
109 ),
110 // Empty [] not as last argument
111 array(
112 array('field1', 'field2[][bla]'),
113 )
114
115 );
116 }
117
118 /**
119 * @test
120 * @author Sebastian Kurfürst <sebastian@typo3.org>
121 * @dataProvider dataProviderForGenerateRequestHash
122 */
123 public function generateRequestHashGeneratesTheCorrectHashesInNormalOperation($input, $expected) {
124 $requestHashService = $this->getMock('Tx_Extbase_Security_Channel_RequestHashService', array('serializeAndHashFormFieldArray'));
125 $requestHashService->expects($this->once())->method('serializeAndHashFormFieldArray')->with($expected);
126 $requestHashService->generateRequestHash($input);
127 }
128
129 /**
130 * @test
131 * @author Sebastian Kurfürst <sebastian@typo3.org>
132 * @dataProvider dataProviderForGenerateRequestHashWithUnallowedValues
133 * @expectedException Tx_Extbase_Security_Exception_InvalidArgumentForRequestHashGeneration
134 */
135 public function generateRequestHashThrowsExceptionInWrongCases($input) {
136 $requestHashService = $this->getMock('Tx_Extbase_Security_Channel_RequestHashService', array('serializeAndHashFormFieldArray'));
137 $requestHashService->generateRequestHash($input);
138 }
139
140 /**
141 * @test
142 * @author Sebastian Kurfürst <sebastian@typo3.org>
143 */
144 public function serializeAndHashFormFieldArrayWorks() {
145 $formFieldArray = array(
146 'bla' => array(
147 'blubb' => 1,
148 'hu' => 1
149 )
150 );
151 $mockHash = '12345';
152
153 $hashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Cryptography_HashService'), array('generateHash'));
154 $hashService->expects($this->once())->method('generateHash')->with(serialize($formFieldArray))->will($this->returnValue($mockHash));
155
156 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy'));
157 $requestHashService->_set('hashService', $hashService);
158
159 $expected = serialize($formFieldArray) . $mockHash;
160 $actual = $requestHashService->_call('serializeAndHashFormFieldArray', $formFieldArray);
161 $this->assertEquals($expected, $actual);
162 }
163
164 /**
165 * @test
166 * @author Sebastian Kurfürst
167 */
168 public function verifyRequestHashSetsHmacVerifiedToFalseIfRequestDoesNotHaveAnHmacArgument() {
169 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'setHmacVerified'));
170 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(FALSE));
171 $request->expects($this->once())->method('setHmacVerified')->with(FALSE);
172 $requestHashService = new Tx_Extbase_Security_Channel_RequestHashService;
173 $requestHashService->verifyRequest($request);
174 }
175
176 /**
177 * @test
178 * @expectedException Tx_Extbase_Security_Exception_SyntacticallyWrongRequestHash
179 * @author Sebastian Kurfürst
180 */
181 public function verifyRequestHashThrowsExceptionIfHmacIsShortherThan40Characters() {
182 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'setHmacVerified'));
183 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
184 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue('abc'));
185 $requestHashService = new Tx_Extbase_Security_Channel_RequestHashService;
186 $requestHashService->verifyRequest($request);
187 }
188
189 /**
190 * @test
191 * @author Sebastian Kurfürst
192 */
193 public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToFalseIfHashCouldNotBeVerified() {
194 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'setHmacVerified'));
195 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
196 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue('11111' . '0000000000000000000000000000000000000000'));
197 $request->expects($this->once())->method('setHmacVerified')->with(FALSE);
198
199 $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash'));
200 $hashService->expects($this->once())->method('validateHash')->with('11111', '0000000000000000000000000000000000000000')->will($this->returnValue(FALSE));
201
202 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy'));
203 $requestHashService->_set('hashService', $hashService);
204 $requestHashService->verifyRequest($request);
205 }
206
207 /**
208 * @test
209 * @author Sebastian Kurfürst
210 */
211 public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToTrueIfArgumentsAreIncludedInTheAllowedArgumentList() {
212 $data = serialize(array('a' => 1));
213 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'getArguments', 'setHmacVerified'));
214 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
215 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue($data . '0000000000000000000000000000000000000000'));
216 $request->expects($this->once())->method('getArguments')->will($this->returnValue(array(
217 '__hmac' => 'ABC',
218 '__referrer' => '...',
219 'a' => 'bla'
220 )));
221 $request->expects($this->once())->method('setHmacVerified')->with(TRUE);
222
223 $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash'));
224 $hashService->expects($this->once())->method('validateHash')->with($data, '0000000000000000000000000000000000000000')->will($this->returnValue(TRUE));
225
226 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('checkFieldNameInclusion'));
227 $requestHashService->expects($this->once())->method('checkFieldNameInclusion')->with(array('a' => 'bla'), array('a' => 1))->will($this->returnValue(TRUE));
228 $requestHashService->_set('hashService', $hashService);
229 $requestHashService->verifyRequest($request);
230 }
231
232 /**
233 * @test
234 * @author Sebastian Kurfürst
235 */
236 public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToFalseIfNotAllArgumentsAreIncludedInTheAllowedArgumentList() {
237 $data = serialize(array('a' => 1));
238 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'getArguments', 'setHmacVerified'));
239 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE));
240 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue($data . '0000000000000000000000000000000000000000'));
241 $request->expects($this->once())->method('getArguments')->will($this->returnValue(array(
242 '__hmac' => 'ABC',
243 '__referrer' => '...',
244 'a' => 'bla',
245 'b' => 'blubb'
246 )));
247 $request->expects($this->once())->method('setHmacVerified')->with(FALSE);
248
249 $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash'));
250 $hashService->expects($this->once())->method('validateHash')->with($data, '0000000000000000000000000000000000000000')->will($this->returnValue(TRUE));
251
252 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('checkFieldNameInclusion'));
253 $requestHashService->expects($this->once())->method('checkFieldNameInclusion')->with(array('a' => 'bla', 'b' => 'blubb'), array('a' => 1))->will($this->returnValue(FALSE));
254 $requestHashService->_set('hashService', $hashService);
255 $requestHashService->verifyRequest($request);
256 }
257
258 /**
259 * Data Provider for checkFieldNameInclusionWorks
260 */
261 public function dataProviderForCheckFieldNameInclusion() {
262 return array(
263 // Simple fields with requestfields = responsefields
264 array(
265 // Request
266 array(
267 'a' => 'X',
268 'b' => 'X',
269 'c' => 'X'
270 ),
271 // Allowed
272 array(
273 'a' => 1,
274 'b' => 1,
275 'c' => 1
276 ),
277 // Expected result
278 TRUE
279 ),
280 // Simple fields with requestfields < responsefields
281 array(
282 // Request
283 array(
284 'a' => 'X',
285 'c' => 'X'
286 ),
287 // Allowed
288 array(
289 'a' => 1,
290 'b' => 1,
291 'c' => 1
292 ),
293 // Expected result
294 TRUE
295 ),
296 // Simple fields with requestfields > responsefields
297 array(
298 // Request
299 array(
300 'a' => 'X',
301 'b' => 'X',
302 'c' => 'X'
303 ),
304 // Allowed
305 array(
306 'a' => 1,
307 'b' => 1
308 ),
309 // Expected result
310 FALSE
311 ),
312 // Hierarchical fields with requestfields < responsefields
313 array(
314 // Request
315 array(
316 'a' => array(
317 'b' => 'X'
318 ),
319 'c' => 'X'
320 ),
321 // Allowed
322 array(
323 'a' => array(
324 'b' => 1,
325 'abc' => 1
326 ),
327 'c' => 1
328 ),
329 // Expected result
330 TRUE
331 ),
332 // Hierarchical fields with requestfields > responsefields
333 array(
334 // Request
335 array(
336 'a' => array(
337 'b' => 'X',
338 'abc' => 'X'
339 ),
340 'c' => 'X'
341 ),
342 // Allowed
343 array(
344 'a' => array(
345 'b' => 1
346 ),
347 'c' => 1
348 ),
349 // Expected result
350 FALSE
351 ),
352 // hierarchical fields with requestfields != responsefields (different types) - 1
353 array(
354 // Request
355 array(
356 'a' => array(
357 'b' => 'X',
358 'c' => 'X'
359 ),
360 'b' => 'X',
361 'c' => 'X'
362 ),
363 // Allowed
364 array(
365 'a' => 1,
366 'b' => 1,
367 'c' => 1
368 ),
369 // Expected result
370 FALSE
371 ),
372 // hierarchical fields with requestfields != responsefields (different types) - 2
373 array(
374 // Request
375 array(
376 'a' => 'X',
377 'b' => 'X',
378 'c' => 'X'
379 ),
380 // Allowed
381 array(
382 'a' => array(
383 'x' => 1,
384 'y' => 1
385 ),
386 'b' => 1,
387 'c' => 1
388 ),
389 // Expected result
390 FALSE
391 ),
392 );
393 }
394
395 /**
396 * @test
397 * @author Sebastian Kurfürst <sebastian@typo3.org>
398 * @dataProvider dataProviderForCheckFieldNameInclusion
399 */
400 public function checkFieldNameInclusionWorks($requestArguments, $allowedFields, $expectedResult) {
401 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy'));
402 $this->assertEquals($expectedResult, $requestHashService->_call('checkFieldNameInclusion', $requestArguments, $allowedFields));
403 }
404 }
405 ?>