PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

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

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