|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2009 Sebastian Kurfürst <sebastian@typo3.org> 00006 * All rights reserved 00007 * 00008 * This class is a backport of the corresponding class of FLOW3. 00009 * All credits go to the v5 team. 00010 * 00011 * This script is part of the TYPO3 project. The TYPO3 project is 00012 * free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License as published by 00014 * the Free Software Foundation; either version 2 of the License, or 00015 * (at your option) any later version. 00016 * 00017 * The GNU General Public License can be found at 00018 * http://www.gnu.org/copyleft/gpl.html. 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 00028 /** 00029 * Testcase for the Request Hash Service 00030 * 00031 * @version $Id: RequestHashService_testcase.php 2334 2010-06-14 16:28:25Z sebastian $ 00032 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser Public License, version 3 or later 00033 */ 00034 class Tx_Extbase_Tests_Unit_Security_Channel_RequestHashServiceTest extends Tx_Extbase_Tests_Unit_BaseTestCase { 00035 00036 public function dataProviderForGenerateRequestHash() { 00037 return array( 00038 // Simple cases 00039 array( 00040 array(), 00041 array(), 00042 ), 00043 array( 00044 array('field1'), 00045 array('field1' => 1), 00046 ), 00047 array( 00048 array('field1', 'field2'), 00049 array( 00050 'field1' => 1, 00051 'field2' => 1 00052 ), 00053 ), 00054 // recursion 00055 array( 00056 array('field1', 'field[subfield1]', 'field[subfield2]'), 00057 array( 00058 'field1' => 1, 00059 'field' => array( 00060 'subfield1' => 1, 00061 'subfield2' => 1 00062 ) 00063 ), 00064 ), 00065 // recursion with duplicated field name 00066 array( 00067 array('field1', 'field[subfield1]', 'field[subfield2]', 'field1'), 00068 array( 00069 'field1' => 1, 00070 'field' => array( 00071 'subfield1' => 1, 00072 'subfield2' => 1 00073 ) 00074 ), 00075 ), 00076 // Recursion with un-named fields at the end (...[]). There, they should be made explicit by increasing the counter 00077 array( 00078 array('field1', 'field[subfield1][]', 'field[subfield1][]', 'field[subfield2]'), 00079 array( 00080 'field1' => 1, 00081 'field' => array( 00082 'subfield1' => array( 00083 0 => 1, 00084 1 => 1 00085 ), 00086 'subfield2' => 1 00087 ) 00088 ), 00089 ), 00090 ); 00091 } 00092 00093 // Data provider for error cases which should throw an exception 00094 public function dataProviderForGenerateRequestHashWithUnallowedValues() { 00095 return array( 00096 // Overriding form fields (string overridden by array) 00097 array( 00098 array('field1', 'field2', 'field2[bla]', 'field2[blubb]'), 00099 ), 00100 array( 00101 array('field1', 'field2[bla]', 'field2[bla][blubb][blubb]'), 00102 ), 00103 // Overriding form fields (array overridden by string) 00104 array( 00105 array('field1', 'field2[bla]', 'field2[blubb]', 'field2'), 00106 ), 00107 array( 00108 array('field1', 'field2[bla][blubb][blubb]', 'field2[bla]'), 00109 ), 00110 // Empty [] not as last argument 00111 array( 00112 array('field1', 'field2[][bla]'), 00113 ) 00114 00115 ); 00116 } 00117 00118 /** 00119 * @test 00120 * @author Sebastian Kurfürst <sebastian@typo3.org> 00121 * @dataProvider dataProviderForGenerateRequestHash 00122 */ 00123 public function generateRequestHashGeneratesTheCorrectHashesInNormalOperation($input, $expected) { 00124 $requestHashService = $this->getMock('Tx_Extbase_Security_Channel_RequestHashService', array('serializeAndHashFormFieldArray')); 00125 $requestHashService->expects($this->once())->method('serializeAndHashFormFieldArray')->with($expected); 00126 $requestHashService->generateRequestHash($input); 00127 } 00128 00129 /** 00130 * @test 00131 * @author Sebastian Kurfürst <sebastian@typo3.org> 00132 * @dataProvider dataProviderForGenerateRequestHashWithUnallowedValues 00133 * @expectedException Tx_Extbase_Security_Exception_InvalidArgumentForRequestHashGeneration 00134 */ 00135 public function generateRequestHashThrowsExceptionInWrongCases($input) { 00136 $requestHashService = $this->getMock('Tx_Extbase_Security_Channel_RequestHashService', array('serializeAndHashFormFieldArray')); 00137 $requestHashService->generateRequestHash($input); 00138 } 00139 00140 /** 00141 * @test 00142 * @author Sebastian Kurfürst <sebastian@typo3.org> 00143 */ 00144 public function serializeAndHashFormFieldArrayWorks() { 00145 $formFieldArray = array( 00146 'bla' => array( 00147 'blubb' => 1, 00148 'hu' => 1 00149 ) 00150 ); 00151 $mockHash = '12345'; 00152 00153 $hashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Cryptography_HashService'), array('generateHash')); 00154 $hashService->expects($this->once())->method('generateHash')->with(serialize($formFieldArray))->will($this->returnValue($mockHash)); 00155 00156 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy')); 00157 $requestHashService->_set('hashService', $hashService); 00158 00159 $expected = serialize($formFieldArray) . $mockHash; 00160 $actual = $requestHashService->_call('serializeAndHashFormFieldArray', $formFieldArray); 00161 $this->assertEquals($expected, $actual); 00162 } 00163 00164 /** 00165 * @test 00166 * @author Sebastian Kurfürst 00167 */ 00168 public function verifyRequestHashSetsHmacVerifiedToFalseIfRequestDoesNotHaveAnHmacArgument() { 00169 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'setHmacVerified')); 00170 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(FALSE)); 00171 $request->expects($this->once())->method('setHmacVerified')->with(FALSE); 00172 $requestHashService = new Tx_Extbase_Security_Channel_RequestHashService; 00173 $requestHashService->verifyRequest($request); 00174 } 00175 00176 /** 00177 * @test 00178 * @expectedException Tx_Extbase_Security_Exception_SyntacticallyWrongRequestHash 00179 * @author Sebastian Kurfürst 00180 */ 00181 public function verifyRequestHashThrowsExceptionIfHmacIsShortherThan40Characters() { 00182 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'setHmacVerified')); 00183 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE)); 00184 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue('abc')); 00185 $requestHashService = new Tx_Extbase_Security_Channel_RequestHashService; 00186 $requestHashService->verifyRequest($request); 00187 } 00188 00189 /** 00190 * @test 00191 * @author Sebastian Kurfürst 00192 */ 00193 public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToFalseIfHashCouldNotBeVerified() { 00194 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'setHmacVerified')); 00195 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE)); 00196 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue('11111' . '0000000000000000000000000000000000000000')); 00197 $request->expects($this->once())->method('setHmacVerified')->with(FALSE); 00198 00199 $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash')); 00200 $hashService->expects($this->once())->method('validateHash')->with('11111', '0000000000000000000000000000000000000000')->will($this->returnValue(FALSE)); 00201 00202 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy')); 00203 $requestHashService->_set('hashService', $hashService); 00204 $requestHashService->verifyRequest($request); 00205 } 00206 00207 /** 00208 * @test 00209 * @author Sebastian Kurfürst 00210 */ 00211 public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToTrueIfArgumentsAreIncludedInTheAllowedArgumentList() { 00212 $data = serialize(array('a' => 1)); 00213 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'getArguments', 'setHmacVerified')); 00214 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE)); 00215 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue($data . '0000000000000000000000000000000000000000')); 00216 $request->expects($this->once())->method('getArguments')->will($this->returnValue(array( 00217 '__hmac' => 'ABC', 00218 '__referrer' => '...', 00219 'a' => 'bla' 00220 ))); 00221 $request->expects($this->once())->method('setHmacVerified')->with(TRUE); 00222 00223 $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash')); 00224 $hashService->expects($this->once())->method('validateHash')->with($data, '0000000000000000000000000000000000000000')->will($this->returnValue(TRUE)); 00225 00226 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('checkFieldNameInclusion')); 00227 $requestHashService->expects($this->once())->method('checkFieldNameInclusion')->with(array('a' => 'bla'), array('a' => 1))->will($this->returnValue(TRUE)); 00228 $requestHashService->_set('hashService', $hashService); 00229 $requestHashService->verifyRequest($request); 00230 } 00231 00232 /** 00233 * @test 00234 * @author Sebastian Kurfürst 00235 */ 00236 public function verifyRequestHashValidatesTheHashAndSetsHmacVerifiedToFalseIfNotAllArgumentsAreIncludedInTheAllowedArgumentList() { 00237 $data = serialize(array('a' => 1)); 00238 $request = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_Request'), array('hasArgument', 'getArgument', 'getArguments', 'setHmacVerified')); 00239 $request->expects($this->once())->method('hasArgument')->with('__hmac')->will($this->returnValue(TRUE)); 00240 $request->expects($this->once())->method('getArgument')->with('__hmac')->will($this->returnValue($data . '0000000000000000000000000000000000000000')); 00241 $request->expects($this->once())->method('getArguments')->will($this->returnValue(array( 00242 '__hmac' => 'ABC', 00243 '__referrer' => '...', 00244 'a' => 'bla', 00245 'b' => 'blubb' 00246 ))); 00247 $request->expects($this->once())->method('setHmacVerified')->with(FALSE); 00248 00249 $hashService = $this->getMock('Tx_Extbase_Security_Cryptography_HashService', array('validateHash')); 00250 $hashService->expects($this->once())->method('validateHash')->with($data, '0000000000000000000000000000000000000000')->will($this->returnValue(TRUE)); 00251 00252 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('checkFieldNameInclusion')); 00253 $requestHashService->expects($this->once())->method('checkFieldNameInclusion')->with(array('a' => 'bla', 'b' => 'blubb'), array('a' => 1))->will($this->returnValue(FALSE)); 00254 $requestHashService->_set('hashService', $hashService); 00255 $requestHashService->verifyRequest($request); 00256 } 00257 00258 /** 00259 * Data Provider for checkFieldNameInclusionWorks 00260 */ 00261 public function dataProviderForCheckFieldNameInclusion() { 00262 return array( 00263 // Simple fields with requestfields = responsefields 00264 array( 00265 // Request 00266 array( 00267 'a' => 'X', 00268 'b' => 'X', 00269 'c' => 'X' 00270 ), 00271 // Allowed 00272 array( 00273 'a' => 1, 00274 'b' => 1, 00275 'c' => 1 00276 ), 00277 // Expected result 00278 TRUE 00279 ), 00280 // Simple fields with requestfields < responsefields 00281 array( 00282 // Request 00283 array( 00284 'a' => 'X', 00285 'c' => 'X' 00286 ), 00287 // Allowed 00288 array( 00289 'a' => 1, 00290 'b' => 1, 00291 'c' => 1 00292 ), 00293 // Expected result 00294 TRUE 00295 ), 00296 // Simple fields with requestfields > responsefields 00297 array( 00298 // Request 00299 array( 00300 'a' => 'X', 00301 'b' => 'X', 00302 'c' => 'X' 00303 ), 00304 // Allowed 00305 array( 00306 'a' => 1, 00307 'b' => 1 00308 ), 00309 // Expected result 00310 FALSE 00311 ), 00312 // Hierarchical fields with requestfields < responsefields 00313 array( 00314 // Request 00315 array( 00316 'a' => array( 00317 'b' => 'X' 00318 ), 00319 'c' => 'X' 00320 ), 00321 // Allowed 00322 array( 00323 'a' => array( 00324 'b' => 1, 00325 'abc' => 1 00326 ), 00327 'c' => 1 00328 ), 00329 // Expected result 00330 TRUE 00331 ), 00332 // Hierarchical fields with requestfields > responsefields 00333 array( 00334 // Request 00335 array( 00336 'a' => array( 00337 'b' => 'X', 00338 'abc' => 'X' 00339 ), 00340 'c' => 'X' 00341 ), 00342 // Allowed 00343 array( 00344 'a' => array( 00345 'b' => 1 00346 ), 00347 'c' => 1 00348 ), 00349 // Expected result 00350 FALSE 00351 ), 00352 // hierarchical fields with requestfields != responsefields (different types) - 1 00353 array( 00354 // Request 00355 array( 00356 'a' => array( 00357 'b' => 'X', 00358 'c' => 'X' 00359 ), 00360 'b' => 'X', 00361 'c' => 'X' 00362 ), 00363 // Allowed 00364 array( 00365 'a' => 1, 00366 'b' => 1, 00367 'c' => 1 00368 ), 00369 // Expected result 00370 FALSE 00371 ), 00372 // hierarchical fields with requestfields != responsefields (different types) - 2 00373 array( 00374 // Request 00375 array( 00376 'a' => 'X', 00377 'b' => 'X', 00378 'c' => 'X' 00379 ), 00380 // Allowed 00381 array( 00382 'a' => array( 00383 'x' => 1, 00384 'y' => 1 00385 ), 00386 'b' => 1, 00387 'c' => 1 00388 ), 00389 // Expected result 00390 FALSE 00391 ), 00392 00393 // hierarchical fields with requestfields != responsefields (different types) 00394 // This case happens if an array of checkboxes is rendered, in case they are fully unchecked. 00395 array( 00396 // Request 00397 array( 00398 'a' => '', // this is the only allowed value. 00399 'b' => 'X', 00400 'c' => 'X' 00401 ), 00402 // Allowed 00403 array( 00404 'a' => array( 00405 'x' => 1, 00406 'y' => 1 00407 ), 00408 'b' => 1, 00409 'c' => 1 00410 ), 00411 // Expected result 00412 TRUE 00413 ), 00414 ); 00415 } 00416 00417 /** 00418 * @test 00419 * @author Sebastian Kurfürst <sebastian@typo3.org> 00420 * @dataProvider dataProviderForCheckFieldNameInclusion 00421 */ 00422 public function checkFieldNameInclusionWorks($requestArguments, $allowedFields, $expectedResult) { 00423 $requestHashService = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Security_Channel_RequestHashService'), array('dummy')); 00424 $this->assertEquals($expectedResult, $requestHashService->_call('checkFieldNameInclusion', $requestArguments, $allowedFields)); 00425 } 00426 } 00427 ?>
1.8.0