PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/tests/session_manager_test.php

https://bitbucket.org/synergylearning/campusconnect
PHP | 480 lines | 338 code | 99 blank | 43 comment | 1 complexity | ab28f0594ba1bf021b26b69ef2d57239 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, Apache-2.0, BSD-3-Clause, AGPL-3.0
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Unit tests for session manager class.
  18. *
  19. * @package core
  20. * @category phpunit
  21. * @copyright 2013 Petr Skoda {@link http://skodak.org}
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. defined('MOODLE_INTERNAL') || die();
  25. /**
  26. * Unit tests for session manager class.
  27. *
  28. * @package core
  29. * @category phpunit
  30. * @copyright 2013 Petr Skoda {@link http://skodak.org}
  31. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32. */
  33. class core_session_manager_testcase extends advanced_testcase {
  34. public function test_start() {
  35. $this->resetAfterTest();
  36. // Session must be started only once...
  37. \core\session\manager::start();
  38. $this->assertDebuggingCalled('Session was already started!', DEBUG_DEVELOPER);
  39. }
  40. public function test_init_empty_session() {
  41. global $SESSION, $USER;
  42. $this->resetAfterTest();
  43. $user = $this->getDataGenerator()->create_user();
  44. $SESSION->test = true;
  45. $this->assertTrue($GLOBALS['SESSION']->test);
  46. $this->assertTrue($_SESSION['SESSION']->test);
  47. \core\session\manager::set_user($user);
  48. $this->assertSame($user, $USER);
  49. $this->assertSame($user, $GLOBALS['USER']);
  50. $this->assertSame($user, $_SESSION['USER']);
  51. \core\session\manager::init_empty_session();
  52. $this->assertInstanceOf('stdClass', $SESSION);
  53. $this->assertEmpty((array)$SESSION);
  54. $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  55. $this->assertSame($GLOBALS['SESSION'], $SESSION);
  56. $this->assertInstanceOf('stdClass', $USER);
  57. $this->assertEquals(array('id' => 0, 'mnethostid' => 1), (array)$USER, '', 0, 10, true);
  58. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  59. $this->assertSame($GLOBALS['USER'], $USER);
  60. // Now test how references work.
  61. $GLOBALS['SESSION'] = new \stdClass();
  62. $GLOBALS['SESSION']->test = true;
  63. $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  64. $this->assertSame($GLOBALS['SESSION'], $SESSION);
  65. $SESSION = new \stdClass();
  66. $SESSION->test2 = true;
  67. $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  68. $this->assertSame($GLOBALS['SESSION'], $SESSION);
  69. $_SESSION['SESSION'] = new stdClass();
  70. $_SESSION['SESSION']->test3 = true;
  71. $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  72. $this->assertSame($GLOBALS['SESSION'], $SESSION);
  73. $GLOBALS['USER'] = new \stdClass();
  74. $GLOBALS['USER']->test = true;
  75. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  76. $this->assertSame($GLOBALS['USER'], $USER);
  77. $USER = new \stdClass();
  78. $USER->test2 = true;
  79. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  80. $this->assertSame($GLOBALS['USER'], $USER);
  81. $_SESSION['USER'] = new stdClass();
  82. $_SESSION['USER']->test3 = true;
  83. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  84. $this->assertSame($GLOBALS['USER'], $USER);
  85. }
  86. public function test_set_user() {
  87. global $USER;
  88. $this->resetAfterTest();
  89. $this->assertEquals(0, $USER->id);
  90. $user = $this->getDataGenerator()->create_user();
  91. $this->assertObjectHasAttribute('description', $user);
  92. $this->assertObjectHasAttribute('password', $user);
  93. \core\session\manager::set_user($user);
  94. $this->assertEquals($user->id, $USER->id);
  95. $this->assertObjectNotHasAttribute('description', $user);
  96. $this->assertObjectNotHasAttribute('password', $user);
  97. $this->assertObjectHasAttribute('sesskey', $user);
  98. $this->assertSame($user, $GLOBALS['USER']);
  99. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  100. $this->assertSame($GLOBALS['USER'], $USER);
  101. }
  102. public function test_login_user() {
  103. global $USER;
  104. $this->resetAfterTest();
  105. $this->assertEquals(0, $USER->id);
  106. $user = $this->getDataGenerator()->create_user();
  107. @\core\session\manager::login_user($user); // Ignore header error messages.
  108. $this->assertEquals($user->id, $USER->id);
  109. $this->assertObjectNotHasAttribute('description', $user);
  110. $this->assertObjectNotHasAttribute('password', $user);
  111. $this->assertSame($user, $GLOBALS['USER']);
  112. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  113. $this->assertSame($GLOBALS['USER'], $USER);
  114. }
  115. public function test_terminate_current() {
  116. global $USER, $SESSION;
  117. $this->resetAfterTest();
  118. $this->setAdminUser();
  119. \core\session\manager::terminate_current();
  120. $this->assertEquals(0, $USER->id);
  121. $this->assertInstanceOf('stdClass', $SESSION);
  122. $this->assertEmpty((array)$SESSION);
  123. $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  124. $this->assertSame($GLOBALS['SESSION'], $SESSION);
  125. $this->assertInstanceOf('stdClass', $USER);
  126. $this->assertEquals(array('id' => 0, 'mnethostid' => 1), (array)$USER, '', 0, 10, true);
  127. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  128. $this->assertSame($GLOBALS['USER'], $USER);
  129. }
  130. public function test_write_close() {
  131. global $USER;
  132. $this->resetAfterTest();
  133. // Just make sure no errors and $USER->id is kept
  134. $this->setAdminUser();
  135. $userid = $USER->id;
  136. \core\session\manager::write_close();
  137. $this->assertSame($userid, $USER->id);
  138. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  139. $this->assertSame($GLOBALS['USER'], $USER);
  140. }
  141. public function test_session_exists() {
  142. global $CFG;
  143. $this->resetAfterTest();
  144. // The file handler is used by default, so let's fake the data somehow.
  145. $sid = md5('hokus');
  146. mkdir("$CFG->dataroot/sessions/", $CFG->directorypermissions, true);
  147. touch("$CFG->dataroot/sessions/sess_$sid");
  148. $this->assertTrue(\core\session\manager::session_exists($sid));
  149. }
  150. public function test_touch_session() {
  151. global $DB;
  152. $this->resetAfterTest();
  153. $sid = md5('hokus');
  154. $record = new \stdClass();
  155. $record->state = 0;
  156. $record->sid = $sid;
  157. $record->sessdata = null;
  158. $record->userid = 2;
  159. $record->timecreated = time() - 60*60;
  160. $record->timemodified = time() - 30;
  161. $record->firstip = $record->lastip = '10.0.0.1';
  162. $record->id = $DB->insert_record('sessions', $record);
  163. $now = time();
  164. \core\session\manager::touch_session($sid);
  165. $updated = $DB->get_field('sessions', 'timemodified', array('id'=>$record->id));
  166. $this->assertGreaterThanOrEqual($now, $updated);
  167. $this->assertLessThanOrEqual(time(), $updated);
  168. }
  169. public function test_kill_session() {
  170. global $DB, $USER;
  171. $this->resetAfterTest();
  172. $this->setAdminUser();
  173. $userid = $USER->id;
  174. $sid = md5('hokus');
  175. $record = new \stdClass();
  176. $record->state = 0;
  177. $record->sid = $sid;
  178. $record->sessdata = null;
  179. $record->userid = $userid;
  180. $record->timecreated = time() - 60*60;
  181. $record->timemodified = time() - 30;
  182. $record->firstip = $record->lastip = '10.0.0.1';
  183. $DB->insert_record('sessions', $record);
  184. $record->userid = 0;
  185. $record->sid = md5('pokus');
  186. $DB->insert_record('sessions', $record);
  187. $this->assertEquals(2, $DB->count_records('sessions'));
  188. \core\session\manager::kill_session($sid);
  189. $this->assertEquals(1, $DB->count_records('sessions'));
  190. $this->assertFalse($DB->record_exists('sessions', array('sid'=>$sid)));
  191. $this->assertSame($userid, $USER->id);
  192. }
  193. public function test_kill_user_sessions() {
  194. global $DB, $USER;
  195. $this->resetAfterTest();
  196. $this->setAdminUser();
  197. $userid = $USER->id;
  198. $sid = md5('hokus');
  199. $record = new \stdClass();
  200. $record->state = 0;
  201. $record->sid = $sid;
  202. $record->sessdata = null;
  203. $record->userid = $userid;
  204. $record->timecreated = time() - 60*60;
  205. $record->timemodified = time() - 30;
  206. $record->firstip = $record->lastip = '10.0.0.1';
  207. $DB->insert_record('sessions', $record);
  208. $record->sid = md5('hokus2');
  209. $DB->insert_record('sessions', $record);
  210. $record->userid = 0;
  211. $record->sid = md5('pokus');
  212. $DB->insert_record('sessions', $record);
  213. $this->assertEquals(3, $DB->count_records('sessions'));
  214. \core\session\manager::kill_user_sessions($userid);
  215. $this->assertEquals(1, $DB->count_records('sessions'));
  216. $this->assertFalse($DB->record_exists('sessions', array('userid'=>$userid)));
  217. }
  218. public function test_kill_all_sessions() {
  219. global $DB, $USER;
  220. $this->resetAfterTest();
  221. $this->setAdminUser();
  222. $userid = $USER->id;
  223. $sid = md5('hokus');
  224. $record = new \stdClass();
  225. $record->state = 0;
  226. $record->sid = $sid;
  227. $record->sessdata = null;
  228. $record->userid = $userid;
  229. $record->timecreated = time() - 60*60;
  230. $record->timemodified = time() - 30;
  231. $record->firstip = $record->lastip = '10.0.0.1';
  232. $DB->insert_record('sessions', $record);
  233. $record->sid = md5('hokus2');
  234. $DB->insert_record('sessions', $record);
  235. $record->userid = 0;
  236. $record->sid = md5('pokus');
  237. $DB->insert_record('sessions', $record);
  238. $this->assertEquals(3, $DB->count_records('sessions'));
  239. \core\session\manager::kill_all_sessions();
  240. $this->assertEquals(0, $DB->count_records('sessions'));
  241. $this->assertSame(0, $USER->id);
  242. }
  243. public function test_gc() {
  244. global $CFG, $DB, $USER;
  245. $this->resetAfterTest();
  246. $this->setAdminUser();
  247. $adminid = $USER->id;
  248. $this->setGuestUser();
  249. $guestid = $USER->id;
  250. $this->setUser(0);
  251. $CFG->sessiontimeout = 60*10;
  252. $record = new \stdClass();
  253. $record->state = 0;
  254. $record->sid = md5('hokus1');
  255. $record->sessdata = null;
  256. $record->userid = $adminid;
  257. $record->timecreated = time() - 60*60;
  258. $record->timemodified = time() - 30;
  259. $record->firstip = $record->lastip = '10.0.0.1';
  260. $r1 = $DB->insert_record('sessions', $record);
  261. $record->sid = md5('hokus2');
  262. $record->userid = $adminid;
  263. $record->timecreated = time() - 60*60;
  264. $record->timemodified = time() - 60*20;
  265. $r2 = $DB->insert_record('sessions', $record);
  266. $record->sid = md5('hokus3');
  267. $record->userid = $guestid;
  268. $record->timecreated = time() - 60*60*60;
  269. $record->timemodified = time() - 60*20;
  270. $r3 = $DB->insert_record('sessions', $record);
  271. $record->sid = md5('hokus4');
  272. $record->userid = $guestid;
  273. $record->timecreated = time() - 60*60*60;
  274. $record->timemodified = time() - 60*10*5 - 60;
  275. $r4 = $DB->insert_record('sessions', $record);
  276. $record->sid = md5('hokus5');
  277. $record->userid = 0;
  278. $record->timecreated = time() - 60*5;
  279. $record->timemodified = time() - 60*5;
  280. $r5 = $DB->insert_record('sessions', $record);
  281. $record->sid = md5('hokus6');
  282. $record->userid = 0;
  283. $record->timecreated = time() - 60*60;
  284. $record->timemodified = time() - 60*10 -10;
  285. $r6 = $DB->insert_record('sessions', $record);
  286. $record->sid = md5('hokus7');
  287. $record->userid = 0;
  288. $record->timecreated = time() - 60*60;
  289. $record->timemodified = time() - 60*9;
  290. $r7 = $DB->insert_record('sessions', $record);
  291. \core\session\manager::gc();
  292. $this->assertTrue($DB->record_exists('sessions', array('id'=>$r1)));
  293. $this->assertFalse($DB->record_exists('sessions', array('id'=>$r2)));
  294. $this->assertTrue($DB->record_exists('sessions', array('id'=>$r3)));
  295. $this->assertFalse($DB->record_exists('sessions', array('id'=>$r4)));
  296. $this->assertFalse($DB->record_exists('sessions', array('id'=>$r5)));
  297. $this->assertFalse($DB->record_exists('sessions', array('id'=>$r6)));
  298. $this->assertTrue($DB->record_exists('sessions', array('id'=>$r7)));
  299. }
  300. /**
  301. * Test loginas.
  302. * @copyright 2103 Rajesh Taneja <rajesh@moodle.com>
  303. */
  304. public function test_loginas() {
  305. global $USER, $SESSION;
  306. $this->resetAfterTest();
  307. // Set current user as Admin user and save it for later use.
  308. $this->setAdminUser();
  309. $adminuser = $USER;
  310. $adminsession = $SESSION;
  311. $user = $this->getDataGenerator()->create_user();
  312. $_SESSION['extra'] = true;
  313. // Try admin loginas this user in system context.
  314. $this->assertObjectNotHasAttribute('realuser', $USER);
  315. \core\session\manager::loginas($user->id, context_system::instance());
  316. $this->assertSame($user->id, $USER->id);
  317. $this->assertSame(context_system::instance(), $USER->loginascontext);
  318. $this->assertSame($adminuser->id, $USER->realuser);
  319. $this->assertSame($GLOBALS['USER'], $_SESSION['USER']);
  320. $this->assertSame($GLOBALS['USER'], $USER);
  321. $this->assertNotSame($adminuser, $_SESSION['REALUSER']);
  322. $this->assertEquals($adminuser, $_SESSION['REALUSER']);
  323. $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']);
  324. $this->assertSame($GLOBALS['SESSION'], $SESSION);
  325. $this->assertNotSame($adminsession, $_SESSION['REALSESSION']);
  326. $this->assertEquals($adminsession, $_SESSION['REALSESSION']);
  327. $this->assertArrayNotHasKey('extra', $_SESSION);
  328. // Set user as current user and login as admin user in course context.
  329. \core\session\manager::init_empty_session();
  330. $this->setUser($user);
  331. $this->assertNotEquals($adminuser->id, $USER->id);
  332. $course = $this->getDataGenerator()->create_course();
  333. $coursecontext = context_course::instance($course->id);
  334. // Catch event triggered.
  335. $sink = $this->redirectEvents();
  336. \core\session\manager::loginas($adminuser->id, $coursecontext);
  337. $events = $sink->get_events();
  338. $sink->close();
  339. $event = array_pop($events);
  340. $this->assertSame($adminuser->id, $USER->id);
  341. $this->assertSame($coursecontext, $USER->loginascontext);
  342. $this->assertSame($user->id, $USER->realuser);
  343. // Test event captured has proper information.
  344. $this->assertInstanceOf('\core\event\user_loggedinas', $event);
  345. $this->assertSame($user->id, $event->objectid);
  346. $this->assertSame($adminuser->id, $event->relateduserid);
  347. $this->assertSame($course->id, $event->courseid);
  348. $this->assertEquals($coursecontext, $event->get_context());
  349. $oldfullname = fullname($user, true);
  350. $newfullname = fullname($adminuser, true);
  351. $expectedlogdata = array($course->id, "course", "loginas", "../user/view.php?id=$course->id&amp;user=$user->id", "$oldfullname -> $newfullname");
  352. $this->assertEventLegacyLogData($expectedlogdata, $event);
  353. }
  354. public function test_is_loggedinas() {
  355. $this->resetAfterTest();
  356. $user1 = $this->getDataGenerator()->create_user();
  357. $user2 = $this->getDataGenerator()->create_user();
  358. $this->assertFalse(\core\session\manager::is_loggedinas());
  359. $this->setUser($user1);
  360. \core\session\manager::loginas($user2->id, context_system::instance());
  361. $this->assertTrue(\core\session\manager::is_loggedinas());
  362. }
  363. public function test_get_realuser() {
  364. $this->resetAfterTest();
  365. $user1 = $this->getDataGenerator()->create_user();
  366. $user2 = $this->getDataGenerator()->create_user();
  367. $this->setUser($user1);
  368. $normal = \core\session\manager::get_realuser();
  369. $this->assertSame($GLOBALS['USER'], $normal);
  370. \core\session\manager::loginas($user2->id, context_system::instance());
  371. $real = \core\session\manager::get_realuser();
  372. unset($real->password);
  373. unset($real->description);
  374. unset($real->sesskey);
  375. unset($user1->password);
  376. unset($user1->description);
  377. unset($user1->sesskey);
  378. $this->assertEquals($real, $user1);
  379. $this->assertSame($_SESSION['REALUSER'], $real);
  380. }
  381. }