PageRenderTime 47ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/cake/tests/cases/libs/controller/components/security.test.php

https://bitbucket.org/unsl/listop
PHP | 1163 lines | 707 code | 62 blank | 394 comment | 5 complexity | 353f4235186d3f6b75fe2d128c0dddd0 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /* SVN FILE: $Id: security.test.php,v 1.1 2010-03-19 15:40:43 diegoq Exp $ */
  3. /**
  4. * SecurityComponentTest file
  5. *
  6. * Long description for file
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
  11. * Copyright 2005-2010, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  12. *
  13. * Licensed under The Open Group Test Suite License
  14. * Redistributions of files must retain the above copyright notice.
  15. *
  16. * @filesource
  17. * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  18. * @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
  19. * @package cake
  20. * @subpackage cake.tests.cases.libs.controller.components
  21. * @since CakePHP(tm) v 1.2.0.5435
  22. * @version $Revision: 1.1 $
  23. * @modifiedby $LastChangedBy$
  24. * @lastmodified $Date: 2010-03-19 15:40:43 $
  25. * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
  26. */
  27. App::import('Component', 'Security');
  28. /**
  29. * TestSecurityComponent
  30. *
  31. * @package cake
  32. * @subpackage cake.tests.cases.libs.controller.components
  33. */
  34. class TestSecurityComponent extends SecurityComponent {
  35. /**
  36. * validatePost method
  37. *
  38. * @param Controller $controller
  39. * @return unknown
  40. */
  41. function validatePost(&$controller) {
  42. return $this->_validatePost($controller);
  43. }
  44. }
  45. /**
  46. * SecurityTestController
  47. *
  48. * @package cake
  49. * @subpackage cake.tests.cases.libs.controller.components
  50. */
  51. class SecurityTestController extends Controller {
  52. /**
  53. * name property
  54. *
  55. * @var string 'SecurityTest'
  56. * @access public
  57. */
  58. var $name = 'SecurityTest';
  59. /**
  60. * components property
  61. *
  62. * @var array
  63. * @access public
  64. */
  65. var $components = array('TestSecurity');
  66. /**
  67. * failed property
  68. *
  69. * @var bool false
  70. * @access public
  71. */
  72. var $failed = false;
  73. /**
  74. * Used for keeping track of headers in test
  75. *
  76. * @var array
  77. * @access public
  78. */
  79. var $testHeaders = array();
  80. /**
  81. * fail method
  82. *
  83. * @access public
  84. * @return void
  85. */
  86. function fail() {
  87. $this->failed = true;
  88. }
  89. /**
  90. * redirect method
  91. *
  92. * @param mixed $option
  93. * @param mixed $code
  94. * @param mixed $exit
  95. * @access public
  96. * @return void
  97. */
  98. function redirect($option, $code, $exit) {
  99. return $code;
  100. }
  101. /**
  102. * Conveinence method for header()
  103. *
  104. * @param string $status
  105. * @return void
  106. * @access public
  107. */
  108. function header($status) {
  109. $this->testHeaders[] = $status;
  110. }
  111. }
  112. /**
  113. * SecurityComponentTest class
  114. *
  115. * @package cake
  116. * @subpackage cake.tests.cases.libs.controller.components
  117. */
  118. class SecurityComponentTest extends CakeTestCase {
  119. /**
  120. * Controller property
  121. *
  122. * @var SecurityTestController
  123. * @access public
  124. */
  125. var $Controller;
  126. /**
  127. * oldSalt property
  128. *
  129. * @var string
  130. * @access public
  131. */
  132. var $oldSalt;
  133. /**
  134. * setUp method
  135. *
  136. * @access public
  137. * @return void
  138. */
  139. function setUp() {
  140. $this->Controller =& new SecurityTestController();
  141. $this->Controller->Component->init($this->Controller);
  142. $this->Controller->Security =& $this->Controller->TestSecurity;
  143. $this->Controller->Security->blackHoleCallback = 'fail';
  144. $this->oldSalt = Configure::read('Security.salt');
  145. Configure::write('Security.salt', 'foo!');
  146. }
  147. /**
  148. * Tear-down method. Resets environment state.
  149. *
  150. * @access public
  151. * @return void
  152. */
  153. function tearDown() {
  154. Configure::write('Security.salt', $this->oldSalt);
  155. $this->Controller->Session->del('_Token');
  156. unset($this->Controller->Security);
  157. unset($this->Controller->Component);
  158. unset($this->Controller);
  159. }
  160. /**
  161. * testStartup method
  162. *
  163. * @access public
  164. * @return void
  165. */
  166. function testStartup() {
  167. $this->Controller->Security->startup($this->Controller);
  168. $result = $this->Controller->params['_Token']['key'];
  169. $this->assertNotNull($result);
  170. $this->assertTrue($this->Controller->Session->check('_Token'));
  171. }
  172. /**
  173. * testRequirePostFail method
  174. *
  175. * @access public
  176. * @return void
  177. */
  178. function testRequirePostFail() {
  179. $_SERVER['REQUEST_METHOD'] = 'GET';
  180. $this->Controller->action = 'posted';
  181. $this->Controller->Security->requirePost('posted');
  182. $this->Controller->Security->startup($this->Controller);
  183. $this->assertTrue($this->Controller->failed);
  184. }
  185. /**
  186. * testRequirePostSucceed method
  187. *
  188. * @access public
  189. * @return void
  190. */
  191. function testRequirePostSucceed() {
  192. $_SERVER['REQUEST_METHOD'] = 'POST';
  193. $this->Controller->action = 'posted';
  194. $this->Controller->Security->requirePost('posted');
  195. $this->Controller->Security->startup($this->Controller);
  196. $this->assertFalse($this->Controller->failed);
  197. }
  198. /**
  199. * testRequireSecureFail method
  200. *
  201. * @access public
  202. * @return void
  203. */
  204. function testRequireSecureFail() {
  205. $_SERVER['HTTPS'] = 'off';
  206. $_SERVER['REQUEST_METHOD'] = 'POST';
  207. $this->Controller->action = 'posted';
  208. $this->Controller->Security->requireSecure('posted');
  209. $this->Controller->Security->startup($this->Controller);
  210. $this->assertTrue($this->Controller->failed);
  211. }
  212. /**
  213. * testRequireSecureSucceed method
  214. *
  215. * @access public
  216. * @return void
  217. */
  218. function testRequireSecureSucceed() {
  219. $_SERVER['REQUEST_METHOD'] = 'Secure';
  220. $this->Controller->action = 'posted';
  221. $_SERVER['HTTPS'] = 'on';
  222. $this->Controller->Security->requireSecure('posted');
  223. $this->Controller->Security->startup($this->Controller);
  224. $this->assertFalse($this->Controller->failed);
  225. }
  226. /**
  227. * testRequireAuthFail method
  228. *
  229. * @access public
  230. * @return void
  231. */
  232. function testRequireAuthFail() {
  233. $_SERVER['REQUEST_METHOD'] = 'AUTH';
  234. $this->Controller->action = 'posted';
  235. $this->Controller->data = array('username' => 'willy', 'password' => 'somePass');
  236. $this->Controller->Security->requireAuth('posted');
  237. $this->Controller->Security->startup($this->Controller);
  238. $this->assertTrue($this->Controller->failed);
  239. $this->Controller->Session->write('_Token', serialize(array('allowedControllers' => array())));
  240. $this->Controller->data = array('username' => 'willy', 'password' => 'somePass');
  241. $this->Controller->action = 'posted';
  242. $this->Controller->Security->requireAuth('posted');
  243. $this->Controller->Security->startup($this->Controller);
  244. $this->assertTrue($this->Controller->failed);
  245. $this->Controller->Session->write('_Token', serialize(array(
  246. 'allowedControllers' => array('SecurityTest'), 'allowedActions' => array('posted2')
  247. )));
  248. $this->Controller->data = array('username' => 'willy', 'password' => 'somePass');
  249. $this->Controller->action = 'posted';
  250. $this->Controller->Security->requireAuth('posted');
  251. $this->Controller->Security->startup($this->Controller);
  252. $this->assertTrue($this->Controller->failed);
  253. }
  254. /**
  255. * testRequireAuthSucceed method
  256. *
  257. * @access public
  258. * @return void
  259. */
  260. function testRequireAuthSucceed() {
  261. $_SERVER['REQUEST_METHOD'] = 'AUTH';
  262. $this->Controller->action = 'posted';
  263. $this->Controller->Security->requireAuth('posted');
  264. $this->Controller->Security->startup($this->Controller);
  265. $this->assertFalse($this->Controller->failed);
  266. $this->Controller->Security->Session->write('_Token', serialize(array(
  267. 'allowedControllers' => array('SecurityTest'), 'allowedActions' => array('posted')
  268. )));
  269. $this->Controller->params['controller'] = 'SecurityTest';
  270. $this->Controller->params['action'] = 'posted';
  271. $this->Controller->data = array(
  272. 'username' => 'willy', 'password' => 'somePass', '_Token' => ''
  273. );
  274. $this->Controller->action = 'posted';
  275. $this->Controller->Security->requireAuth('posted');
  276. $this->Controller->Security->startup($this->Controller);
  277. $this->assertFalse($this->Controller->failed);
  278. }
  279. /**
  280. * testRequirePostSucceedWrongMethod method
  281. *
  282. * @access public
  283. * @return void
  284. */
  285. function testRequirePostSucceedWrongMethod() {
  286. $_SERVER['REQUEST_METHOD'] = 'GET';
  287. $this->Controller->action = 'getted';
  288. $this->Controller->Security->requirePost('posted');
  289. $this->Controller->Security->startup($this->Controller);
  290. $this->assertFalse($this->Controller->failed);
  291. }
  292. /**
  293. * testRequireGetFail method
  294. *
  295. * @access public
  296. * @return void
  297. */
  298. function testRequireGetFail() {
  299. $_SERVER['REQUEST_METHOD'] = 'POST';
  300. $this->Controller->action = 'getted';
  301. $this->Controller->Security->requireGet('getted');
  302. $this->Controller->Security->startup($this->Controller);
  303. $this->assertTrue($this->Controller->failed);
  304. }
  305. /**
  306. * testRequireGetSucceed method
  307. *
  308. * @access public
  309. * @return void
  310. */
  311. function testRequireGetSucceed() {
  312. $_SERVER['REQUEST_METHOD'] = 'GET';
  313. $this->Controller->action = 'getted';
  314. $this->Controller->Security->requireGet('getted');
  315. $this->Controller->Security->startup($this->Controller);
  316. $this->assertFalse($this->Controller->failed);
  317. }
  318. /**
  319. * testRequireLogin method
  320. *
  321. * @access public
  322. * @return void
  323. */
  324. function testRequireLogin() {
  325. $this->Controller->action = 'posted';
  326. $this->Controller->Security->requireLogin(
  327. 'posted',
  328. array('type' => 'basic', 'users' => array('admin' => 'password'))
  329. );
  330. $_SERVER['PHP_AUTH_USER'] = 'admin';
  331. $_SERVER['PHP_AUTH_PW'] = 'password';
  332. $this->Controller->Security->startup($this->Controller);
  333. $this->assertFalse($this->Controller->failed);
  334. $this->Controller->action = 'posted';
  335. $this->Controller->Security->requireLogin(
  336. 'posted',
  337. array('type' => 'basic', 'users' => array('admin' => 'password'))
  338. );
  339. $_SERVER['PHP_AUTH_USER'] = 'admin2';
  340. $_SERVER['PHP_AUTH_PW'] = 'password';
  341. $this->Controller->Security->startup($this->Controller);
  342. $this->assertTrue($this->Controller->failed);
  343. $this->Controller->action = 'posted';
  344. $this->Controller->Security->requireLogin(
  345. 'posted',
  346. array('type' => 'basic', 'users' => array('admin' => 'password'))
  347. );
  348. $_SERVER['PHP_AUTH_USER'] = 'admin';
  349. $_SERVER['PHP_AUTH_PW'] = 'password2';
  350. $this->Controller->Security->startup($this->Controller);
  351. $this->assertTrue($this->Controller->failed);
  352. }
  353. /**
  354. * testDigestAuth method
  355. *
  356. * @access public
  357. * @return void
  358. */
  359. function testDigestAuth() {
  360. $skip = $this->skipIf((version_compare(PHP_VERSION, '5.1') == -1) XOR (!function_exists('apache_request_headers')),
  361. "%s Cannot run Digest Auth test for PHP versions < 5.1"
  362. );
  363. if ($skip) {
  364. return;
  365. }
  366. $this->Controller->action = 'posted';
  367. $_SERVER['PHP_AUTH_DIGEST'] = $digest = <<<DIGEST
  368. Digest username="Mufasa",
  369. realm="testrealm@host.com",
  370. nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
  371. uri="/dir/index.html",
  372. qop=auth,
  373. nc=00000001,
  374. cnonce="0a4f113b",
  375. response="460d0d3c6867c2f1ab85b1ada1aece48",
  376. opaque="5ccc069c403ebaf9f0171e9517f40e41"
  377. DIGEST;
  378. $this->Controller->Security->requireLogin('posted', array(
  379. 'type' => 'digest', 'users' => array('Mufasa' => 'password'),
  380. 'realm' => 'testrealm@host.com'
  381. ));
  382. $this->Controller->Security->startup($this->Controller);
  383. $this->assertFalse($this->Controller->failed);
  384. }
  385. /**
  386. * testRequireGetSucceedWrongMethod method
  387. *
  388. * @access public
  389. * @return void
  390. */
  391. function testRequireGetSucceedWrongMethod() {
  392. $_SERVER['REQUEST_METHOD'] = 'POST';
  393. $this->Controller->action = 'posted';
  394. $this->Controller->Security->requireGet('getted');
  395. $this->Controller->Security->startup($this->Controller);
  396. $this->assertFalse($this->Controller->failed);
  397. }
  398. /**
  399. * testRequirePutFail method
  400. *
  401. * @access public
  402. * @return void
  403. */
  404. function testRequirePutFail() {
  405. $_SERVER['REQUEST_METHOD'] = 'POST';
  406. $this->Controller->action = 'putted';
  407. $this->Controller->Security->requirePut('putted');
  408. $this->Controller->Security->startup($this->Controller);
  409. $this->assertTrue($this->Controller->failed);
  410. }
  411. /**
  412. * testRequirePutSucceed method
  413. *
  414. * @access public
  415. * @return void
  416. */
  417. function testRequirePutSucceed() {
  418. $_SERVER['REQUEST_METHOD'] = 'PUT';
  419. $this->Controller->action = 'putted';
  420. $this->Controller->Security->requirePut('putted');
  421. $this->Controller->Security->startup($this->Controller);
  422. $this->assertFalse($this->Controller->failed);
  423. }
  424. /**
  425. * testRequirePutSucceedWrongMethod method
  426. *
  427. * @access public
  428. * @return void
  429. */
  430. function testRequirePutSucceedWrongMethod() {
  431. $_SERVER['REQUEST_METHOD'] = 'POST';
  432. $this->Controller->action = 'posted';
  433. $this->Controller->Security->requirePut('putted');
  434. $this->Controller->Security->startup($this->Controller);
  435. $this->assertFalse($this->Controller->failed);
  436. }
  437. /**
  438. * testRequireDeleteFail method
  439. *
  440. * @access public
  441. * @return void
  442. */
  443. function testRequireDeleteFail() {
  444. $_SERVER['REQUEST_METHOD'] = 'POST';
  445. $this->Controller->action = 'deleted';
  446. $this->Controller->Security->requireDelete('deleted');
  447. $this->Controller->Security->startup($this->Controller);
  448. $this->assertTrue($this->Controller->failed);
  449. }
  450. /**
  451. * testRequireDeleteSucceed method
  452. *
  453. * @access public
  454. * @return void
  455. */
  456. function testRequireDeleteSucceed() {
  457. $_SERVER['REQUEST_METHOD'] = 'DELETE';
  458. $this->Controller->action = 'deleted';
  459. $this->Controller->Security->requireDelete('deleted');
  460. $this->Controller->Security->startup($this->Controller);
  461. $this->assertFalse($this->Controller->failed);
  462. }
  463. /**
  464. * testRequireDeleteSucceedWrongMethod method
  465. *
  466. * @access public
  467. * @return void
  468. */
  469. function testRequireDeleteSucceedWrongMethod() {
  470. $_SERVER['REQUEST_METHOD'] = 'POST';
  471. $this->Controller->action = 'posted';
  472. $this->Controller->Security->requireDelete('deleted');
  473. $this->Controller->Security->startup($this->Controller);
  474. $this->assertFalse($this->Controller->failed);
  475. }
  476. /**
  477. * testRequireLoginSettings method
  478. *
  479. * @access public
  480. * @return void
  481. */
  482. function testRequireLoginSettings() {
  483. $this->Controller->Security->requireLogin(
  484. 'add', 'edit',
  485. array('type' => 'basic', 'users' => array('admin' => 'password'))
  486. );
  487. $this->assertEqual($this->Controller->Security->requireLogin, array('add', 'edit'));
  488. $this->assertEqual($this->Controller->Security->loginUsers, array('admin' => 'password'));
  489. }
  490. /**
  491. * testRequireLoginAllActions method
  492. *
  493. * @access public
  494. * @return void
  495. */
  496. function testRequireLoginAllActions() {
  497. $this->Controller->Security->requireLogin(
  498. array('type' => 'basic', 'users' => array('admin' => 'password'))
  499. );
  500. $this->assertEqual($this->Controller->Security->requireLogin, array('*'));
  501. $this->assertEqual($this->Controller->Security->loginUsers, array('admin' => 'password'));
  502. }
  503. /**
  504. * Simple hash validation test
  505. *
  506. * @access public
  507. * @return void
  508. */
  509. function testValidatePost() {
  510. $this->Controller->Security->startup($this->Controller);
  511. $key = $this->Controller->params['_Token']['key'];
  512. $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3An%3A1%3A%7Bv%3A0%3B';
  513. $fields .= 'f%3A11%3A%22Zbqry.inyvq%22%3B%7D';
  514. $this->Controller->data = array(
  515. 'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
  516. '_Token' => compact('key', 'fields')
  517. );
  518. $this->assertTrue($this->Controller->Security->validatePost($this->Controller));
  519. }
  520. /**
  521. * test that validatePost fails if any of its required fields are missing.
  522. *
  523. * @return void
  524. **/
  525. function testValidatePostFormHacking() {
  526. $this->Controller->Security->startup($this->Controller);
  527. $key = $this->Controller->params['_Token']['key'];
  528. $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3An%3A1%3A%7Bv%3A0%3B';
  529. $fields .= 'f%3A11%3A%22Zbqry.inyvq%22%3B%7D';
  530. $this->Controller->data = array(
  531. 'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
  532. '_Token' => compact('key')
  533. );
  534. $result = $this->Controller->Security->validatePost($this->Controller);
  535. $this->assertFalse($result, 'validatePost passed when fields were missing. %s');
  536. $this->Controller->data = array(
  537. 'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
  538. '_Token' => compact('fields')
  539. );
  540. $result = $this->Controller->Security->validatePost($this->Controller);
  541. $this->assertFalse($result, 'validatePost passed when key was missing. %s');
  542. }
  543. /**
  544. * Tests validation of checkbox arrays
  545. *
  546. * @access public
  547. * @return void
  548. */
  549. function testValidatePostArray() {
  550. $this->Controller->Security->startup($this->Controller);
  551. $key = $this->Controller->params['_Token']['key'];
  552. $fields = 'f7d573650a295b94e0938d32b323fde775e5f32b%3An%3A0%3A%7B%7D';
  553. $this->Controller->data = array(
  554. 'Model' => array('multi_field' => array('1', '3')),
  555. '_Token' => compact('key', 'fields')
  556. );
  557. $this->assertTrue($this->Controller->Security->validatePost($this->Controller));
  558. }
  559. /**
  560. * testValidatePostNoModel method
  561. *
  562. * @access public
  563. * @return void
  564. */
  565. function testValidatePostNoModel() {
  566. $this->Controller->Security->startup($this->Controller);
  567. $key = $this->Controller->params['_Token']['key'];
  568. $fields = '540ac9c60d323c22bafe997b72c0790f39a8bdef%3An%3A0%3A%7B%7D';
  569. $this->Controller->data = array(
  570. 'anything' => 'some_data',
  571. '_Token' => compact('key', 'fields')
  572. );
  573. $result = $this->Controller->Security->validatePost($this->Controller);
  574. $this->assertTrue($result);
  575. }
  576. /**
  577. * testValidatePostSimple method
  578. *
  579. * @access public
  580. * @return void
  581. */
  582. function testValidatePostSimple() {
  583. $this->Controller->Security->startup($this->Controller);
  584. $key = $this->Controller->params['_Token']['key'];
  585. $fields = '69f493434187b867ea14b901fdf58b55d27c935d%3An%3A0%3A%7B%7D';
  586. $this->Controller->data = $data = array(
  587. 'Model' => array('username' => '', 'password' => ''),
  588. '_Token' => compact('key', 'fields')
  589. );
  590. $result = $this->Controller->Security->validatePost($this->Controller);
  591. $this->assertTrue($result);
  592. }
  593. /**
  594. * Tests hash validation for multiple records, including locked fields
  595. *
  596. * @access public
  597. * @return void
  598. */
  599. function testValidatePostComplex() {
  600. $this->Controller->Security->startup($this->Controller);
  601. $key = $this->Controller->params['_Token']['key'];
  602. $fields = 'c9118120e680a7201b543f562e5301006ccfcbe2%3An%3A2%3A%7Bv%3A0%3Bf%3A14%3A%';
  603. $fields .= '22Nqqerffrf.0.vq%22%3Bv%3A1%3Bf%3A14%3A%22Nqqerffrf.1.vq%22%3B%7D';
  604. $this->Controller->data = array(
  605. 'Addresses' => array(
  606. '0' => array(
  607. 'id' => '123456', 'title' => '', 'first_name' => '', 'last_name' => '',
  608. 'address' => '', 'city' => '', 'phone' => '', 'primary' => ''
  609. ),
  610. '1' => array(
  611. 'id' => '654321', 'title' => '', 'first_name' => '', 'last_name' => '',
  612. 'address' => '', 'city' => '', 'phone' => '', 'primary' => ''
  613. )
  614. ),
  615. '_Token' => compact('key', 'fields')
  616. );
  617. $result = $this->Controller->Security->validatePost($this->Controller);
  618. $this->assertTrue($result);
  619. }
  620. /**
  621. * test ValidatePost with multiple select elements.
  622. *
  623. * @return void
  624. **/
  625. function testValidatePostMultipleSelect() {
  626. $this->Controller->Security->startup($this->Controller);
  627. $key = $this->Controller->params['_Token']['key'];
  628. $fields = '422cde416475abc171568be690a98cad20e66079%3An%3A0%3A%7B%7D';
  629. $this->Controller->data = array(
  630. 'Tag' => array('Tag' => array(1, 2)),
  631. '_Token' => compact('key', 'fields'),
  632. );
  633. $result = $this->Controller->Security->validatePost($this->Controller);
  634. $this->assertTrue($result);
  635. $this->Controller->data = array(
  636. 'Tag' => array('Tag' => array(1, 2, 3)),
  637. '_Token' => compact('key', 'fields'),
  638. );
  639. $result = $this->Controller->Security->validatePost($this->Controller);
  640. $this->assertTrue($result);
  641. $this->Controller->data = array(
  642. 'Tag' => array('Tag' => array(1, 2, 3, 4)),
  643. '_Token' => compact('key', 'fields'),
  644. );
  645. $result = $this->Controller->Security->validatePost($this->Controller);
  646. $this->assertTrue($result);
  647. $fields = '19464422eafe977ee729c59222af07f983010c5f%3An%3A0%3A%7B%7D';
  648. $this->Controller->data = array(
  649. 'User.password' => 'bar', 'User.name' => 'foo', 'User.is_valid' => '1',
  650. 'Tag' => array('Tag' => array(1)), '_Token' => compact('key', 'fields'),
  651. );
  652. $result = $this->Controller->Security->validatePost($this->Controller);
  653. $this->assertTrue($result);
  654. }
  655. /**
  656. * testValidatePostCheckbox method
  657. *
  658. * First block tests un-checked checkbox
  659. * Second block tests checked checkbox
  660. *
  661. * @access public
  662. * @return void
  663. */
  664. function testValidatePostCheckbox() {
  665. $this->Controller->Security->startup($this->Controller);
  666. $key = $this->Controller->params['_Token']['key'];
  667. $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3An%3A1%3A%7Bv%3A0%';
  668. $fields .= '3Bf%3A11%3A%22Zbqry.inyvq%22%3B%7D';
  669. $this->Controller->data = array(
  670. 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
  671. '_Token' => compact('key', 'fields')
  672. );
  673. $result = $this->Controller->Security->validatePost($this->Controller);
  674. $this->assertTrue($result);
  675. $fields = '874439ca69f89b4c4a5f50fb9c36ff56a28f5d42%3An%3A0%3A%7B%7D';
  676. $this->Controller->data = array(
  677. 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
  678. '_Token' => compact('key', 'fields')
  679. );
  680. $result = $this->Controller->Security->validatePost($this->Controller);
  681. $this->assertTrue($result);
  682. $this->Controller->data = array();
  683. $this->Controller->Security->startup($this->Controller);
  684. $key = $this->Controller->params['_Token']['key'];
  685. $this->Controller->data = $data = array(
  686. 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
  687. '_Token' => compact('key', 'fields')
  688. );
  689. $result = $this->Controller->Security->validatePost($this->Controller);
  690. $this->assertTrue($result);
  691. }
  692. /**
  693. * testValidatePostHidden method
  694. *
  695. * @access public
  696. * @return void
  697. */
  698. function testValidatePostHidden() {
  699. $this->Controller->Security->startup($this->Controller);
  700. $key = $this->Controller->params['_Token']['key'];
  701. $fields = '51ccd8cb0997c7b3d4523ecde5a109318405ef8c%3An%3A2%3A%7Bv%3A0%3Bf%3A12%3A';
  702. $fields .= '%22Zbqry.uvqqra%22%3Bv%3A1%3Bf%3A18%3A%22Zbqry.bgure_uvqqra%22%3B%7D';
  703. $this->Controller->data = array(
  704. 'Model' => array(
  705. 'username' => '', 'password' => '', 'hidden' => '0',
  706. 'other_hidden' => 'some hidden value'
  707. ),
  708. '_Token' => compact('key', 'fields')
  709. );
  710. $result = $this->Controller->Security->validatePost($this->Controller);
  711. $this->assertTrue($result);
  712. }
  713. /**
  714. * testValidatePostWithDisabledFields method
  715. *
  716. * @access public
  717. * @return void
  718. */
  719. function testValidatePostWithDisabledFields() {
  720. $this->Controller->Security->disabledFields = array('Model.username', 'Model.password');
  721. $this->Controller->Security->startup($this->Controller);
  722. $key = $this->Controller->params['_Token']['key'];
  723. $fields = 'ef1082968c449397bcd849f963636864383278b1%3An%3A1%3A%7Bv%';
  724. $fields .= '3A0%3Bf%3A12%3A%22Zbqry.uvqqra%22%3B%7D';
  725. $this->Controller->data = array(
  726. 'Model' => array(
  727. 'username' => '', 'password' => '', 'hidden' => '0'
  728. ),
  729. '_Token' => compact('fields', 'key')
  730. );
  731. $result = $this->Controller->Security->validatePost($this->Controller);
  732. $this->assertTrue($result);
  733. }
  734. /**
  735. * testValidateHiddenMultipleModel method
  736. *
  737. * @access public
  738. * @return void
  739. */
  740. function testValidateHiddenMultipleModel() {
  741. $this->Controller->Security->startup($this->Controller);
  742. $key = $this->Controller->params['_Token']['key'];
  743. $fields = 'a2d01072dc4660eea9d15007025f35a7a5b58e18%3An%3A3%3A%7Bv%3A0%3Bf%3A11';
  744. $fields .= '%3A%22Zbqry.inyvq%22%3Bv%3A1%3Bf%3A12%3A%22Zbqry2.inyvq%22%3Bv%3A2%';
  745. $fields .= '3Bf%3A12%3A%22Zbqry3.inyvq%22%3B%7D';
  746. $this->Controller->data = array(
  747. 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
  748. 'Model2' => array('valid' => '0'),
  749. 'Model3' => array('valid' => '0'),
  750. '_Token' => compact('key', 'fields')
  751. );
  752. $result = $this->Controller->Security->validatePost($this->Controller);
  753. $this->assertTrue($result);
  754. }
  755. /**
  756. * testLoginValidation method
  757. *
  758. * @access public
  759. * @return void
  760. */
  761. function testLoginValidation() {
  762. }
  763. /**
  764. * testValidateHasManyModel method
  765. *
  766. * @access public
  767. * @return void
  768. */
  769. function testValidateHasManyModel() {
  770. $this->Controller->Security->startup($this->Controller);
  771. $key = $this->Controller->params['_Token']['key'];
  772. $fields = '51e3b55a6edd82020b3f29c9ae200e14bbeb7ee5%3An%3A4%3A%7Bv%3A0%3Bf%3A14%3A%2';
  773. $fields .= '2Zbqry.0.uvqqra%22%3Bv%3A1%3Bf%3A13%3A%22Zbqry.0.inyvq%22%3Bv%3A2%3Bf%3';
  774. $fields .= 'A14%3A%22Zbqry.1.uvqqra%22%3Bv%3A3%3Bf%3A13%3A%22Zbqry.1.inyvq%22%3B%7D';
  775. $this->Controller->data = array(
  776. 'Model' => array(
  777. array(
  778. 'username' => 'username', 'password' => 'password',
  779. 'hidden' => 'value', 'valid' => '0'
  780. ),
  781. array(
  782. 'username' => 'username', 'password' => 'password',
  783. 'hidden' => 'value', 'valid' => '0'
  784. )
  785. ),
  786. '_Token' => compact('key', 'fields')
  787. );
  788. $result = $this->Controller->Security->validatePost($this->Controller);
  789. $this->assertTrue($result);
  790. }
  791. /**
  792. * testValidateHasManyRecordsPass method
  793. *
  794. * @access public
  795. * @return void
  796. */
  797. function testValidateHasManyRecordsPass() {
  798. $this->Controller->Security->startup($this->Controller);
  799. $key = $this->Controller->params['_Token']['key'];
  800. $fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3An%3A4%3A%7Bv%3A0%3Bf%3A12%3A%2';
  801. $fields .= '2Nqqerff.0.vq%22%3Bv%3A1%3Bf%3A17%3A%22Nqqerff.0.cevznel%22%3Bv%3A2%3Bf%';
  802. $fields .= '3A12%3A%22Nqqerff.1.vq%22%3Bv%3A3%3Bf%3A17%3A%22Nqqerff.1.cevznel%22%3B%7D';
  803. $this->Controller->data = array(
  804. 'Address' => array(
  805. 0 => array(
  806. 'id' => '123',
  807. 'title' => 'home',
  808. 'first_name' => 'Bilbo',
  809. 'last_name' => 'Baggins',
  810. 'address' => '23 Bag end way',
  811. 'city' => 'the shire',
  812. 'phone' => 'N/A',
  813. 'primary' => '1',
  814. ),
  815. 1 => array(
  816. 'id' => '124',
  817. 'title' => 'home',
  818. 'first_name' => 'Frodo',
  819. 'last_name' => 'Baggins',
  820. 'address' => '50 Bag end way',
  821. 'city' => 'the shire',
  822. 'phone' => 'N/A',
  823. 'primary' => '1'
  824. )
  825. ),
  826. '_Token' => compact('key', 'fields')
  827. );
  828. $result = $this->Controller->Security->validatePost($this->Controller);
  829. $this->assertTrue($result);
  830. }
  831. /**
  832. * testValidateHasManyRecords method
  833. *
  834. * validatePost should fail, hidden fields have been changed.
  835. *
  836. * @access public
  837. * @return void
  838. */
  839. function testValidateHasManyRecordsFail() {
  840. $this->Controller->Security->startup($this->Controller);
  841. $key = $this->Controller->params['_Token']['key'];
  842. $fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3An%3A4%3A%7Bv%3A0%3Bf%3A12%3A%2';
  843. $fields .= '2Nqqerff.0.vq%22%3Bv%3A1%3Bf%3A17%3A%22Nqqerff.0.cevznel%22%3Bv%3A2%3Bf%';
  844. $fields .= '3A12%3A%22Nqqerff.1.vq%22%3Bv%3A3%3Bf%3A17%3A%22Nqqerff.1.cevznel%22%3B%7D';
  845. $this->Controller->data = array(
  846. 'Address' => array(
  847. 0 => array(
  848. 'id' => '123',
  849. 'title' => 'home',
  850. 'first_name' => 'Bilbo',
  851. 'last_name' => 'Baggins',
  852. 'address' => '23 Bag end way',
  853. 'city' => 'the shire',
  854. 'phone' => 'N/A',
  855. 'primary' => '5',
  856. ),
  857. 1 => array(
  858. 'id' => '124',
  859. 'title' => 'home',
  860. 'first_name' => 'Frodo',
  861. 'last_name' => 'Baggins',
  862. 'address' => '50 Bag end way',
  863. 'city' => 'the shire',
  864. 'phone' => 'N/A',
  865. 'primary' => '1'
  866. )
  867. ),
  868. '_Token' => compact('key', 'fields')
  869. );
  870. $result = $this->Controller->Security->validatePost($this->Controller);
  871. $this->assertFalse($result);
  872. }
  873. /**
  874. * testLoginRequest method
  875. *
  876. * @access public
  877. * @return void
  878. */
  879. function testLoginRequest() {
  880. $this->Controller->Security->startup($this->Controller);
  881. $realm = 'cakephp.org';
  882. $options = array('realm' => $realm, 'type' => 'basic');
  883. $result = $this->Controller->Security->loginRequest($options);
  884. $expected = 'WWW-Authenticate: Basic realm="'.$realm.'"';
  885. $this->assertEqual($result, $expected);
  886. $this->Controller->Security->startup($this->Controller);
  887. $options = array('realm' => $realm, 'type' => 'digest');
  888. $result = $this->Controller->Security->loginRequest($options);
  889. $this->assertPattern('/realm="'.$realm.'"/', $result);
  890. $this->assertPattern('/qop="auth"/', $result);
  891. }
  892. /**
  893. * testGenerateDigestResponseHash method
  894. *
  895. * @access public
  896. * @return void
  897. */
  898. function testGenerateDigestResponseHash() {
  899. $this->Controller->Security->startup($this->Controller);
  900. $realm = 'cakephp.org';
  901. $loginData = array('realm' => $realm, 'users' => array('Willy Smith' => 'password'));
  902. $this->Controller->Security->requireLogin($loginData);
  903. $data = array(
  904. 'username' => 'Willy Smith',
  905. 'password' => 'password',
  906. 'nonce' => String::uuid(),
  907. 'nc' => 1,
  908. 'cnonce' => 1,
  909. 'realm' => $realm,
  910. 'uri' => 'path_to_identifier',
  911. 'qop' => 'testme'
  912. );
  913. $_SERVER['REQUEST_METHOD'] = 'POST';
  914. $result = $this->Controller->Security->generateDigestResponseHash($data);
  915. $expected = md5(
  916. md5($data['username'] . ':' . $loginData['realm'] . ':' . $data['password']) . ':' .
  917. $data['nonce'] . ':' . $data['nc'] . ':' . $data['cnonce'] . ':' . $data['qop'] . ':' .
  918. md5(env('REQUEST_METHOD') . ':' . $data['uri'])
  919. );
  920. $this->assertIdentical($result, $expected);
  921. }
  922. /**
  923. * testLoginCredentials method
  924. *
  925. * @access public
  926. * @return void
  927. */
  928. function testLoginCredentials() {
  929. $this->Controller->Security->startup($this->Controller);
  930. $_SERVER['PHP_AUTH_USER'] = $user = 'Willy Test';
  931. $_SERVER['PHP_AUTH_PW'] = $pw = 'some password for the nice test';
  932. $result = $this->Controller->Security->loginCredentials('basic');
  933. $expected = array('username' => $user, 'password' => $pw);
  934. $this->assertIdentical($result, $expected);
  935. if (version_compare(PHP_VERSION, '5.1') != -1) {
  936. $_SERVER['PHP_AUTH_DIGEST'] = $digest = <<<DIGEST
  937. Digest username="Mufasa",
  938. realm="testrealm@host.com",
  939. nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
  940. uri="/dir/index.html",
  941. qop=auth,
  942. nc=00000001,
  943. cnonce="0a4f113b",
  944. response="6629fae49393a05397450978507c4ef1",
  945. opaque="5ccc069c403ebaf9f0171e9517f40e41"
  946. DIGEST;
  947. $expected = array(
  948. 'username' => 'Mufasa',
  949. 'nonce' => 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
  950. 'uri' => '/dir/index.html',
  951. 'qop' => 'auth',
  952. 'nc' => '00000001',
  953. 'cnonce' => '0a4f113b',
  954. 'response' => '6629fae49393a05397450978507c4ef1',
  955. 'opaque' => '5ccc069c403ebaf9f0171e9517f40e41'
  956. );
  957. $result = $this->Controller->Security->loginCredentials('digest');
  958. $this->assertIdentical($result, $expected);
  959. }
  960. }
  961. /**
  962. * testParseDigestAuthData method
  963. *
  964. * @access public
  965. * @return void
  966. */
  967. function testParseDigestAuthData() {
  968. $this->Controller->Security->startup($this->Controller);
  969. $digest = <<<DIGEST
  970. Digest username="Mufasa",
  971. realm="testrealm@host.com",
  972. nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
  973. uri="/dir/index.html",
  974. qop=auth,
  975. nc=00000001,
  976. cnonce="0a4f113b",
  977. response="6629fae49393a05397450978507c4ef1",
  978. opaque="5ccc069c403ebaf9f0171e9517f40e41"
  979. DIGEST;
  980. $expected = array(
  981. 'username' => 'Mufasa',
  982. 'nonce' => 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
  983. 'uri' => '/dir/index.html',
  984. 'qop' => 'auth',
  985. 'nc' => '00000001',
  986. 'cnonce' => '0a4f113b',
  987. 'response' => '6629fae49393a05397450978507c4ef1',
  988. 'opaque' => '5ccc069c403ebaf9f0171e9517f40e41'
  989. );
  990. $result = $this->Controller->Security->parseDigestAuthData($digest);
  991. $this->assertIdentical($result, $expected);
  992. $result = $this->Controller->Security->parseDigestAuthData('');
  993. $this->assertNull($result);
  994. }
  995. /**
  996. * testFormDisabledFields method
  997. *
  998. * @access public
  999. * @return void
  1000. */
  1001. function testFormDisabledFields() {
  1002. $this->Controller->Security->startup($this->Controller);
  1003. $key = $this->Controller->params['_Token']['key'];
  1004. $fields = '11842060341b9d0fc3808b90ba29fdea7054d6ad%3An%3A0%3A%7B%7D';
  1005. $this->Controller->data = array(
  1006. 'MyModel' => array('name' => 'some data'),
  1007. '_Token' => compact('key', 'fields')
  1008. );
  1009. $result = $this->Controller->Security->validatePost($this->Controller);
  1010. $this->assertFalse($result);
  1011. $this->Controller->Security->startup($this->Controller);
  1012. $this->Controller->Security->disabledFields = array('MyModel.name');
  1013. $key = $this->Controller->params['_Token']['key'];
  1014. $this->Controller->data = array(
  1015. 'MyModel' => array('name' => 'some data'),
  1016. '_Token' => compact('key', 'fields')
  1017. );
  1018. $result = $this->Controller->Security->validatePost($this->Controller);
  1019. $this->assertTrue($result);
  1020. }
  1021. /**
  1022. * testRadio method
  1023. *
  1024. * @access public
  1025. * @return void
  1026. */
  1027. function testRadio() {
  1028. $this->Controller->Security->startup($this->Controller);
  1029. $key = $this->Controller->params['_Token']['key'];
  1030. $fields = '575ef54ca4fc8cab468d6d898e9acd3a9671c17e%3An%3A0%3A%7B%7D';
  1031. $this->Controller->data = array(
  1032. '_Token' => compact('key', 'fields')
  1033. );
  1034. $result = $this->Controller->Security->validatePost($this->Controller);
  1035. $this->assertFalse($result);
  1036. $this->Controller->data = array(
  1037. '_Token' => compact('key', 'fields'),
  1038. 'Test' => array('test' => '')
  1039. );
  1040. $result = $this->Controller->Security->validatePost($this->Controller);
  1041. $this->assertTrue($result);
  1042. $this->Controller->data = array(
  1043. '_Token' => compact('key', 'fields'),
  1044. 'Test' => array('test' => '1')
  1045. );
  1046. $result = $this->Controller->Security->validatePost($this->Controller);
  1047. $this->assertTrue($result);
  1048. $this->Controller->data = array(
  1049. '_Token' => compact('key', 'fields'),
  1050. 'Test' => array('test' => '2')
  1051. );
  1052. $result = $this->Controller->Security->validatePost($this->Controller);
  1053. $this->assertTrue($result);
  1054. }
  1055. /**
  1056. * testInvalidAuthHeaders method
  1057. *
  1058. * @access public
  1059. * @return void
  1060. */
  1061. function testInvalidAuthHeaders() {
  1062. $this->Controller->Security->blackHoleCallback = null;
  1063. $_SERVER['PHP_AUTH_USER'] = 'admin';
  1064. $_SERVER['PHP_AUTH_PW'] = 'password';
  1065. $realm = 'cakephp.org';
  1066. $loginData = array('type' => 'basic', 'realm' => $realm);
  1067. $this->Controller->Security->requireLogin($loginData);
  1068. $this->Controller->Security->startup($this->Controller);
  1069. $expected = 'WWW-Authenticate: Basic realm="'.$realm.'"';
  1070. $this->assertEqual(count($this->Controller->testHeaders), 1);
  1071. $this->assertEqual(current($this->Controller->testHeaders), $expected);
  1072. }
  1073. /**
  1074. * test that a requestAction's controller will have the _Token appended to
  1075. * the params.
  1076. *
  1077. * @return void
  1078. * @see http://cakephp.lighthouseapp.com/projects/42648/tickets/68
  1079. */
  1080. function testSettingTokenForRequestAction() {
  1081. $this->Controller->Security->startup($this->Controller);
  1082. $key = $this->Controller->params['_Token']['key'];
  1083. $this->Controller->params['requested'] = 1;
  1084. unset($this->Controller->params['_Token']);
  1085. $this->Controller->Security->startup($this->Controller);
  1086. $this->assertEqual($this->Controller->params['_Token']['key'], $key);
  1087. }
  1088. /**
  1089. * test that blackhole doesn't delete the _Token session key so repeat data submissions
  1090. * stay blackholed.
  1091. *
  1092. * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/214
  1093. * @return void
  1094. */
  1095. function testBlackHoleNotDeletingSessionInformation() {
  1096. $this->Controller->Security->startup($this->Controller);
  1097. $this->Controller->Security->blackHole($this->Controller, 'auth');
  1098. $this->assertTrue($this->Controller->Security->Session->check('_Token'), '_Token was deleted by blackHole %s');
  1099. }
  1100. }
  1101. ?>