SessionTest.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. <?php
  2. /**
  3. * SessionTest file
  4. *
  5. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  6. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  14. * @since 1.2.0
  15. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  16. */
  17. namespace Cake\Test\TestCase\Network;
  18. use Cake\Cache\Cache;
  19. use Cake\Core\App;
  20. use Cake\Core\Configure;
  21. use Cake\Core\Plugin;
  22. use Cake\Network\Session;
  23. use Cake\Network\Session\CacheSession;
  24. use Cake\Network\Session\DatabaseSession;
  25. use Cake\TestSuite\TestCase;
  26. /**
  27. * Class TestCakeSession
  28. *
  29. */
  30. class TestCakeSession extends Session {
  31. public static function setUserAgent($value) {
  32. static::$_userAgent = $value;
  33. }
  34. public static function setHost($host) {
  35. static::_setHost($host);
  36. }
  37. }
  38. /**
  39. * Class TestCacheSession
  40. *
  41. */
  42. class TestCacheSession extends CacheSession {
  43. protected function _writeSession() {
  44. return true;
  45. }
  46. }
  47. /**
  48. * Class TestDatabaseSession
  49. *
  50. */
  51. class TestDatabaseSession extends DatabaseSession {
  52. protected function _writeSession() {
  53. return true;
  54. }
  55. }
  56. /**
  57. * SessionTest class
  58. *
  59. */
  60. class SessionTest extends TestCase {
  61. protected static $_gcDivisor;
  62. /**
  63. * Fixtures used in the SessionTest
  64. *
  65. * @var array
  66. */
  67. public $fixtures = array('core.session', 'core.cake_session');
  68. /**
  69. * setup before class.
  70. *
  71. * @return void
  72. */
  73. public static function setupBeforeClass() {
  74. // Make sure garbage colector will be called
  75. static::$_gcDivisor = ini_get('session.gc_divisor');
  76. ini_set('session.gc_divisor', '1');
  77. }
  78. /**
  79. * teardown after class
  80. *
  81. * @return void
  82. */
  83. public static function teardownAfterClass() {
  84. // Revert to the default setting
  85. ini_set('session.gc_divisor', static::$_gcDivisor);
  86. }
  87. /**
  88. * setUp method
  89. *
  90. * @return void
  91. */
  92. public function setUp() {
  93. parent::setUp();
  94. Configure::write('Session', array(
  95. 'defaults' => 'php',
  96. 'cookie' => 'cakephp',
  97. 'timeout' => 120,
  98. 'cookieTimeout' => 120,
  99. 'ini' => array(),
  100. ));
  101. }
  102. /**
  103. * tearDown method
  104. *
  105. * @return void
  106. */
  107. public function tearDown() {
  108. if (TestCakeSession::started()) {
  109. session_write_close();
  110. }
  111. unset($_SESSION);
  112. parent::tearDown();
  113. }
  114. /**
  115. * test setting ini properties with Session configuration.
  116. *
  117. * @return void
  118. */
  119. public function testSessionConfigIniSetting() {
  120. $_SESSION = null;
  121. Configure::write('Session', array(
  122. 'cookie' => 'test',
  123. 'checkAgent' => false,
  124. 'timeout' => 86400,
  125. 'ini' => array(
  126. 'session.referer_check' => 'example.com',
  127. 'session.use_trans_sid' => false
  128. )
  129. ));
  130. TestCakeSession::start();
  131. $this->assertEquals('', ini_get('session.use_trans_sid'), 'Ini value is incorrect');
  132. $this->assertEquals('example.com', ini_get('session.referer_check'), 'Ini value is incorrect');
  133. $this->assertEquals('test', ini_get('session.name'), 'Ini value is incorrect');
  134. }
  135. /**
  136. * testSessionPath
  137. *
  138. * @return void
  139. */
  140. public function testSessionPath() {
  141. TestCakeSession::init('/index.php');
  142. $this->assertEquals('/', TestCakeSession::$path);
  143. TestCakeSession::init('/sub_dir/index.php');
  144. $this->assertEquals('/sub_dir/', TestCakeSession::$path);
  145. }
  146. /**
  147. * testCakeSessionPathEmpty
  148. *
  149. * @return void
  150. */
  151. public function testCakeSessionPathEmpty() {
  152. TestCakeSession::init('');
  153. $this->assertEquals('/', TestCakeSession::$path, 'Session path is empty, with "" as $base needs to be /');
  154. }
  155. /**
  156. * testCakeSessionPathContainsParams
  157. *
  158. * @return void
  159. */
  160. public function testCakeSessionPathContainsQuestion() {
  161. TestCakeSession::init('/index.php?');
  162. $this->assertEquals('/', TestCakeSession::$path);
  163. }
  164. /**
  165. * testSetHost
  166. *
  167. * @return void
  168. */
  169. public function testSetHost() {
  170. TestCakeSession::init();
  171. TestCakeSession::setHost('cakephp.org');
  172. $this->assertEquals('cakephp.org', TestCakeSession::$host);
  173. }
  174. /**
  175. * testSetHostWithPort
  176. *
  177. * @return void
  178. */
  179. public function testSetHostWithPort() {
  180. TestCakeSession::init();
  181. TestCakeSession::setHost('cakephp.org:443');
  182. $this->assertEquals('cakephp.org', TestCakeSession::$host);
  183. }
  184. /**
  185. * test valid with bogus user agent.
  186. *
  187. * @return void
  188. */
  189. public function testValidBogusUserAgent() {
  190. Configure::write('Session.checkAgent', true);
  191. TestCakeSession::start();
  192. $this->assertTrue(TestCakeSession::valid(), 'Newly started session should be valid');
  193. TestCakeSession::userAgent('bogus!');
  194. $this->assertFalse(TestCakeSession::valid(), 'user agent mismatch should fail.');
  195. }
  196. /**
  197. * test valid with bogus user agent.
  198. *
  199. * @return void
  200. */
  201. public function testValidTimeExpiry() {
  202. Configure::write('Session.checkAgent', true);
  203. TestCakeSession::start();
  204. $this->assertTrue(TestCakeSession::valid(), 'Newly started session should be valid');
  205. TestCakeSession::$time = strtotime('next year');
  206. $this->assertFalse(TestCakeSession::valid(), 'time should cause failure.');
  207. }
  208. /**
  209. * testCheck method
  210. *
  211. * @return void
  212. */
  213. public function testCheck() {
  214. TestCakeSession::write('SessionTestCase', 'value');
  215. $this->assertTrue(TestCakeSession::check('SessionTestCase'));
  216. $this->assertFalse(TestCakeSession::check('NotExistingSessionTestCase'));
  217. }
  218. /**
  219. * testSimpleRead method
  220. *
  221. * @return void
  222. */
  223. public function testSimpleRead() {
  224. TestCakeSession::write('testing', '1,2,3');
  225. $result = TestCakeSession::read('testing');
  226. $this->assertEquals('1,2,3', $result);
  227. TestCakeSession::write('testing', array('1' => 'one', '2' => 'two', '3' => 'three'));
  228. $result = TestCakeSession::read('testing.1');
  229. $this->assertEquals('one', $result);
  230. $result = TestCakeSession::read('testing');
  231. $this->assertEquals(array('1' => 'one', '2' => 'two', '3' => 'three'), $result);
  232. $result = TestCakeSession::read();
  233. $this->assertTrue(isset($result['testing']));
  234. $this->assertTrue(isset($result['Config']));
  235. $this->assertTrue(isset($result['Config']['userAgent']));
  236. TestCakeSession::write('This.is.a.deep.array.my.friend', 'value');
  237. $result = TestCakeSession::read('This.is.a.deep.array.my.friend');
  238. $this->assertEquals('value', $result);
  239. }
  240. /**
  241. * testReadyEmpty
  242. *
  243. * @return void
  244. */
  245. public function testReadyEmpty() {
  246. $this->assertFalse(TestCakeSession::read(''));
  247. }
  248. /**
  249. * test writing a hash of values/
  250. *
  251. * @return void
  252. */
  253. public function testWriteArray() {
  254. $result = TestCakeSession::write(array(
  255. 'one' => 1,
  256. 'two' => 2,
  257. 'three' => array('something'),
  258. 'null' => null
  259. ));
  260. $this->assertTrue($result);
  261. $this->assertEquals(1, TestCakeSession::read('one'));
  262. $this->assertEquals(array('something'), TestCakeSession::read('three'));
  263. $this->assertEquals(null, TestCakeSession::read('null'));
  264. }
  265. /**
  266. * testWriteEmptyKey
  267. *
  268. * @return void
  269. */
  270. public function testWriteEmptyKey() {
  271. $this->assertFalse(TestCakeSession::write('', 'graham'));
  272. $this->assertFalse(TestCakeSession::write('', ''));
  273. $this->assertFalse(TestCakeSession::write(''));
  274. }
  275. /**
  276. * Test overwriting a string value as if it were an array.
  277. *
  278. * @return void
  279. */
  280. public function testWriteOverwriteStringValue() {
  281. TestCakeSession::write('Some.string', 'value');
  282. $this->assertEquals('value', TestCakeSession::read('Some.string'));
  283. TestCakeSession::write('Some.string.array', array('values'));
  284. $this->assertEquals(
  285. array('values'),
  286. TestCakeSession::read('Some.string.array')
  287. );
  288. }
  289. /**
  290. * testId method
  291. *
  292. * @return void
  293. */
  294. public function testId() {
  295. TestCakeSession::destroy();
  296. $result = TestCakeSession::id();
  297. $expected = session_id();
  298. $this->assertEquals($expected, $result);
  299. TestCakeSession::id('MySessionId');
  300. $result = TestCakeSession::id();
  301. $this->assertEquals('MySessionId', $result);
  302. }
  303. /**
  304. * testStarted method
  305. *
  306. * @return void
  307. */
  308. public function testStarted() {
  309. unset($_SESSION);
  310. $_SESSION = null;
  311. $this->assertFalse(TestCakeSession::started());
  312. $this->assertTrue(TestCakeSession::start());
  313. $this->assertTrue(TestCakeSession::started());
  314. }
  315. /**
  316. * testDel method
  317. *
  318. * @return void
  319. */
  320. public function testDelete() {
  321. $this->assertTrue(TestCakeSession::write('Delete.me', 'Clearing out'));
  322. $this->assertTrue(TestCakeSession::delete('Delete.me'));
  323. $this->assertFalse(TestCakeSession::check('Delete.me'));
  324. $this->assertTrue(TestCakeSession::check('Delete'));
  325. $this->assertTrue(TestCakeSession::write('Clearing.sale', 'everything must go'));
  326. $this->assertTrue(TestCakeSession::delete('Clearing'));
  327. $this->assertFalse(TestCakeSession::check('Clearing.sale'));
  328. $this->assertFalse(TestCakeSession::check('Clearing'));
  329. }
  330. /**
  331. * testDestroy method
  332. *
  333. * @return void
  334. */
  335. public function testDestroy() {
  336. TestCakeSession::write('bulletProof', 'invincible');
  337. $id = TestCakeSession::id();
  338. TestCakeSession::destroy();
  339. $this->assertFalse(TestCakeSession::check('bulletProof'));
  340. $this->assertNotEquals(TestCakeSession::id(), $id);
  341. }
  342. /**
  343. * testCheckingSavedEmpty method
  344. *
  345. * @return void
  346. */
  347. public function testCheckingSavedEmpty() {
  348. $this->assertTrue(TestCakeSession::write('SessionTestCase', 0));
  349. $this->assertTrue(TestCakeSession::check('SessionTestCase'));
  350. $this->assertTrue(TestCakeSession::write('SessionTestCase', '0'));
  351. $this->assertTrue(TestCakeSession::check('SessionTestCase'));
  352. $this->assertTrue(TestCakeSession::write('SessionTestCase', false));
  353. $this->assertTrue(TestCakeSession::check('SessionTestCase'));
  354. $this->assertTrue(TestCakeSession::write('SessionTestCase', null));
  355. $this->assertFalse(TestCakeSession::check('SessionTestCase'));
  356. }
  357. /**
  358. * testCheckKeyWithSpaces method
  359. *
  360. * @return void
  361. */
  362. public function testCheckKeyWithSpaces() {
  363. $this->assertTrue(TestCakeSession::write('Session Test', "test"));
  364. $this->assertTrue(TestCakeSession::check('Session Test'));
  365. TestCakeSession::delete('Session Test');
  366. $this->assertTrue(TestCakeSession::write('Session Test.Test Case', "test"));
  367. $this->assertTrue(TestCakeSession::check('Session Test.Test Case'));
  368. }
  369. /**
  370. * testCheckEmpty
  371. *
  372. * @return void
  373. */
  374. public function testCheckEmpty() {
  375. $this->assertFalse(TestCakeSession::check());
  376. }
  377. /**
  378. * test key exploitation
  379. *
  380. * @return void
  381. */
  382. public function testKeyExploit() {
  383. $key = "a'] = 1; phpinfo(); \$_SESSION['a";
  384. $result = TestCakeSession::write($key, 'haxored');
  385. $this->assertFalse($result);
  386. $result = TestCakeSession::read($key);
  387. $this->assertNull($result);
  388. }
  389. /**
  390. * testReadingSavedEmpty method
  391. *
  392. * @return void
  393. */
  394. public function testReadingSavedEmpty() {
  395. TestCakeSession::write('SessionTestCase', 0);
  396. $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
  397. TestCakeSession::write('SessionTestCase', '0');
  398. $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
  399. $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
  400. TestCakeSession::write('SessionTestCase', false);
  401. $this->assertFalse(TestCakeSession::read('SessionTestCase'));
  402. TestCakeSession::write('SessionTestCase', null);
  403. $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
  404. }
  405. /**
  406. * testCheckUserAgentFalse method
  407. *
  408. * @return void
  409. */
  410. public function testCheckUserAgentFalse() {
  411. Configure::write('Session.checkAgent', false);
  412. TestCakeSession::setUserAgent(md5('http://randomdomainname.com' . Configure::read('Security.salt')));
  413. $this->assertTrue(TestCakeSession::valid());
  414. }
  415. /**
  416. * testCheckUserAgentTrue method
  417. *
  418. * @return void
  419. */
  420. public function testCheckUserAgentTrue() {
  421. Configure::write('Session.checkAgent', true);
  422. TestCakeSession::$error = false;
  423. $agent = md5('http://randomdomainname.com' . Configure::read('Security.salt'));
  424. TestCakeSession::write('Config.userAgent', md5('Hacking you!'));
  425. TestCakeSession::setUserAgent($agent);
  426. $this->assertFalse(TestCakeSession::valid());
  427. }
  428. /**
  429. * testReadAndWriteWithCakeStorage method
  430. *
  431. * @return void
  432. */
  433. public function testReadAndWriteWithCakeStorage() {
  434. Configure::write('Session.defaults', 'cake');
  435. TestCakeSession::init();
  436. TestCakeSession::start();
  437. TestCakeSession::write('SessionTestCase', 0);
  438. $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
  439. TestCakeSession::write('SessionTestCase', '0');
  440. $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
  441. $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
  442. TestCakeSession::write('SessionTestCase', false);
  443. $this->assertFalse(TestCakeSession::read('SessionTestCase'));
  444. TestCakeSession::write('SessionTestCase', null);
  445. $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
  446. TestCakeSession::write('SessionTestCase', 'This is a Test');
  447. $this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
  448. TestCakeSession::write('SessionTestCase', 'This is a Test');
  449. TestCakeSession::write('SessionTestCase', 'This was updated');
  450. $this->assertEquals('This was updated', TestCakeSession::read('SessionTestCase'));
  451. TestCakeSession::destroy();
  452. $this->assertNull(TestCakeSession::read('SessionTestCase'));
  453. }
  454. /**
  455. * test using a handler from app/Model/Datasource/Session.
  456. *
  457. * @return void
  458. */
  459. public function testUsingAppLibsHandler() {
  460. Configure::write('App.namespace', 'TestApp');
  461. Configure::write('Session', array(
  462. 'defaults' => 'cake',
  463. 'handler' => array(
  464. 'engine' => 'TestAppLibSession'
  465. )
  466. ));
  467. TestCakeSession::start();
  468. $this->assertTrue(TestCakeSession::started());
  469. TestCakeSession::destroy();
  470. $this->assertFalse(TestCakeSession::started());
  471. }
  472. /**
  473. * test using a handler from a plugin.
  474. *
  475. * @return void
  476. */
  477. public function testUsingPluginHandler() {
  478. Plugin::load('TestPlugin');
  479. Configure::write('App.namespace', 'TestApp');
  480. Configure::write('Session', array(
  481. 'defaults' => 'cake',
  482. 'handler' => array(
  483. 'engine' => 'TestPlugin.TestPluginSession'
  484. )
  485. ));
  486. TestCakeSession::start();
  487. $this->assertTrue(TestCakeSession::started());
  488. TestCakeSession::destroy();
  489. $this->assertFalse(TestCakeSession::started());
  490. }
  491. /**
  492. * testReadAndWriteWithCacheStorage method
  493. *
  494. * @return void
  495. */
  496. public function testReadAndWriteWithCacheStorage() {
  497. Cache::config('default', [
  498. 'engine' => 'File',
  499. 'path' => TMP,
  500. 'prefix' => 'session_test_'
  501. ]);
  502. Configure::write('Session.defaults', 'cache');
  503. Configure::write('Session.handler.engine', __NAMESPACE__ . '\TestCacheSession');
  504. TestCakeSession::init();
  505. TestCakeSession::destroy();
  506. TestCakeSession::write('SessionTestCase', 0);
  507. $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
  508. TestCakeSession::write('SessionTestCase', '0');
  509. $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
  510. $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
  511. TestCakeSession::write('SessionTestCase', false);
  512. $this->assertFalse(TestCakeSession::read('SessionTestCase'));
  513. TestCakeSession::write('SessionTestCase', null);
  514. $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
  515. TestCakeSession::write('SessionTestCase', 'This is a Test');
  516. $this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
  517. TestCakeSession::write('SessionTestCase', 'This is a Test');
  518. TestCakeSession::write('SessionTestCase', 'This was updated');
  519. $this->assertEquals('This was updated', TestCakeSession::read('SessionTestCase'));
  520. TestCakeSession::destroy();
  521. $this->assertNull(TestCakeSession::read('SessionTestCase'));
  522. }
  523. /**
  524. * test that changing the config name of the cache config works.
  525. *
  526. * @return void
  527. */
  528. public function testReadAndWriteWithCustomCacheConfig() {
  529. Configure::write('Session.defaults', 'cache');
  530. Configure::write('Session.handler.engine', __NAMESPACE__ . '\TestCacheSession');
  531. Configure::write('Session.handler.config', 'session_test');
  532. Cache::config('session_test', [
  533. 'engine' => 'File',
  534. 'prefix' => 'session_test_'
  535. ]);
  536. TestCakeSession::init();
  537. TestCakeSession::start();
  538. TestCakeSession::write('SessionTestCase', 'Some value');
  539. $this->assertEquals('Some value', TestCakeSession::read('SessionTestCase'));
  540. $id = TestCakeSession::id();
  541. Cache::delete($id, 'session_test');
  542. }
  543. /**
  544. * testReadAndWriteWithDatabaseStorage method
  545. *
  546. * @return void
  547. */
  548. public function testReadAndWriteWithDatabaseStorage() {
  549. Configure::write('Session.defaults', 'database');
  550. Configure::write('Session.handler.engine', __NAMESPACE__ . '\TestDatabaseSession');
  551. TestCakeSession::init();
  552. $this->assertNull(TestCakeSession::id());
  553. TestCakeSession::start();
  554. $expected = session_id();
  555. $this->assertEquals($expected, TestCakeSession::id());
  556. TestCakeSession::renew();
  557. $this->assertFalse($expected === TestCakeSession::id());
  558. $expected = session_id();
  559. $this->assertEquals($expected, TestCakeSession::id());
  560. TestCakeSession::write('SessionTestCase', 0);
  561. $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
  562. TestCakeSession::write('SessionTestCase', '0');
  563. $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
  564. $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
  565. TestCakeSession::write('SessionTestCase', false);
  566. $this->assertFalse(TestCakeSession::read('SessionTestCase'));
  567. TestCakeSession::write('SessionTestCase', null);
  568. $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
  569. TestCakeSession::write('SessionTestCase', 'This is a Test');
  570. $this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
  571. TestCakeSession::write('SessionTestCase', 'Some additional data');
  572. $this->assertEquals('Some additional data', TestCakeSession::read('SessionTestCase'));
  573. TestCakeSession::destroy();
  574. $this->assertNull(TestCakeSession::read('SessionTestCase'));
  575. Configure::write('Session', array(
  576. 'defaults' => 'php'
  577. ));
  578. TestCakeSession::init();
  579. }
  580. /**
  581. * testSessionTimeout method
  582. *
  583. * @return void
  584. */
  585. public function testSessionTimeout() {
  586. Configure::write('debug', true);
  587. Configure::write('Session.defaults', 'cake');
  588. Configure::write('Session.autoRegenerate', false);
  589. $timeoutSeconds = Configure::read('Session.timeout') * 60;
  590. TestCakeSession::destroy();
  591. TestCakeSession::write('Test', 'some value');
  592. $this->assertWithinMargin(time() + $timeoutSeconds, Session::$sessionTime, 1);
  593. $this->assertEquals(10, $_SESSION['Config']['countdown']);
  594. $this->assertWithinMargin(Session::$sessionTime, $_SESSION['Config']['time'], 1);
  595. $this->assertWithinMargin(time(), Session::$time, 1);
  596. $this->assertWithinMargin(time() + $timeoutSeconds, $_SESSION['Config']['time'], 1);
  597. Configure::write('Session.harden', true);
  598. TestCakeSession::destroy();
  599. TestCakeSession::write('Test', 'some value');
  600. $this->assertWithinMargin(time() + $timeoutSeconds, Session::$sessionTime, 1);
  601. $this->assertEquals(10, $_SESSION['Config']['countdown']);
  602. $this->assertWithinMargin(Session::$sessionTime, $_SESSION['Config']['time'], 1);
  603. $this->assertWithinMargin(time(), Session::$time, 1);
  604. $this->assertWithinMargin(Session::$time + $timeoutSeconds, $_SESSION['Config']['time'], 1);
  605. }
  606. /**
  607. * Test that cookieTimeout matches timeout when unspecified.
  608. *
  609. * @return void
  610. */
  611. public function testCookieTimeoutFallback() {
  612. $_SESSION = null;
  613. Configure::write('Session', array(
  614. 'defaults' => 'cake',
  615. 'timeout' => 400,
  616. ));
  617. TestCakeSession::start();
  618. $this->assertEquals(400, Configure::read('Session.cookieTimeout'));
  619. $this->assertEquals(400, Configure::read('Session.timeout'));
  620. $this->assertEquals(400 * 60, ini_get('session.cookie_lifetime'));
  621. $this->assertEquals(400 * 60, ini_get('session.gc_maxlifetime'));
  622. $_SESSION = null;
  623. Configure::write('Session', array(
  624. 'defaults' => 'cake',
  625. 'timeout' => 400,
  626. 'cookieTimeout' => 600
  627. ));
  628. TestCakeSession::start();
  629. $this->assertEquals(600, Configure::read('Session.cookieTimeout'));
  630. $this->assertEquals(400, Configure::read('Session.timeout'));
  631. }
  632. /**
  633. * Proves that invalid sessions will be destroyed and re-created
  634. * if invalid
  635. *
  636. * @return void
  637. */
  638. public function testInvalidSessionRenew() {
  639. TestCakeSession::start();
  640. $this->assertNotEmpty($_SESSION['Config']);
  641. $data = $_SESSION;
  642. session_write_close();
  643. $_SESSION = null;
  644. TestCakeSession::start();
  645. $this->assertEquals($data, $_SESSION);
  646. TestCakeSession::write('Foo', 'Bar');
  647. session_write_close();
  648. $_SESSION = null;
  649. TestCakeSession::userAgent('bogus!');
  650. TestCakeSession::start();
  651. $this->assertNotEquals($data, $_SESSION);
  652. }
  653. }