AuthComponentTest.php 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  1. <?php
  2. /**
  3. * AuthComponentTest file
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
  8. * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice
  12. *
  13. * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
  15. * @package cake.tests.cases.libs.controller.components
  16. * @since CakePHP(tm) v 1.2.0.5347
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. App::uses('Controller', 'Controller');
  20. App::uses('AuthComponent', 'Controller/Component');
  21. App::uses('AclComponent', 'Controller/Component');
  22. App::uses('FormAuthenticate', 'Controller/Component/Auth');
  23. /**
  24. * TestAuthComponent class
  25. *
  26. * @package cake
  27. * @package cake.tests.cases.libs.controller.components
  28. */
  29. class TestAuthComponent extends AuthComponent {
  30. /**
  31. * testStop property
  32. *
  33. * @var bool false
  34. * @access public
  35. */
  36. public $testStop = false;
  37. /**
  38. * stop method
  39. *
  40. * @access public
  41. * @return void
  42. */
  43. function _stop($status = 0) {
  44. $this->testStop = true;
  45. }
  46. }
  47. /**
  48. * AuthUser class
  49. *
  50. * @package cake
  51. * @package cake.tests.cases.libs.controller.components
  52. */
  53. class AuthUser extends CakeTestModel {
  54. /**
  55. * name property
  56. *
  57. * @var string 'AuthUser'
  58. * @access public
  59. */
  60. public $name = 'AuthUser';
  61. /**
  62. * useDbConfig property
  63. *
  64. * @var string 'test'
  65. * @access public
  66. */
  67. public $useDbConfig = 'test';
  68. }
  69. /**
  70. * AuthTestController class
  71. *
  72. * @package cake
  73. * @package cake.tests.cases.libs.controller.components
  74. */
  75. class AuthTestController extends Controller {
  76. /**
  77. * name property
  78. *
  79. * @var string 'AuthTest'
  80. * @access public
  81. */
  82. public $name = 'AuthTest';
  83. /**
  84. * uses property
  85. *
  86. * @var array
  87. * @access public
  88. */
  89. public $uses = array('AuthUser');
  90. /**
  91. * components property
  92. *
  93. * @var array
  94. * @access public
  95. */
  96. public $components = array('Session', 'Auth');
  97. /**
  98. * testUrl property
  99. *
  100. * @var mixed null
  101. * @access public
  102. */
  103. public $testUrl = null;
  104. /**
  105. * construct method
  106. *
  107. * @access private
  108. * @return void
  109. */
  110. function __construct($request) {
  111. $request->addParams(Router::parse('/auth_test'));
  112. $request->here = '/auth_test';
  113. $request->webroot = '/';
  114. Router::setRequestInfo($request);
  115. parent::__construct($request);
  116. }
  117. /**
  118. * login method
  119. *
  120. * @access public
  121. * @return void
  122. */
  123. function login() {
  124. }
  125. /**
  126. * admin_login method
  127. *
  128. * @access public
  129. * @return void
  130. */
  131. function admin_login() {
  132. }
  133. /**
  134. * admin_add method
  135. *
  136. * @access public
  137. * @return void
  138. */
  139. function admin_add() {
  140. }
  141. /**
  142. * logout method
  143. *
  144. * @access public
  145. * @return void
  146. */
  147. function logout() {
  148. }
  149. /**
  150. * add method
  151. *
  152. * @access public
  153. * @return void
  154. */
  155. function add() {
  156. echo "add";
  157. }
  158. /**
  159. * add method
  160. *
  161. * @access public
  162. * @return void
  163. */
  164. function camelCase() {
  165. echo "camelCase";
  166. }
  167. /**
  168. * redirect method
  169. *
  170. * @param mixed $url
  171. * @param mixed $status
  172. * @param mixed $exit
  173. * @access public
  174. * @return void
  175. */
  176. function redirect($url, $status = null, $exit = true) {
  177. $this->testUrl = Router::url($url);
  178. return false;
  179. }
  180. /**
  181. * isAuthorized method
  182. *
  183. * @access public
  184. * @return void
  185. */
  186. function isAuthorized() {
  187. }
  188. }
  189. /**
  190. * AjaxAuthController class
  191. *
  192. * @package cake.tests.cases.libs.controller.components
  193. */
  194. class AjaxAuthController extends Controller {
  195. /**
  196. * name property
  197. *
  198. * @var string 'AjaxAuth'
  199. * @access public
  200. */
  201. public $name = 'AjaxAuth';
  202. /**
  203. * components property
  204. *
  205. * @var array
  206. * @access public
  207. */
  208. public $components = array('Session', 'TestAuth');
  209. /**
  210. * uses property
  211. *
  212. * @var array
  213. * @access public
  214. */
  215. public $uses = array();
  216. /**
  217. * testUrl property
  218. *
  219. * @var mixed null
  220. * @access public
  221. */
  222. public $testUrl = null;
  223. /**
  224. * beforeFilter method
  225. *
  226. * @access public
  227. * @return void
  228. */
  229. function beforeFilter() {
  230. $this->TestAuth->ajaxLogin = 'test_element';
  231. $this->TestAuth->userModel = 'AuthUser';
  232. $this->TestAuth->RequestHandler->ajaxLayout = 'ajax2';
  233. }
  234. /**
  235. * add method
  236. *
  237. * @access public
  238. * @return void
  239. */
  240. function add() {
  241. if ($this->TestAuth->testStop !== true) {
  242. echo 'Added Record';
  243. }
  244. }
  245. /**
  246. * redirect method
  247. *
  248. * @param mixed $url
  249. * @param mixed $status
  250. * @param mixed $exit
  251. * @access public
  252. * @return void
  253. */
  254. function redirect($url, $status = null, $exit = true) {
  255. $this->testUrl = Router::url($url);
  256. return false;
  257. }
  258. }
  259. /**
  260. * AuthTest class
  261. *
  262. * @package cake
  263. * @package cake.tests.cases.libs.controller.components
  264. */
  265. class AuthTest extends CakeTestCase {
  266. /**
  267. * name property
  268. *
  269. * @var string 'Auth'
  270. * @access public
  271. */
  272. public $name = 'Auth';
  273. /**
  274. * fixtures property
  275. *
  276. * @var array
  277. * @access public
  278. */
  279. public $fixtures = array('core.auth_user');
  280. /**
  281. * initialized property
  282. *
  283. * @var bool false
  284. * @access public
  285. */
  286. public $initialized = false;
  287. /**
  288. * setUp method
  289. *
  290. * @access public
  291. * @return void
  292. */
  293. function setUp() {
  294. parent::setUp();
  295. $this->_server = $_SERVER;
  296. $this->_env = $_ENV;
  297. Configure::write('Security.salt', 'YJfIxfs2guVoUubWDYhG93b0qyJfIxfs2guwvniR2G0FgaC9mi');
  298. Configure::write('Security.cipherSeed', 770011223369876);
  299. $request = new CakeRequest(null, false);
  300. $this->Controller = new AuthTestController($request);
  301. $collection = new ComponentCollection();
  302. $collection->init($this->Controller);
  303. $this->Auth = new TestAuthComponent($collection);
  304. $this->Auth->request = $request;
  305. $this->Auth->response = $this->getMock('CakeResponse');
  306. $this->Controller->Components->init($this->Controller);
  307. $this->initialized = true;
  308. Router::reload();
  309. ClassRegistry::init('AuthUser')->updateAll(array('password' => '"' . Security::hash('cake', null, true) . '"'));
  310. }
  311. /**
  312. * tearDown method
  313. *
  314. * @return void
  315. */
  316. function tearDown() {
  317. parent::tearDown();
  318. $_SERVER = $this->_server;
  319. $_ENV = $this->_env;
  320. $this->Auth->Session->delete('Auth');
  321. $this->Auth->Session->delete('Message.auth');
  322. unset($this->Controller, $this->Auth);
  323. }
  324. /**
  325. * testNoAuth method
  326. *
  327. * @access public
  328. * @return void
  329. */
  330. function testNoAuth() {
  331. $this->assertFalse($this->Auth->isAuthorized());
  332. }
  333. /**
  334. * testIsErrorOrTests
  335. *
  336. * @access public
  337. * @return void
  338. */
  339. function testIsErrorOrTests() {
  340. $this->Controller->Auth->initialize($this->Controller);
  341. $this->Controller->name = 'CakeError';
  342. $this->assertTrue($this->Controller->Auth->startup($this->Controller));
  343. $this->Controller->name = 'Post';
  344. $this->Controller->request['action'] = 'thisdoesnotexist';
  345. $this->assertTrue($this->Controller->Auth->startup($this->Controller));
  346. $this->Controller->scaffold = null;
  347. $this->Controller->request['action'] = 'index';
  348. $this->assertFalse($this->Controller->Auth->startup($this->Controller));
  349. }
  350. /**
  351. * testLogin method
  352. *
  353. * @access public
  354. * @return void
  355. */
  356. function testLogin() {
  357. $this->getMock('FormAuthenticate', array(), array(), 'AuthLoginFormAuthenticate', false);
  358. $this->Auth->authenticate = array(
  359. 'AuthLoginForm' => array(
  360. 'userModel' => 'AuthUser'
  361. )
  362. );
  363. $mocks = $this->Auth->constructAuthenticate();
  364. $this->mockObjects[] = $mocks[0];
  365. $this->Auth->request->data = array(
  366. 'AuthUser' => array(
  367. 'username' => 'mark',
  368. 'password' => Security::hash('cake', null, true)
  369. )
  370. );
  371. $user = array(
  372. 'id' => 1,
  373. 'username' => 'mark'
  374. );
  375. $mocks[0]->expects($this->once())
  376. ->method('authenticate')
  377. ->with($this->Auth->request)
  378. ->will($this->returnValue($user));
  379. $result = $this->Auth->login();
  380. $this->assertTrue($result);
  381. $this->assertTrue($this->Auth->loggedIn());
  382. $this->assertEquals($user, $this->Auth->user());
  383. }
  384. /**
  385. * test that being redirected to the login page, with no post data does
  386. * not set the session value. Saving the session value in this circumstance
  387. * can cause the user to be redirected to an already public page.
  388. *
  389. * @return void
  390. */
  391. function testLoginActionNotSettingAuthRedirect() {
  392. $_SERVER['HTTP_REFERER'] = '/pages/display/about';
  393. $this->Controller->data = array();
  394. $this->Controller->request->addParams(Router::parse('auth_test/login'));
  395. $this->Controller->request->url = 'auth_test/login';
  396. $this->Auth->Session->delete('Auth');
  397. $this->Auth->loginRedirect = '/users/dashboard';
  398. $this->Auth->loginAction = 'auth_test/login';
  399. $this->Auth->userModel = 'AuthUser';
  400. $this->Auth->startup($this->Controller);
  401. $redirect = $this->Auth->Session->read('Auth.redirect');
  402. $this->assertNull($redirect);
  403. }
  404. /**
  405. * testAuthorizeFalse method
  406. *
  407. * @access public
  408. * @return void
  409. */
  410. function testAuthorizeFalse() {
  411. $this->AuthUser = new AuthUser();
  412. $user = $this->AuthUser->find();
  413. $this->Auth->Session->write('Auth.User', $user['AuthUser']);
  414. $this->Controller->Auth->userModel = 'AuthUser';
  415. $this->Controller->Auth->authorize = false;
  416. $this->Controller->request->addParams(Router::parse('auth_test/add'));
  417. $result = $this->Controller->Auth->startup($this->Controller);
  418. $this->assertTrue($result);
  419. $this->Auth->Session->delete('Auth');
  420. $result = $this->Controller->Auth->startup($this->Controller);
  421. $this->assertFalse($result);
  422. $this->assertTrue($this->Auth->Session->check('Message.auth'));
  423. $this->Controller->request->addParams(Router::parse('auth_test/camelCase'));
  424. $result = $this->Controller->Auth->startup($this->Controller);
  425. $this->assertFalse($result);
  426. }
  427. /**
  428. * @expectedException CakeException
  429. * @return void
  430. */
  431. function testIsAuthorizedMissingFile() {
  432. $this->Controller->Auth->authorize = 'Missing';
  433. $this->Controller->Auth->isAuthorized(array('User' => array('id' => 1)));
  434. }
  435. /**
  436. * test that isAuthroized calls methods correctly
  437. *
  438. * @return void
  439. */
  440. function testIsAuthorizedDelegation() {
  441. $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockOneAuthorize', false);
  442. $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockTwoAuthorize', false);
  443. $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockThreeAuthorize', false);
  444. $this->Auth->authorize = array(
  445. 'AuthMockOne',
  446. 'AuthMockTwo',
  447. 'AuthMockThree'
  448. );
  449. $mocks = $this->Auth->constructAuthorize();
  450. $request = $this->Auth->request;
  451. $this->assertEquals(3, count($mocks));
  452. $mocks[0]->expects($this->once())
  453. ->method('authorize')
  454. ->with(array('User'), $request)
  455. ->will($this->returnValue(false));
  456. $mocks[1]->expects($this->once())
  457. ->method('authorize')
  458. ->with(array('User'), $request)
  459. ->will($this->returnValue(true));
  460. $mocks[2]->expects($this->never())
  461. ->method('authorize');
  462. $this->assertTrue($this->Auth->isAuthorized(array('User'), $request));
  463. }
  464. /**
  465. * test that isAuthorized will use the session user if none is given.
  466. *
  467. * @return void
  468. */
  469. function testIsAuthorizedUsingUserInSession() {
  470. $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockFourAuthorize', false);
  471. $this->Auth->authorize = array('AuthMockFour');
  472. $user = array('user' => 'mark');
  473. $this->Auth->Session->write('Auth.User', $user);
  474. $mocks = $this->Auth->constructAuthorize();
  475. $request = $this->Controller->request;
  476. $mocks[0]->expects($this->once())
  477. ->method('authorize')
  478. ->with($user, $request)
  479. ->will($this->returnValue(true));
  480. $this->assertTrue($this->Auth->isAuthorized(null, $request));
  481. }
  482. /**
  483. * test that loadAuthorize resets the loaded objects each time.
  484. *
  485. * @return void
  486. */
  487. function testLoadAuthorizeResets() {
  488. $this->Controller->Auth->authorize = array(
  489. 'Controller'
  490. );
  491. $result = $this->Controller->Auth->constructAuthorize();
  492. $this->assertEquals(1, count($result));
  493. $result = $this->Controller->Auth->constructAuthorize();
  494. $this->assertEquals(1, count($result));
  495. }
  496. /**
  497. * @expectedException CakeException
  498. * @return void
  499. */
  500. function testLoadAuthenticateNoFile() {
  501. $this->Controller->Auth->authenticate = 'Missing';
  502. $this->Controller->Auth->identify($this->Controller->request, $this->Controller->response);
  503. }
  504. /**
  505. * test the * key with authenticate
  506. *
  507. * @return void
  508. */
  509. function testAllConfigWithAuthorize() {
  510. $this->Controller->Auth->authorize = array(
  511. AuthComponent::ALL => array('actionPath' => 'controllers/'),
  512. 'Actions'
  513. );
  514. $objects = $this->Controller->Auth->constructAuthorize();
  515. $result = $objects[0];
  516. $this->assertEquals($result->settings['actionPath'], 'controllers/');
  517. }
  518. /**
  519. * test that loadAuthorize resets the loaded objects each time.
  520. *
  521. * @return void
  522. */
  523. function testLoadAuthenticateResets() {
  524. $this->Controller->Auth->authenticate = array(
  525. 'Form'
  526. );
  527. $result = $this->Controller->Auth->constructAuthenticate();
  528. $this->assertEquals(1, count($result));
  529. $result = $this->Controller->Auth->constructAuthenticate();
  530. $this->assertEquals(1, count($result));
  531. }
  532. /**
  533. * test the * key with authenticate
  534. *
  535. * @return void
  536. */
  537. function testAllConfigWithAuthenticate() {
  538. $this->Controller->Auth->authenticate = array(
  539. AuthComponent::ALL => array('userModel' => 'AuthUser'),
  540. 'Form'
  541. );
  542. $objects = $this->Controller->Auth->constructAuthenticate();
  543. $result = $objects[0];
  544. $this->assertEquals($result->settings['userModel'], 'AuthUser');
  545. }
  546. /**
  547. * Tests that deny always takes precedence over allow
  548. *
  549. * @access public
  550. * @return void
  551. */
  552. function testAllowDenyAll() {
  553. $this->Controller->Auth->initialize($this->Controller);
  554. $this->Controller->Auth->allow('*');
  555. $this->Controller->Auth->deny('add', 'camelCase');
  556. $this->Controller->request['action'] = 'delete';
  557. $this->assertTrue($this->Controller->Auth->startup($this->Controller));
  558. $this->Controller->request['action'] = 'add';
  559. $this->assertFalse($this->Controller->Auth->startup($this->Controller));
  560. $this->Controller->request['action'] = 'camelCase';
  561. $this->assertFalse($this->Controller->Auth->startup($this->Controller));
  562. $this->Controller->Auth->allow('*');
  563. $this->Controller->Auth->deny(array('add', 'camelCase'));
  564. $this->Controller->request['action'] = 'camelCase';
  565. $this->assertFalse($this->Controller->Auth->startup($this->Controller));
  566. }
  567. /**
  568. * test that deny() converts camel case inputs to lowercase.
  569. *
  570. * @return void
  571. */
  572. function testDenyWithCamelCaseMethods() {
  573. $this->Controller->Auth->initialize($this->Controller);
  574. $this->Controller->Auth->allow('*');
  575. $this->Controller->Auth->deny('add', 'camelCase');
  576. $url = '/auth_test/camelCase';
  577. $this->Controller->request->addParams(Router::parse($url));
  578. $this->Controller->request->query['url'] = Router::normalize($url);
  579. $this->assertFalse($this->Controller->Auth->startup($this->Controller));
  580. }
  581. /**
  582. * test that allow() and allowedActions work with camelCase method names.
  583. *
  584. * @return void
  585. */
  586. function testAllowedActionsWithCamelCaseMethods() {
  587. $url = '/auth_test/camelCase';
  588. $this->Controller->request->addParams(Router::parse($url));
  589. $this->Controller->request->query['url'] = Router::normalize($url);
  590. $this->Controller->Auth->initialize($this->Controller);
  591. $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  592. $this->Controller->Auth->userModel = 'AuthUser';
  593. $this->Controller->Auth->allow('*');
  594. $result = $this->Controller->Auth->startup($this->Controller);
  595. $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
  596. $url = '/auth_test/camelCase';
  597. $this->Controller->request->addParams(Router::parse($url));
  598. $this->Controller->request->query['url'] = Router::normalize($url);
  599. $this->Controller->Auth->initialize($this->Controller);
  600. $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  601. $this->Controller->Auth->userModel = 'AuthUser';
  602. $this->Controller->Auth->allowedActions = array('delete', 'camelCase', 'add');
  603. $result = $this->Controller->Auth->startup($this->Controller);
  604. $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
  605. $this->Controller->Auth->allowedActions = array('delete', 'add');
  606. $result = $this->Controller->Auth->startup($this->Controller);
  607. $this->assertFalse($result, 'startup() should return false, as action is not allowed. %s');
  608. $url = '/auth_test/delete';
  609. $this->Controller->request->addParams(Router::parse($url));
  610. $this->Controller->request->query['url'] = Router::normalize($url);
  611. $this->Controller->Auth->initialize($this->Controller);
  612. $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  613. $this->Controller->Auth->userModel = 'AuthUser';
  614. $this->Controller->Auth->allow(array('delete', 'add'));
  615. $result = $this->Controller->Auth->startup($this->Controller);
  616. $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
  617. }
  618. function testAllowedActionsSetWithAllowMethod() {
  619. $url = '/auth_test/action_name';
  620. $this->Controller->request->addParams(Router::parse($url));
  621. $this->Controller->request->query['url'] = Router::normalize($url);
  622. $this->Controller->Auth->initialize($this->Controller);
  623. $this->Controller->Auth->allow('action_name', 'anotherAction');
  624. $this->assertEqual($this->Controller->Auth->allowedActions, array('action_name', 'anotherAction'));
  625. }
  626. /**
  627. * testLoginRedirect method
  628. *
  629. * @access public
  630. * @return void
  631. */
  632. function testLoginRedirect() {
  633. $_SERVER['HTTP_REFERER'] = false;
  634. $_ENV['HTTP_REFERER'] = false;
  635. putenv('HTTP_REFERER=');
  636. $this->Auth->Session->write('Auth', array(
  637. 'AuthUser' => array('id' => '1', 'username' => 'nate')
  638. ));
  639. $this->Auth->request->addParams(Router::parse('users/login'));
  640. $this->Auth->request->url = 'users/login';
  641. $this->Auth->initialize($this->Controller);
  642. $this->Auth->loginRedirect = array(
  643. 'controller' => 'pages', 'action' => 'display', 'welcome'
  644. );
  645. $this->Auth->startup($this->Controller);
  646. $expected = Router::normalize($this->Auth->loginRedirect);
  647. $this->assertEqual($expected, $this->Auth->redirect());
  648. $this->Auth->Session->delete('Auth');
  649. //empty referer no session
  650. $_SERVER['HTTP_REFERER'] = false;
  651. $_ENV['HTTP_REFERER'] = false;
  652. putenv('HTTP_REFERER=');
  653. $url = '/posts/view/1';
  654. $this->Auth->Session->write('Auth', array(
  655. 'AuthUser' => array('id' => '1', 'username' => 'nate'))
  656. );
  657. $this->Controller->testUrl = null;
  658. $this->Auth->request->addParams(Router::parse($url));
  659. array_push($this->Controller->methods, 'view', 'edit', 'index');
  660. $this->Auth->initialize($this->Controller);
  661. $this->Auth->authorize = 'controller';
  662. $this->Auth->loginAction = array(
  663. 'controller' => 'AuthTest', 'action' => 'login'
  664. );
  665. $this->Auth->startup($this->Controller);
  666. $expected = Router::normalize('/AuthTest/login');
  667. $this->assertEqual($expected, $this->Controller->testUrl);
  668. $this->Auth->Session->delete('Auth');
  669. $_SERVER['HTTP_REFERER'] = $_ENV['HTTP_REFERER'] = Router::url('/admin', true);
  670. $this->Auth->Session->write('Auth', array(
  671. 'AuthUser' => array('id'=>'1', 'username' => 'nate')
  672. ));
  673. $this->Auth->request->params['action'] = 'login';
  674. $this->Auth->request->url = 'auth_test/login';
  675. $this->Auth->initialize($this->Controller);
  676. $this->Auth->loginAction = 'auth_test/login';
  677. $this->Auth->loginRedirect = false;
  678. $this->Auth->startup($this->Controller);
  679. $expected = Router::normalize('/admin');
  680. $this->assertEqual($expected, $this->Auth->redirect());
  681. //Ticket #4750
  682. //named params
  683. $this->Auth->Session->delete('Auth');
  684. $url = '/posts/index/year:2008/month:feb';
  685. $this->Auth->request->addParams(Router::parse($url));
  686. $this->Auth->request->url = Router::normalize($url);
  687. $this->Auth->initialize($this->Controller);
  688. $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  689. $this->Auth->startup($this->Controller);
  690. $expected = Router::normalize('posts/index/year:2008/month:feb');
  691. $this->assertEqual($expected, $this->Auth->Session->read('Auth.redirect'));
  692. //passed args
  693. $this->Auth->Session->delete('Auth');
  694. $url = '/posts/view/1';
  695. $this->Auth->request->addParams(Router::parse($url));
  696. $this->Auth->request->url = Router::normalize($url);
  697. $this->Auth->initialize($this->Controller);
  698. $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  699. $this->Auth->startup($this->Controller);
  700. $expected = Router::normalize('posts/view/1');
  701. $this->assertEqual($expected, $this->Auth->Session->read('Auth.redirect'));
  702. // QueryString parameters
  703. $_back = $_GET;
  704. $_GET = array(
  705. 'url' => '/posts/index/29',
  706. 'print' => 'true',
  707. 'refer' => 'menu'
  708. );
  709. $this->Auth->Session->delete('Auth');
  710. $url = '/posts/index/29';
  711. $this->Auth->request = $this->Controller->request = new CakeRequest($url);
  712. $this->Auth->request->addParams(Router::parse($url));
  713. $this->Auth->initialize($this->Controller);
  714. $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  715. $this->Auth->startup($this->Controller);
  716. $expected = Router::normalize('posts/index/29?print=true&refer=menu');
  717. $this->assertEqual($expected, $this->Auth->Session->read('Auth.redirect'));
  718. $_GET = array(
  719. 'url' => '/posts/index/29',
  720. 'print' => 'true',
  721. 'refer' => 'menu'
  722. );
  723. $this->Auth->Session->delete('Auth');
  724. $url = '/posts/index/29';
  725. $this->Auth->request = $this->Controller->request = new CakeRequest($url);
  726. $this->Auth->request->addParams(Router::parse($url));
  727. $this->Auth->initialize($this->Controller);
  728. $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  729. $this->Auth->startup($this->Controller);
  730. $expected = Router::normalize('posts/index/29?print=true&refer=menu');
  731. $this->assertEqual($expected, $this->Auth->Session->read('Auth.redirect'));
  732. $_GET = $_back;
  733. //external authed action
  734. $_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
  735. $_GET = array(
  736. 'url' => '/posts/edit/1'
  737. );
  738. $this->Auth->Session->delete('Auth');
  739. $url = '/posts/edit/1';
  740. $this->Auth->request = $this->Controller->request = new CakeRequest($url);
  741. $this->Auth->request->addParams(Router::parse($url));
  742. $this->Auth->request->url = Router::normalize($url);
  743. $this->Auth->initialize($this->Controller);
  744. $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  745. $this->Auth->startup($this->Controller);
  746. $expected = Router::normalize('/posts/edit/1');
  747. $this->assertEqual($expected, $this->Auth->Session->read('Auth.redirect'));
  748. //external direct login link
  749. $_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
  750. $this->Auth->Session->delete('Auth');
  751. $url = '/AuthTest/login';
  752. $this->Auth->request = $this->Controller->request = new CakeRequest($url);
  753. $this->Auth->request->addParams(Router::parse($url));
  754. $this->Auth->request->url = Router::normalize($url);
  755. $this->Auth->initialize($this->Controller);
  756. $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  757. $this->Auth->startup($this->Controller);
  758. $expected = Router::normalize('/');
  759. $this->assertEqual($expected, $this->Auth->Session->read('Auth.redirect'));
  760. $this->Auth->Session->delete('Auth');
  761. }
  762. /**
  763. * test that no redirects or authoization tests occur on the loginAction
  764. *
  765. * @return void
  766. */
  767. function testNoRedirectOnLoginAction() {
  768. $controller = $this->getMock('Controller');
  769. $controller->methods = array('login');
  770. $url = '/AuthTest/login';
  771. $this->Auth->request = $controller->request = new CakeRequest($url);
  772. $this->Auth->request->addParams(Router::parse($url));
  773. $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
  774. $this->Auth->authorize = array('Controller');
  775. $controller->expects($this->never())
  776. ->method('redirect');
  777. $this->Auth->startup($controller);
  778. }
  779. /**
  780. * Ensure that no redirect is performed when a 404 is reached
  781. * And the user doesn't have a session.
  782. *
  783. * @return void
  784. */
  785. function testNoRedirectOn404() {
  786. $this->Auth->Session->delete('Auth');
  787. $this->Auth->initialize($this->Controller);
  788. $this->Auth->request->addParams(Router::parse('auth_test/something_totally_wrong'));
  789. $result = $this->Auth->startup($this->Controller);
  790. $this->assertTrue($result, 'Auth redirected a missing action %s');
  791. }
  792. /**
  793. * testAdminRoute method
  794. *
  795. * @access public
  796. * @return void
  797. */
  798. function testAdminRoute() {
  799. $prefixes = Configure::read('Routing.prefixes');
  800. Configure::write('Routing.prefixes', array('admin'));
  801. Router::reload();
  802. $url = '/admin/auth_test/add';
  803. $this->Auth->request->addParams(Router::parse($url));
  804. $this->Auth->request->query['url'] = ltrim($url, '/');
  805. $this->Auth->request->base = '';
  806. Router::setRequestInfo($this->Auth->request);
  807. $this->Auth->initialize($this->Controller);
  808. $this->Auth->loginAction = array(
  809. 'admin' => true, 'controller' => 'auth_test', 'action' => 'login'
  810. );
  811. $this->Auth->startup($this->Controller);
  812. $this->assertEqual($this->Controller->testUrl, '/admin/auth_test/login');
  813. Configure::write('Routing.prefixes', $prefixes);
  814. }
  815. /**
  816. * testAjaxLogin method
  817. *
  818. * @access public
  819. * @return void
  820. */
  821. function testAjaxLogin() {
  822. App::build(array(
  823. 'View' => array(LIBS . 'Test' . DS . 'test_app' . DS . 'View'. DS)
  824. ));
  825. $_SERVER['HTTP_X_REQUESTED_WITH'] = "XMLHttpRequest";
  826. App::uses('Dispatcher', 'Routing');
  827. ob_start();
  828. $Dispatcher = new Dispatcher();
  829. $Dispatcher->dispatch(new CakeRequest('/ajax_auth/add'), array('return' => 1));
  830. $result = ob_get_clean();
  831. $this->assertEqual("Ajax!\nthis is the test element", str_replace("\r\n", "\n", $result));
  832. unset($_SERVER['HTTP_X_REQUESTED_WITH']);
  833. }
  834. /**
  835. * testLoginActionRedirect method
  836. *
  837. * @access public
  838. * @return void
  839. */
  840. function testLoginActionRedirect() {
  841. $admin = Configure::read('Routing.prefixes');
  842. Configure::write('Routing.prefixes', array('admin'));
  843. Router::reload();
  844. $url = '/admin/auth_test/login';
  845. $this->Auth->request->addParams(Router::parse($url));
  846. $this->Auth->request->url = ltrim($url, '/');
  847. Router::setRequestInfo(array(
  848. array(
  849. 'pass' => array(), 'action' => 'admin_login', 'plugin' => null, 'controller' => 'auth_test',
  850. 'admin' => true,
  851. ),
  852. array(
  853. 'base' => null, 'here' => $url,
  854. 'webroot' => '/', 'passedArgs' => array(),
  855. )
  856. ));
  857. $this->Auth->initialize($this->Controller);
  858. $this->Auth->loginAction = array('admin' => true, 'controller' => 'auth_test', 'action' => 'login');
  859. $this->Auth->startup($this->Controller);
  860. $this->assertNull($this->Controller->testUrl);
  861. Configure::write('Routing.prefixes', $admin);
  862. }
  863. /**
  864. * Tests that shutdown destroys the redirect session var
  865. *
  866. * @access public
  867. * @return void
  868. */
  869. function testShutDown() {
  870. $this->Auth->Session->write('Auth.User', 'not empty');
  871. $this->Auth->Session->write('Auth.redirect', 'foo');
  872. $this->Controller->Auth->loggedIn(true);
  873. $this->Controller->Auth->shutdown($this->Controller);
  874. $this->assertNull($this->Auth->Session->read('Auth.redirect'));
  875. }
  876. /**
  877. * test $settings in Controller::$components
  878. *
  879. * @access public
  880. * @return void
  881. */
  882. function testComponentSettings() {
  883. $request = new CakeRequest(null, false);
  884. $this->Controller = new AuthTestController($request);
  885. $this->Controller->components = array(
  886. 'Auth' => array(
  887. 'loginAction' => array('controller' => 'people', 'action' => 'login'),
  888. 'logoutRedirect' => array('controller' => 'people', 'action' => 'login'),
  889. ),
  890. 'Session'
  891. );
  892. $this->Controller->Components->init($this->Controller);
  893. $this->Controller->Components->trigger('initialize', array(&$this->Controller));
  894. Router::reload();
  895. $expected = array(
  896. 'loginAction' => array('controller' => 'people', 'action' => 'login'),
  897. 'logoutRedirect' => array('controller' => 'people', 'action' => 'login'),
  898. );
  899. $this->assertEqual($expected['loginAction'], $this->Controller->Auth->loginAction);
  900. $this->assertEqual($expected['logoutRedirect'], $this->Controller->Auth->logoutRedirect);
  901. }
  902. /**
  903. * test that logout deletes the session variables. and returns the correct url
  904. *
  905. * @return void
  906. */
  907. function testLogout() {
  908. $this->Auth->Session->write('Auth.User.id', '1');
  909. $this->Auth->Session->write('Auth.redirect', '/users/login');
  910. $this->Auth->logoutRedirect = '/';
  911. $result = $this->Auth->logout();
  912. $this->assertEqual($result, '/');
  913. $this->assertNull($this->Auth->Session->read('Auth.AuthUser'));
  914. $this->assertNull($this->Auth->Session->read('Auth.redirect'));
  915. }
  916. /**
  917. * test mapActions loading and delegating to authorize objects.
  918. *
  919. * @return void
  920. */
  921. function testMapActionsDelegation() {
  922. $this->getMock('BaseAuthorize', array('authorize'), array(), 'MapActionMockAuthorize', false);
  923. $this->Auth->authorize = array('MapActionMock');
  924. $mock = $this->Auth->constructAuthorize();
  925. $mock[0]->expects($this->once())
  926. ->method('mapActions')
  927. ->with(array('create' => array('my_action')));
  928. $this->Auth->mapActions(array('create' => array('my_action')));
  929. }
  930. /**
  931. * test logging in with a request.
  932. *
  933. * @return void
  934. */
  935. function testLoginWithRequestData() {
  936. $this->getMock('FormAuthenticate', array(), array(), 'RequestLoginMockAuthenticate', false);
  937. $request = new CakeRequest('users/login', false);
  938. $user = array('username' => 'mark', 'role' => 'admin');
  939. $this->Auth->request = $request;
  940. $this->Auth->authenticate = array('RequestLoginMock');
  941. $mock = $this->Auth->constructAuthenticate();
  942. $mock[0]->expects($this->once())
  943. ->method('authenticate')
  944. ->with($request)
  945. ->will($this->returnValue($user));
  946. $this->assertTrue($this->Auth->login());
  947. $this->assertEquals($user['username'], $this->Auth->user('username'));
  948. }
  949. /**
  950. * test login() with user data
  951. *
  952. * @return void
  953. */
  954. function testLoginWithUserData() {
  955. $this->assertFalse($this->Auth->loggedIn());
  956. $user = array(
  957. 'username' => 'mariano',
  958. 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
  959. 'created' => '2007-03-17 01:16:23',
  960. 'updated' => '2007-03-17 01:18:31'
  961. );
  962. $this->assertTrue($this->Auth->login($user));
  963. $this->assertTrue($this->Auth->loggedIn());
  964. $this->assertEquals($user['username'], $this->Auth->user('username'));
  965. }
  966. /**
  967. * test flash settings.
  968. *
  969. * @return void
  970. */
  971. function testFlashSettings() {
  972. $this->Auth->Session = $this->getMock('SessionComponent', array(), array(), '', false);
  973. $this->Auth->Session->expects($this->once())
  974. ->method('setFlash')
  975. ->with('Auth failure', 'custom', array(1), 'auth-key');
  976. $this->Auth->flash = array(
  977. 'element' => 'custom',
  978. 'params' => array(1),
  979. 'key' => 'auth-key'
  980. );
  981. $this->Auth->flash('Auth failure');
  982. }
  983. /**
  984. * test the various states of Auth::redirect()
  985. *
  986. * @return void
  987. */
  988. function testRedirectSet() {
  989. $value = array('controller' => 'users', 'action' => 'home');
  990. $result = $this->Auth->redirect($value);
  991. $this->assertEquals('/users/home', $result);
  992. $this->assertEquals($value, $this->Auth->Session->read('Auth.redirect'));
  993. }
  994. /**
  995. * test redirect using Auth.redirect from the session.
  996. *
  997. * @return void
  998. */
  999. function testRedirectSessionRead() {
  1000. $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
  1001. $this->Auth->Session->write('Auth.redirect', '/users/home');
  1002. $result = $this->Auth->redirect();
  1003. $this->assertEquals('/users/home', $result);
  1004. $this->assertFalse($this->Auth->Session->check('Auth.redirect'));
  1005. }
  1006. /**
  1007. * test that redirect does not return loginAction if that is what's stored in Auth.redirect.
  1008. * instead loginRedirect should be used.
  1009. *
  1010. * @return void
  1011. */
  1012. function testRedirectSessionReadEqualToLoginAction() {
  1013. $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
  1014. $this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'home');
  1015. $this->Auth->Session->write('Auth.redirect', array('controller' => 'users', 'action' => 'login'));
  1016. $result = $this->Auth->redirect();
  1017. $this->assertEquals('/users/home', $result);
  1018. $this->assertFalse($this->Auth->Session->check('Auth.redirect'));
  1019. }
  1020. /**
  1021. * test password hashing
  1022. *
  1023. * @return void
  1024. */
  1025. function testPassword() {
  1026. $result = $this->Auth->password('password');
  1027. $expected = Security::hash('password', null, true);
  1028. $this->assertEquals($expected, $result);
  1029. }
  1030. }