SessionTest.php 20 KB

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