Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
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 /** 18 * Unit tests for session manager class. 19 * 20 * @package core 21 * @category phpunit 22 * @copyright 2013 Petr Skoda {@link http://skodak.org} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** 29 * Unit tests for session manager class. 30 * 31 * @package core 32 * @category phpunit 33 * @copyright 2013 Petr Skoda {@link http://skodak.org} 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class core_session_manager_testcase extends advanced_testcase { 37 public function test_start() { 38 $this->resetAfterTest(); 39 // Session must be started only once... 40 \core\session\manager::start(); 41 $this->assertDebuggingCalled('Session was already started!', DEBUG_DEVELOPER); 42 } 43 44 public function test_init_empty_session() { 45 global $SESSION, $USER; 46 $this->resetAfterTest(); 47 48 $user = $this->getDataGenerator()->create_user(); 49 50 $SESSION->test = true; 51 $this->assertTrue($GLOBALS['SESSION']->test); 52 $this->assertTrue($_SESSION['SESSION']->test); 53 54 \core\session\manager::set_user($user); 55 $this->assertSame($user, $USER); 56 $this->assertSame($user, $GLOBALS['USER']); 57 $this->assertSame($user, $_SESSION['USER']); 58 59 \core\session\manager::init_empty_session(); 60 61 $this->assertInstanceOf('stdClass', $SESSION); 62 $this->assertEmpty((array)$SESSION); 63 $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']); 64 $this->assertSame($GLOBALS['SESSION'], $SESSION); 65 66 $this->assertInstanceOf('stdClass', $USER); 67 $this->assertEqualsCanonicalizing(array('id' => 0, 'mnethostid' => 1), (array)$USER); 68 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 69 $this->assertSame($GLOBALS['USER'], $USER); 70 71 // Now test how references work. 72 73 $GLOBALS['SESSION'] = new \stdClass(); 74 $GLOBALS['SESSION']->test = true; 75 $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']); 76 $this->assertSame($GLOBALS['SESSION'], $SESSION); 77 78 $SESSION = new \stdClass(); 79 $SESSION->test2 = true; 80 $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']); 81 $this->assertSame($GLOBALS['SESSION'], $SESSION); 82 83 $_SESSION['SESSION'] = new stdClass(); 84 $_SESSION['SESSION']->test3 = true; 85 $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']); 86 $this->assertSame($GLOBALS['SESSION'], $SESSION); 87 88 $GLOBALS['USER'] = new \stdClass(); 89 $GLOBALS['USER']->test = true; 90 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 91 $this->assertSame($GLOBALS['USER'], $USER); 92 93 $USER = new \stdClass(); 94 $USER->test2 = true; 95 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 96 $this->assertSame($GLOBALS['USER'], $USER); 97 98 $_SESSION['USER'] = new stdClass(); 99 $_SESSION['USER']->test3 = true; 100 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 101 $this->assertSame($GLOBALS['USER'], $USER); 102 } 103 104 public function test_set_user() { 105 global $USER; 106 $this->resetAfterTest(); 107 108 $this->assertEquals(0, $USER->id); 109 110 $user = $this->getDataGenerator()->create_user(); 111 $this->assertObjectHasAttribute('description', $user); 112 $this->assertObjectHasAttribute('password', $user); 113 114 \core\session\manager::set_user($user); 115 116 $this->assertEquals($user->id, $USER->id); 117 $this->assertObjectNotHasAttribute('description', $user); 118 $this->assertObjectNotHasAttribute('password', $user); 119 $this->assertObjectHasAttribute('sesskey', $user); 120 $this->assertSame($user, $GLOBALS['USER']); 121 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 122 $this->assertSame($GLOBALS['USER'], $USER); 123 } 124 125 public function test_login_user() { 126 global $USER; 127 $this->resetAfterTest(); 128 129 $this->assertEquals(0, $USER->id); 130 131 $user = $this->getDataGenerator()->create_user(); 132 133 @\core\session\manager::login_user($user); // Ignore header error messages. 134 $this->assertEquals($user->id, $USER->id); 135 136 $this->assertObjectNotHasAttribute('description', $user); 137 $this->assertObjectNotHasAttribute('password', $user); 138 $this->assertSame($user, $GLOBALS['USER']); 139 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 140 $this->assertSame($GLOBALS['USER'], $USER); 141 } 142 143 public function test_terminate_current() { 144 global $USER, $SESSION; 145 $this->resetAfterTest(); 146 147 $this->setAdminUser(); 148 \core\session\manager::terminate_current(); 149 $this->assertEquals(0, $USER->id); 150 151 $this->assertInstanceOf('stdClass', $SESSION); 152 $this->assertEmpty((array)$SESSION); 153 $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']); 154 $this->assertSame($GLOBALS['SESSION'], $SESSION); 155 156 $this->assertInstanceOf('stdClass', $USER); 157 $this->assertEqualsCanonicalizing(array('id' => 0, 'mnethostid' => 1), (array)$USER); 158 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 159 $this->assertSame($GLOBALS['USER'], $USER); 160 } 161 162 public function test_write_close() { 163 global $USER; 164 $this->resetAfterTest(); 165 166 // Just make sure no errors and $USER->id is kept 167 $this->setAdminUser(); 168 $userid = $USER->id; 169 \core\session\manager::write_close(); 170 $this->assertSame($userid, $USER->id); 171 172 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 173 $this->assertSame($GLOBALS['USER'], $USER); 174 } 175 176 public function test_session_exists() { 177 global $CFG, $DB; 178 $this->resetAfterTest(); 179 180 $this->assertFalse(\core\session\manager::session_exists('abc')); 181 182 $user = $this->getDataGenerator()->create_user(); 183 $guest = guest_user(); 184 185 // The file handler is used by default, so let's fake the data somehow. 186 $sid = md5('hokus'); 187 mkdir("$CFG->dataroot/sessions/", $CFG->directorypermissions, true); 188 touch("$CFG->dataroot/sessions/sess_$sid"); 189 190 $this->assertFalse(\core\session\manager::session_exists($sid)); 191 192 $record = new stdClass(); 193 $record->userid = 0; 194 $record->sid = $sid; 195 $record->timecreated = time(); 196 $record->timemodified = $record->timecreated; 197 $record->id = $DB->insert_record('sessions', $record); 198 199 $this->assertTrue(\core\session\manager::session_exists($sid)); 200 201 $record->timecreated = time() - $CFG->sessiontimeout - 100; 202 $record->timemodified = $record->timecreated + 10; 203 $DB->update_record('sessions', $record); 204 205 $this->assertTrue(\core\session\manager::session_exists($sid)); 206 207 $record->userid = $guest->id; 208 $DB->update_record('sessions', $record); 209 210 $this->assertTrue(\core\session\manager::session_exists($sid)); 211 212 $record->userid = $user->id; 213 $DB->update_record('sessions', $record); 214 215 $this->assertFalse(\core\session\manager::session_exists($sid)); 216 217 $CFG->sessiontimeout = $CFG->sessiontimeout + 3000; 218 219 $this->assertTrue(\core\session\manager::session_exists($sid)); 220 } 221 222 public function test_touch_session() { 223 global $DB; 224 $this->resetAfterTest(); 225 226 $sid = md5('hokus'); 227 $record = new \stdClass(); 228 $record->state = 0; 229 $record->sid = $sid; 230 $record->sessdata = null; 231 $record->userid = 2; 232 $record->timecreated = time() - 60*60; 233 $record->timemodified = time() - 30; 234 $record->firstip = $record->lastip = '10.0.0.1'; 235 $record->id = $DB->insert_record('sessions', $record); 236 237 $now = time(); 238 \core\session\manager::touch_session($sid); 239 $updated = $DB->get_field('sessions', 'timemodified', array('id'=>$record->id)); 240 241 $this->assertGreaterThanOrEqual($now, $updated); 242 $this->assertLessThanOrEqual(time(), $updated); 243 } 244 245 public function test_kill_session() { 246 global $DB, $USER; 247 $this->resetAfterTest(); 248 249 $this->setAdminUser(); 250 $userid = $USER->id; 251 252 $sid = md5('hokus'); 253 $record = new \stdClass(); 254 $record->state = 0; 255 $record->sid = $sid; 256 $record->sessdata = null; 257 $record->userid = $userid; 258 $record->timecreated = time() - 60*60; 259 $record->timemodified = time() - 30; 260 $record->firstip = $record->lastip = '10.0.0.1'; 261 $DB->insert_record('sessions', $record); 262 263 $record->userid = 0; 264 $record->sid = md5('pokus'); 265 $DB->insert_record('sessions', $record); 266 267 $this->assertEquals(2, $DB->count_records('sessions')); 268 269 \core\session\manager::kill_session($sid); 270 271 $this->assertEquals(1, $DB->count_records('sessions')); 272 $this->assertFalse($DB->record_exists('sessions', array('sid'=>$sid))); 273 274 $this->assertSame($userid, $USER->id); 275 } 276 277 public function test_kill_user_sessions() { 278 global $DB, $USER; 279 $this->resetAfterTest(); 280 281 $this->setAdminUser(); 282 $userid = $USER->id; 283 284 $sid = md5('hokus'); 285 $record = new \stdClass(); 286 $record->state = 0; 287 $record->sid = $sid; 288 $record->sessdata = null; 289 $record->userid = $userid; 290 $record->timecreated = time() - 60*60; 291 $record->timemodified = time() - 30; 292 $record->firstip = $record->lastip = '10.0.0.1'; 293 $DB->insert_record('sessions', $record); 294 295 $record->sid = md5('hokus2'); 296 $DB->insert_record('sessions', $record); 297 298 $record->userid = 0; 299 $record->sid = md5('pokus'); 300 $DB->insert_record('sessions', $record); 301 302 $this->assertEquals(3, $DB->count_records('sessions')); 303 304 \core\session\manager::kill_user_sessions($userid); 305 306 $this->assertEquals(1, $DB->count_records('sessions')); 307 $this->assertFalse($DB->record_exists('sessions', array('userid' => $userid))); 308 309 $record->userid = $userid; 310 $record->sid = md5('pokus3'); 311 $DB->insert_record('sessions', $record); 312 313 $record->userid = $userid; 314 $record->sid = md5('pokus4'); 315 $DB->insert_record('sessions', $record); 316 317 $record->userid = $userid; 318 $record->sid = md5('pokus5'); 319 $DB->insert_record('sessions', $record); 320 321 $this->assertEquals(3, $DB->count_records('sessions', array('userid' => $userid))); 322 323 \core\session\manager::kill_user_sessions($userid, md5('pokus5')); 324 325 $this->assertEquals(1, $DB->count_records('sessions', array('userid' => $userid))); 326 $this->assertEquals(1, $DB->count_records('sessions', array('userid' => $userid, 'sid' => md5('pokus5')))); 327 } 328 329 public function test_apply_concurrent_login_limit() { 330 global $DB; 331 $this->resetAfterTest(); 332 333 $user1 = $this->getDataGenerator()->create_user(); 334 $user2 = $this->getDataGenerator()->create_user(); 335 $guest = guest_user(); 336 337 $record = new \stdClass(); 338 $record->state = 0; 339 $record->sessdata = null; 340 $record->userid = $user1->id; 341 $record->timemodified = time(); 342 $record->firstip = $record->lastip = '10.0.0.1'; 343 344 $record->sid = md5('hokus1'); 345 $record->timecreated = 20; 346 $DB->insert_record('sessions', $record); 347 $record->sid = md5('hokus2'); 348 $record->timecreated = 10; 349 $DB->insert_record('sessions', $record); 350 $record->sid = md5('hokus3'); 351 $record->timecreated = 30; 352 $DB->insert_record('sessions', $record); 353 354 $record->userid = $user2->id; 355 $record->sid = md5('pokus1'); 356 $record->timecreated = 20; 357 $DB->insert_record('sessions', $record); 358 $record->sid = md5('pokus2'); 359 $record->timecreated = 10; 360 $DB->insert_record('sessions', $record); 361 $record->sid = md5('pokus3'); 362 $record->timecreated = 30; 363 $DB->insert_record('sessions', $record); 364 365 $record->timecreated = 10; 366 $record->userid = $guest->id; 367 $record->sid = md5('g1'); 368 $DB->insert_record('sessions', $record); 369 $record->sid = md5('g2'); 370 $DB->insert_record('sessions', $record); 371 $record->sid = md5('g3'); 372 $DB->insert_record('sessions', $record); 373 374 $record->userid = 0; 375 $record->sid = md5('nl1'); 376 $DB->insert_record('sessions', $record); 377 $record->sid = md5('nl2'); 378 $DB->insert_record('sessions', $record); 379 $record->sid = md5('nl3'); 380 $DB->insert_record('sessions', $record); 381 382 set_config('limitconcurrentlogins', 0); 383 $this->assertCount(12, $DB->get_records('sessions')); 384 385 \core\session\manager::apply_concurrent_login_limit($user1->id); 386 \core\session\manager::apply_concurrent_login_limit($user2->id); 387 \core\session\manager::apply_concurrent_login_limit($guest->id); 388 \core\session\manager::apply_concurrent_login_limit(0); 389 $this->assertCount(12, $DB->get_records('sessions')); 390 391 set_config('limitconcurrentlogins', -1); 392 393 \core\session\manager::apply_concurrent_login_limit($user1->id); 394 \core\session\manager::apply_concurrent_login_limit($user2->id); 395 \core\session\manager::apply_concurrent_login_limit($guest->id); 396 \core\session\manager::apply_concurrent_login_limit(0); 397 $this->assertCount(12, $DB->get_records('sessions')); 398 399 set_config('limitconcurrentlogins', 2); 400 401 \core\session\manager::apply_concurrent_login_limit($user1->id); 402 $this->assertCount(11, $DB->get_records('sessions')); 403 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20))); 404 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30))); 405 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10))); 406 407 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20))); 408 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30))); 409 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10))); 410 set_config('limitconcurrentlogins', 2); 411 \core\session\manager::apply_concurrent_login_limit($user2->id, md5('pokus2')); 412 $this->assertCount(10, $DB->get_records('sessions')); 413 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20))); 414 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30))); 415 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10))); 416 417 \core\session\manager::apply_concurrent_login_limit($guest->id); 418 \core\session\manager::apply_concurrent_login_limit(0); 419 $this->assertCount(10, $DB->get_records('sessions')); 420 421 set_config('limitconcurrentlogins', 1); 422 423 \core\session\manager::apply_concurrent_login_limit($user1->id, md5('grrr')); 424 $this->assertCount(9, $DB->get_records('sessions')); 425 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20))); 426 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30))); 427 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10))); 428 429 \core\session\manager::apply_concurrent_login_limit($user1->id); 430 $this->assertCount(9, $DB->get_records('sessions')); 431 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20))); 432 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30))); 433 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10))); 434 435 \core\session\manager::apply_concurrent_login_limit($user2->id, md5('pokus2')); 436 $this->assertCount(8, $DB->get_records('sessions')); 437 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20))); 438 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30))); 439 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10))); 440 441 \core\session\manager::apply_concurrent_login_limit($user2->id); 442 $this->assertCount(8, $DB->get_records('sessions')); 443 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20))); 444 $this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30))); 445 $this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10))); 446 447 \core\session\manager::apply_concurrent_login_limit($guest->id); 448 \core\session\manager::apply_concurrent_login_limit(0); 449 $this->assertCount(8, $DB->get_records('sessions')); 450 } 451 452 public function test_kill_all_sessions() { 453 global $DB, $USER; 454 $this->resetAfterTest(); 455 456 $this->setAdminUser(); 457 $userid = $USER->id; 458 459 $sid = md5('hokus'); 460 $record = new \stdClass(); 461 $record->state = 0; 462 $record->sid = $sid; 463 $record->sessdata = null; 464 $record->userid = $userid; 465 $record->timecreated = time() - 60*60; 466 $record->timemodified = time() - 30; 467 $record->firstip = $record->lastip = '10.0.0.1'; 468 $DB->insert_record('sessions', $record); 469 470 $record->sid = md5('hokus2'); 471 $DB->insert_record('sessions', $record); 472 473 $record->userid = 0; 474 $record->sid = md5('pokus'); 475 $DB->insert_record('sessions', $record); 476 477 $this->assertEquals(3, $DB->count_records('sessions')); 478 479 \core\session\manager::kill_all_sessions(); 480 481 $this->assertEquals(0, $DB->count_records('sessions')); 482 $this->assertSame(0, $USER->id); 483 } 484 485 public function test_gc() { 486 global $CFG, $DB, $USER; 487 $this->resetAfterTest(); 488 489 $this->setAdminUser(); 490 $adminid = $USER->id; 491 $this->setGuestUser(); 492 $guestid = $USER->id; 493 $this->setUser(0); 494 495 $CFG->sessiontimeout = 60*10; 496 497 $record = new \stdClass(); 498 $record->state = 0; 499 $record->sid = md5('hokus1'); 500 $record->sessdata = null; 501 $record->userid = $adminid; 502 $record->timecreated = time() - 60*60; 503 $record->timemodified = time() - 30; 504 $record->firstip = $record->lastip = '10.0.0.1'; 505 $r1 = $DB->insert_record('sessions', $record); 506 507 $record->sid = md5('hokus2'); 508 $record->userid = $adminid; 509 $record->timecreated = time() - 60*60; 510 $record->timemodified = time() - 60*20; 511 $r2 = $DB->insert_record('sessions', $record); 512 513 $record->sid = md5('hokus3'); 514 $record->userid = $guestid; 515 $record->timecreated = time() - 60*60*60; 516 $record->timemodified = time() - 60*20; 517 $r3 = $DB->insert_record('sessions', $record); 518 519 $record->sid = md5('hokus4'); 520 $record->userid = $guestid; 521 $record->timecreated = time() - 60*60*60; 522 $record->timemodified = time() - 60*10*5 - 60; 523 $r4 = $DB->insert_record('sessions', $record); 524 525 $record->sid = md5('hokus5'); 526 $record->userid = 0; 527 $record->timecreated = time() - 60*5; 528 $record->timemodified = time() - 60*5; 529 $r5 = $DB->insert_record('sessions', $record); 530 531 $record->sid = md5('hokus6'); 532 $record->userid = 0; 533 $record->timecreated = time() - 60*60; 534 $record->timemodified = time() - 60*10 -10; 535 $r6 = $DB->insert_record('sessions', $record); 536 537 $record->sid = md5('hokus7'); 538 $record->userid = 0; 539 $record->timecreated = time() - 60*60; 540 $record->timemodified = time() - 60*9; 541 $r7 = $DB->insert_record('sessions', $record); 542 543 \core\session\manager::gc(); 544 545 $this->assertTrue($DB->record_exists('sessions', array('id'=>$r1))); 546 $this->assertFalse($DB->record_exists('sessions', array('id'=>$r2))); 547 $this->assertTrue($DB->record_exists('sessions', array('id'=>$r3))); 548 $this->assertFalse($DB->record_exists('sessions', array('id'=>$r4))); 549 $this->assertFalse($DB->record_exists('sessions', array('id'=>$r5))); 550 $this->assertFalse($DB->record_exists('sessions', array('id'=>$r6))); 551 $this->assertTrue($DB->record_exists('sessions', array('id'=>$r7))); 552 } 553 554 /** 555 * Test loginas. 556 * @copyright 2103 Rajesh Taneja <rajesh@moodle.com> 557 */ 558 public function test_loginas() { 559 global $USER, $SESSION; 560 $this->resetAfterTest(); 561 562 // Set current user as Admin user and save it for later use. 563 $this->setAdminUser(); 564 $adminuser = $USER; 565 $adminsession = $SESSION; 566 $user = $this->getDataGenerator()->create_user(); 567 $_SESSION['extra'] = true; 568 569 // Try admin loginas this user in system context. 570 $this->assertObjectNotHasAttribute('realuser', $USER); 571 \core\session\manager::loginas($user->id, context_system::instance()); 572 573 $this->assertSame($user->id, $USER->id); 574 $this->assertEquals(context_system::instance(), $USER->loginascontext); 575 $this->assertSame($adminuser->id, $USER->realuser); 576 $this->assertSame($GLOBALS['USER'], $_SESSION['USER']); 577 $this->assertSame($GLOBALS['USER'], $USER); 578 $this->assertNotSame($adminuser, $_SESSION['REALUSER']); 579 $this->assertEquals($adminuser, $_SESSION['REALUSER']); 580 581 $this->assertSame($GLOBALS['SESSION'], $_SESSION['SESSION']); 582 $this->assertSame($GLOBALS['SESSION'], $SESSION); 583 $this->assertNotSame($adminsession, $_SESSION['REALSESSION']); 584 $this->assertEquals($adminsession, $_SESSION['REALSESSION']); 585 586 $this->assertArrayNotHasKey('extra', $_SESSION); 587 588 // Set user as current user and login as admin user in course context. 589 \core\session\manager::init_empty_session(); 590 $this->setUser($user); 591 $this->assertNotEquals($adminuser->id, $USER->id); 592 $course = $this->getDataGenerator()->create_course(); 593 $coursecontext = context_course::instance($course->id); 594 595 // Catch event triggered. 596 $sink = $this->redirectEvents(); 597 \core\session\manager::loginas($adminuser->id, $coursecontext); 598 $events = $sink->get_events(); 599 $sink->close(); 600 $event = array_pop($events); 601 602 $this->assertSame($adminuser->id, $USER->id); 603 $this->assertSame($coursecontext, $USER->loginascontext); 604 $this->assertSame($user->id, $USER->realuser); 605 606 // Test event captured has proper information. 607 $this->assertInstanceOf('\core\event\user_loggedinas', $event); 608 $this->assertSame($user->id, $event->objectid); 609 $this->assertSame($adminuser->id, $event->relateduserid); 610 $this->assertSame($course->id, $event->courseid); 611 $this->assertEquals($coursecontext, $event->get_context()); 612 $oldfullname = fullname($user, true); 613 $newfullname = fullname($adminuser, true); 614 $expectedlogdata = array($course->id, "course", "loginas", "../user/view.php?id=$course->id&user=$user->id", "$oldfullname -> $newfullname"); 615 $this->assertEventLegacyLogData($expectedlogdata, $event); 616 } 617 618 public function test_is_loggedinas() { 619 $this->resetAfterTest(); 620 621 $user1 = $this->getDataGenerator()->create_user(); 622 $user2 = $this->getDataGenerator()->create_user(); 623 624 $this->assertFalse(\core\session\manager::is_loggedinas()); 625 626 $this->setUser($user1); 627 \core\session\manager::loginas($user2->id, context_system::instance()); 628 629 $this->assertTrue(\core\session\manager::is_loggedinas()); 630 } 631 632 public function test_get_realuser() { 633 $this->resetAfterTest(); 634 635 $user1 = $this->getDataGenerator()->create_user(); 636 $user2 = $this->getDataGenerator()->create_user(); 637 638 $this->setUser($user1); 639 $normal = \core\session\manager::get_realuser(); 640 $this->assertSame($GLOBALS['USER'], $normal); 641 642 \core\session\manager::loginas($user2->id, context_system::instance()); 643 644 $real = \core\session\manager::get_realuser(); 645 646 unset($real->password); 647 unset($real->description); 648 unset($real->sesskey); 649 unset($user1->password); 650 unset($user1->description); 651 unset($user1->sesskey); 652 653 $this->assertEquals($real, $user1); 654 $this->assertSame($_SESSION['REALUSER'], $real); 655 } 656 657 /** 658 * Session lock info on pages. 659 * 660 * @return array 661 */ 662 public function pages_sessionlocks() { 663 return [ 664 [ 665 'url' => '/good.php', 666 'start' => 1500000001.000, 667 'gained' => 1500000002.000, 668 'released' => 1500000003.000, 669 'wait' => 1.0, 670 'held' => 1.0 671 ], 672 [ 673 'url' => '/bad.php?wait=5', 674 'start' => 1500000003.000, 675 'gained' => 1500000005.000, 676 'released' => 1500000007.000, 677 'held' => 2.0, 678 'wait' => 2.0 679 ] 680 ]; 681 } 682 683 /** 684 * Test to get recent session locks. 685 */ 686 public function test_get_recent_session_locks() { 687 global $CFG; 688 689 $this->resetAfterTest(); 690 $CFG->debugsessionlock = 5; 691 $pages = $this->pages_sessionlocks(); 692 // Recent session locks must be empty at first. 693 $recentsessionlocks = \core\session\manager::get_recent_session_locks(); 694 $this->assertEmpty($recentsessionlocks); 695 696 // Add page to the recentsessionlocks array. 697 \core\session\manager::update_recent_session_locks($pages[0]); 698 $recentsessionlocks = \core\session\manager::get_recent_session_locks(); 699 // Make sure we are getting the first page we added. 700 $this->assertEquals($pages[0], $recentsessionlocks[0]); 701 // There should be 1 page in the array. 702 $this->assertCount(1, $recentsessionlocks); 703 704 // Add second page to the recentsessionlocks array. 705 \core\session\manager::update_recent_session_locks($pages[1]); 706 $recentsessionlocks = \core\session\manager::get_recent_session_locks(); 707 // Make sure we are getting the second page we added. 708 $this->assertEquals($pages[1], $recentsessionlocks[1]); 709 // There should be 2 pages in the array. 710 $this->assertCount(2, $recentsessionlocks); 711 } 712 713 /** 714 * Test to update recent session locks. 715 */ 716 public function test_update_recent_session_locks() { 717 global $CFG; 718 719 $this->resetAfterTest(); 720 $CFG->debugsessionlock = 5; 721 $pages = $this->pages_sessionlocks(); 722 723 \core\session\manager::update_recent_session_locks($pages[0]); 724 \core\session\manager::update_recent_session_locks($pages[1]); 725 $recentsessionlocks = \core\session\manager::get_recent_session_locks(); 726 // There should be 2 pages in the array. 727 $this->assertCount(2, $recentsessionlocks); 728 // Make sure the last page is added at the end of the array. 729 $this->assertEquals($pages[1], end($recentsessionlocks)); 730 731 } 732 733 /** 734 * Test to get session lock info. 735 */ 736 public function test_get_session_lock_info() { 737 global $PERF; 738 739 $this->resetAfterTest(); 740 741 $pages = $this->pages_sessionlocks(); 742 $PERF->sessionlock = $pages[0]; 743 $sessionlock = \core\session\manager::get_session_lock_info(); 744 $this->assertEquals($pages[0], $sessionlock); 745 } 746 747 /** 748 * Session lock info on some pages to serve as history. 749 * 750 * @return array 751 */ 752 public function sessionlock_history() { 753 return [ 754 [ 755 'url' => '/good.php', 756 'start' => 1500000001.000, 757 'gained' => 1500000001.100, 758 'released' => 1500000001.500, 759 'wait' => 0.1 760 ], 761 [ 762 // This bad request doesn't release the session for 10 seconds. 763 'url' => '/bad.php', 764 'start' => 1500000012.000, 765 'gained' => 1500000012.200, 766 'released' => 1500000020.200, 767 'wait' => 0.2 768 ], 769 [ 770 // All subsequent requests are blocked and need to wait. 771 'url' => '/good.php?id=1', 772 'start' => 1500000012.900, 773 'gained' => 1500000020.200, 774 'released' => 1500000022.000, 775 'wait' => 7.29 776 ], 777 [ 778 'url' => '/good.php?id=2', 779 'start' => 1500000014.000, 780 'gained' => 1500000022.000, 781 'released' => 1500000025.000, 782 'wait' => 8.0 783 ], 784 [ 785 'url' => '/good.php?id=3', 786 'start' => 1500000015.000, 787 'gained' => 1500000025.000, 788 'released' => 1500000026.000, 789 'wait' => 10.0 790 ], 791 [ 792 'url' => '/good.php?id=4', 793 'start' => 1500000016.000, 794 'gained' => 1500000026.000, 795 'released' => 1500000027.000, 796 'wait' => 10.0 797 ] 798 ]; 799 } 800 801 /** 802 * Data provider for test_get_locked_page_at function. 803 * 804 * @return array 805 */ 806 public function sessionlocks_info_provider() : array { 807 return [ 808 [ 809 'url' => null, 810 'time' => 1500000001.000 811 ], 812 [ 813 'url' => '/bad.php', 814 'time' => 1500000014.000 815 ], 816 [ 817 'url' => '/good.php?id=2', 818 'time' => 1500000022.500 819 ], 820 ]; 821 } 822 823 /** 824 * Test to get locked page at a speficic timestamp. 825 * 826 * @dataProvider sessionlocks_info_provider 827 * @param array $url Session lock page url. 828 * @param array $time Session lock time. 829 */ 830 public function test_get_locked_page_at($url, $time) { 831 global $CFG, $SESSION; 832 833 $this->resetAfterTest(); 834 $CFG->debugsessionlock = 5; 835 $SESSION->recentsessionlocks = $this->sessionlock_history(); 836 837 $page = \core\session\manager::get_locked_page_at($time); 838 $this->assertEquals($url, is_array($page) ? $page['url'] : null); 839 } 840 841 /** 842 * Test cleanup recent session locks. 843 */ 844 public function test_cleanup_recent_session_locks() { 845 global $CFG, $SESSION; 846 847 $this->resetAfterTest(); 848 $CFG->debugsessionlock = 5; 849 850 $SESSION->recentsessionlocks = $this->sessionlock_history(); 851 $this->assertCount(6, $SESSION->recentsessionlocks); 852 \core\session\manager::cleanup_recent_session_locks(); 853 // Make sure the session history has been cleaned up and only has the latest page. 854 $this->assertCount(1, $SESSION->recentsessionlocks); 855 $this->assertEquals('/good.php?id=4', $SESSION->recentsessionlocks[0]['url']); 856 } 857 858 public function test_array_session_diff_same_array() { 859 $a = []; 860 $a['c'] = new stdClass(); 861 $a['c']->o = new stdClass(); 862 $a['c']->o->o = new stdClass(); 863 $a['c']->o->o->l = 'cool'; 864 865 $class = new ReflectionClass('\core\session\manager'); 866 $method = $class->getMethod('array_session_diff'); 867 $method->setAccessible(true); 868 869 $result = $method->invokeArgs(null, [$a, $a]); 870 871 $this->assertEmpty($result); 872 } 873 874 public function test_array_session_diff_first_array_larger() { 875 $a = []; 876 $a['stdClass'] = new stdClass(); 877 $a['stdClass']->attribute = 'This is an attribute'; 878 $a['array'] = ['array', 'contents']; 879 880 $b = []; 881 $b['array'] = ['array', 'contents']; 882 883 $class = new ReflectionClass('\core\session\manager'); 884 $method = $class->getMethod('array_session_diff'); 885 $method->setAccessible(true); 886 887 $result = $method->invokeArgs(null, [$a, $b]); 888 889 $expected = []; 890 $expected['stdClass'] = new stdClass(); 891 $expected['stdClass']->attribute = 'This is an attribute'; 892 $this->assertEquals($expected, $result); 893 } 894 895 public function test_array_session_diff_second_array_larger() { 896 $a = []; 897 $a['array'] = ['array', 'contents']; 898 899 $b = []; 900 $b['stdClass'] = new stdClass(); 901 $b['stdClass']->attribute = 'This is an attribute'; 902 $b['array'] = ['array', 'contents']; 903 904 $class = new ReflectionClass('\core\session\manager'); 905 $method = $class->getMethod('array_session_diff'); 906 $method->setAccessible(true); 907 908 $result = $method->invokeArgs(null, [$a, $b]); 909 910 // It's empty because the first array contains all the contents of the second. 911 $expected = []; 912 $this->assertEquals($expected, $result); 913 } 914 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body