diff --git a/.travis.yml b/.travis.yml index 31b1ce2..1763903 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,46 +1,68 @@ language: php -notifications: - email: - recipients: - - dmitriim@catalyst-au.net - -sudo: false +addons: + firefox: "47.0.1" + postgresql: "9.4" cache: directories: - $HOME/.composer/cache + - $HOME/.npm -php: - - 7.0 - - 7.1 +dist: trusty -addons: - postgresql: "9.3" - -env: - - DB=pgsql MOODLE_BRANCH=MOODLE_33_STABLE - - DB=pgsql MOODLE_BRANCH=MOODLE_34_STABLE - - DB=pgsql MOODLE_BRANCH=master - - DB=mysqli MOODLE_BRANCH=MOODLE_33_STABLE - - DB=mysqli MOODLE_BRANCH=MOODLE_34_STABLE - - DB=mysqli MOODLE_BRANCH=master +matrix: + include: + - php: 7.0 + env: DB=mysqli MOODLE_BRANCH=MOODLE_33_STABLE + - php: 7.0 + env: DB=pgsql MOODLE_BRANCH=MOODLE_33_STABLE + - php: 7.0 + env: DB=mysqli MOODLE_BRANCH=MOODLE_34_STABLE + - php: 7.0 + env: DB=pgsql MOODLE_BRANCH=MOODLE_34_STABLE + - php: 7.1 + env: DB=mysqli MOODLE_BRANCH=MOODLE_33_STABLE + - php: 7.1 + env: DB=pgsql MOODLE_BRANCH=MOODLE_33_STABLE + - php: 7.1 + env: DB=mysqli MOODLE_BRANCH=MOODLE_34_STABLE + - php: 7.1 + env: DB=pgsql MOODLE_BRANCH=MOODLE_34_STABLE + - php: 7.1 + env: DB=mysqli MOODLE_BRANCH=MOODLE_35_STABLE + - php: 7.1 + env: DB=pgsql MOODLE_BRANCH=MOODLE_35_STABLE + - php: 7.1 + env: DB=mysqli MOODLE_BRANCH=MOODLE_36_STABLE + - php: 7.1 + env: DB=pgsql MOODLE_BRANCH=MOODLE_36_STABLE + - php: 7.2 + env: DB=mysqli MOODLE_BRANCH=MOODLE_37_STABLE + - php: 7.2 + env: DB=pgsql MOODLE_BRANCH=MOODLE_37_STABLE + - php: 7.2 + env: DB=mysqli MOODLE_BRANCH=master + - php: 7.2 + env: DB=pgsql MOODLE_BRANCH=master before_install: + - phpenv config-rm xdebug.ini + - nvm install 8.9 + - nvm use 8.9 - cd ../.. - - composer selfupdate - - composer create-project -n --no-dev moodlerooms/moodle-plugin-ci ci ^1 + - composer create-project -n --no-dev --prefer-dist moodlerooms/moodle-plugin-ci ci ^2 - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" install: - moodle-plugin-ci install script: - - moodle-plugin-ci validate - moodle-plugin-ci phplint - moodle-plugin-ci codechecker - - moodle-plugin-ci csslint - - moodle-plugin-ci shifter - - moodle-plugin-ci jshint + - moodle-plugin-ci validate + - moodle-plugin-ci savepoints + - moodle-plugin-ci mustache + - moodle-plugin-ci grunt - moodle-plugin-ci phpunit - moodle-plugin-ci behat diff --git a/auth.php b/auth.php index 377c119..1abead0 100644 --- a/auth.php +++ b/auth.php @@ -134,10 +134,12 @@ class auth_plugin_userkey extends auth_plugin_base { /** * Logs a user in using userkey and redirects after. * + * @TODO: refactor this method to make it easy to read. + * * @throws \moodle_exception If something went wrong. */ public function user_login_userkey() { - global $SESSION, $CFG; + global $SESSION, $CFG, $USER; $keyvalue = required_param('key', PARAM_ALPHANUM); $wantsurl = optional_param('wantsurl', '', PARAM_URL); @@ -148,11 +150,27 @@ class auth_plugin_userkey extends auth_plugin_base { $redirecturl = $CFG->wwwroot; } - if (isloggedin()) { - $this->redirect($redirecturl); + try { + $key = $this->userkeymanager->validate_key($keyvalue); + } catch (moodle_exception $exception) { + // If user is logged in and key is not valid, we'd like to logout a user. + if (isloggedin()) { + require_logout(); + } + print_error($exception->errorcode); + } + + if (isloggedin()) { + if ($USER->id != $key->userid) { + // Logout the current user if it's different to one that associated to the valid key. + require_logout(); + } else { + // Don't process further if the user is already logged in. + $this->userkeymanager->delete_keys($key->userid); + $this->redirect($redirecturl); + } } - $key = $this->userkeymanager->validate_key($keyvalue); $this->userkeymanager->delete_keys($key->userid); $user = get_complete_user_data('id', $key->userid); diff --git a/tests/auth_plugin_test.php b/tests/auth_plugin_test.php index ba6c119..98e9606 100644 --- a/tests/auth_plugin_test.php +++ b/tests/auth_plugin_test.php @@ -752,7 +752,7 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * Test that IP address mismatch exception gets thrown if user id is incorrect. * * @expectedException moodle_exception - * @expectedExceptionMessage Invalid user id + * @expectedExceptionMessageRegExp /Invalid user id/i */ public function test_invalid_user_exception_thrown_if_user_is_invalid() { global $DB; @@ -989,4 +989,101 @@ class auth_plugin_userkey_testcase extends advanced_testcase { $this->assertTrue($this->auth->pre_loginpage_hook()); } + /** + * Test that if one user logged, he will be logged out before a new one is authorised. + */ + public function test_that_different_authorised_user_is_logged_out_and_new_one_logged_in() { + global $DB, $USER, $SESSION; + + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + $this->assertEquals($USER->id, $user->id); + + $key = new stdClass(); + $key->value = 'UserLogin'; + $key->script = 'auth/userkey'; + $key->userid = $this->user->id; + $key->instance = $this->user->id; + $key->iprestriction = null; + $key->validuntil = time() + 300; + $key->timecreated = time(); + $DB->insert_record('user_private_key', $key); + + $_POST['key'] = 'UserLogin'; + + try { + // Using @ is the only way to test this. Thanks moodle! + @$this->auth->user_login_userkey(); + } catch (moodle_exception $e) { + $this->assertEquals($this->user->id, $USER->id); + $this->assertSame(sesskey(), $USER->sesskey); + $this->assertObjectHasAttribute('userkey', $SESSION); + } + } + + /** + * Test that authorised user gets logged out when trying to logged in with invalid key. + */ + public function test_if_invalid_key_authorised_user_gets_logged_out() { + global $DB, $USER, $SESSION; + + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + $this->assertEquals($USER->id, $user->id); + + $key = new stdClass(); + $key->value = 'UserLogin'; + $key->script = 'auth/userkey'; + $key->userid = $this->user->id; + $key->instance = $this->user->id; + $key->iprestriction = null; + $key->validuntil = time() + 300; + $key->timecreated = time(); + $DB->insert_record('user_private_key', $key); + + $_POST['key'] = 'Incorrect Key'; + + try { + // Using @ is the only way to test this. Thanks moodle! + @$this->auth->user_login_userkey(); + } catch (moodle_exception $e) { + $this->assertEquals('Incorrect key', $e->getMessage()); + $this->assertEmpty($USER->id); + $this->assertEquals(new stdClass(), $SESSION); + } + } + + /** + * Test if a user is logged in and tries to log in again it stays logged in. + */ + public function test_that_already_logged_in_user_stays_logged_in() { + global $DB, $USER, $SESSION; + + $this->setUser($this->user); + $this->assertEquals($USER->id, $this->user->id); + + $key = new stdClass(); + $key->value = 'UserLogin'; + $key->script = 'auth/userkey'; + $key->userid = $this->user->id; + $key->instance = $this->user->id; + $key->iprestriction = null; + $key->validuntil = time() + 300; + $key->timecreated = time(); + $DB->insert_record('user_private_key', $key); + + $_POST['key'] = 'UserLogin'; + + try { + // Using @ is the only way to test this. Thanks moodle! + @$this->auth->user_login_userkey(); + } catch (moodle_exception $e) { + $this->assertEquals($this->user->id, $USER->id); + $this->assertSame(sesskey(), $USER->sesskey); + $this->assertObjectNotHasAttribute('userkey', $SESSION); + $keyexists = $DB->record_exists('user_private_key', array('value' => 'UserLogin')); + $this->assertFalse($keyexists); + } + } + }