mirror of
https://github.com/moodle/moodle.git
synced 2025-08-07 18:06:51 +02:00
Merge branch 'wip_MDL-47834_m29_concurrentlogins' of https://github.com/skodak/moodle
This commit is contained in:
commit
3111b66fbd
7 changed files with 191 additions and 0 deletions
|
@ -622,6 +622,62 @@ class manager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate other sessions of current user depending
|
||||
* on $CFG->limitconcurrentlogins restriction.
|
||||
*
|
||||
* This is expected to be called right after complete_user_login().
|
||||
*
|
||||
* NOTE:
|
||||
* * Do not use from SSO auth plugins, this would not work.
|
||||
* * Do not use from web services because they do not have sessions.
|
||||
*
|
||||
* @param int $userid
|
||||
* @param string $sid session id to be always keep, usually the current one
|
||||
* @return void
|
||||
*/
|
||||
public static function apply_concurrent_login_limit($userid, $sid = null) {
|
||||
global $CFG, $DB;
|
||||
|
||||
// NOTE: the $sid parameter is here mainly to allow testing,
|
||||
// in most cases it should be current session id.
|
||||
|
||||
if (isguestuser($userid) or empty($userid)) {
|
||||
// This applies to real users only!
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($CFG->limitconcurrentlogins) or $CFG->limitconcurrentlogins < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$count = $DB->count_records('sessions', array('userid' => $userid));
|
||||
|
||||
if ($count <= $CFG->limitconcurrentlogins) {
|
||||
return;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$select = "userid = :userid";
|
||||
$params = array('userid' => $userid);
|
||||
if ($sid) {
|
||||
if ($DB->record_exists('sessions', array('sid' => $sid, 'userid' => $userid))) {
|
||||
$select .= " AND sid <> :sid";
|
||||
$params['sid'] = $sid;
|
||||
$i = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$sessions = $DB->get_records_select('sessions', $select, $params, 'timecreated DESC', 'id, sid');
|
||||
foreach ($sessions as $session) {
|
||||
$i++;
|
||||
if ($i <= $CFG->limitconcurrentlogins) {
|
||||
continue;
|
||||
}
|
||||
self::kill_session($session->sid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current user.
|
||||
*
|
||||
|
|
|
@ -326,6 +326,129 @@ class core_session_manager_testcase extends advanced_testcase {
|
|||
$this->assertEquals(1, $DB->count_records('sessions', array('userid' => $userid, 'sid' => md5('pokus5'))));
|
||||
}
|
||||
|
||||
public function test_apply_concurrent_login_limit() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$guest = guest_user();
|
||||
|
||||
$record = new \stdClass();
|
||||
$record->state = 0;
|
||||
$record->sessdata = null;
|
||||
$record->userid = $user1->id;
|
||||
$record->timemodified = time();
|
||||
$record->firstip = $record->lastip = '10.0.0.1';
|
||||
|
||||
$record->sid = md5('hokus1');
|
||||
$record->timecreated = 20;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('hokus2');
|
||||
$record->timecreated = 10;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('hokus3');
|
||||
$record->timecreated = 30;
|
||||
$DB->insert_record('sessions', $record);
|
||||
|
||||
$record->userid = $user2->id;
|
||||
$record->sid = md5('pokus1');
|
||||
$record->timecreated = 20;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('pokus2');
|
||||
$record->timecreated = 10;
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('pokus3');
|
||||
$record->timecreated = 30;
|
||||
$DB->insert_record('sessions', $record);
|
||||
|
||||
$record->timecreated = 10;
|
||||
$record->userid = $guest->id;
|
||||
$record->sid = md5('g1');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('g2');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('g3');
|
||||
$DB->insert_record('sessions', $record);
|
||||
|
||||
$record->userid = 0;
|
||||
$record->sid = md5('nl1');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('nl2');
|
||||
$DB->insert_record('sessions', $record);
|
||||
$record->sid = md5('nl3');
|
||||
$DB->insert_record('sessions', $record);
|
||||
|
||||
set_config('limitconcurrentlogins', 0);
|
||||
$this->assertCount(12, $DB->get_records('sessions'));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id);
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id);
|
||||
\core\session\manager::apply_concurrent_login_limit($guest->id);
|
||||
\core\session\manager::apply_concurrent_login_limit(0);
|
||||
$this->assertCount(12, $DB->get_records('sessions'));
|
||||
|
||||
set_config('limitconcurrentlogins', -1);
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id);
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id);
|
||||
\core\session\manager::apply_concurrent_login_limit($guest->id);
|
||||
\core\session\manager::apply_concurrent_login_limit(0);
|
||||
$this->assertCount(12, $DB->get_records('sessions'));
|
||||
|
||||
set_config('limitconcurrentlogins', 2);
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id);
|
||||
$this->assertCount(11, $DB->get_records('sessions'));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10)));
|
||||
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
set_config('limitconcurrentlogins', 2);
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id, md5('pokus2'));
|
||||
$this->assertCount(10, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($guest->id);
|
||||
\core\session\manager::apply_concurrent_login_limit(0);
|
||||
$this->assertCount(10, $DB->get_records('sessions'));
|
||||
|
||||
set_config('limitconcurrentlogins', 1);
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id, md5('grrr'));
|
||||
$this->assertCount(9, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10)));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user1->id);
|
||||
$this->assertCount(9, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 20)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 30)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user1->id, 'timecreated' => 10)));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id, md5('pokus2'));
|
||||
$this->assertCount(8, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($user2->id);
|
||||
$this->assertCount(8, $DB->get_records('sessions'));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 20)));
|
||||
$this->assertFalse($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 30)));
|
||||
$this->assertTrue($DB->record_exists('sessions', array('userid' => $user2->id, 'timecreated' => 10)));
|
||||
|
||||
\core\session\manager::apply_concurrent_login_limit($guest->id);
|
||||
\core\session\manager::apply_concurrent_login_limit(0);
|
||||
$this->assertCount(8, $DB->get_records('sessions'));
|
||||
}
|
||||
|
||||
public function test_kill_all_sessions() {
|
||||
global $DB, $USER;
|
||||
$this->resetAfterTest();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue