diff --git a/.travis.yml b/.travis.yml index 1763903..6bf89c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,68 +1,64 @@ language: php -addons: - firefox: "47.0.1" - postgresql: "9.4" +notifications: + email: + recipients: + - dmitriim@catalyst-au.net + +sudo: false cache: directories: - $HOME/.composer/cache - - $HOME/.npm -dist: trusty +addons: + postgresql: "9.6" + +php: + - 7.1 + - 7.2 + - 7.3 + +env: + global: + - DB=pgsql + matrix: + - MOODLE_BRANCH=MOODLE_33_STABLE + - MOODLE_BRANCH=MOODLE_34_STABLE + - MOODLE_BRANCH=MOODLE_35_STABLE + - MOODLE_BRANCH=MOODLE_36_STABLE + - MOODLE_BRANCH=MOODLE_37_STABLE + - MOODLE_BRANCH=MOODLE_38_STABLE + - 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 + exclude: - 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 + env: MOODLE_BRANCH=master - 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 + env: MOODLE_BRANCH=MOODLE_33_STABLE + - php: 7.3 + env: MOODLE_BRANCH=MOODLE_33_STABLE + - php: 7.3 + env: MOODLE_BRANCH=MOODLE_34_STABLE + - php: 7.3 + env: MOODLE_BRANCH=MOODLE_35_STABLE before_install: - - phpenv config-rm xdebug.ini - - nvm install 8.9 - - nvm use 8.9 - cd ../.. - - composer create-project -n --no-dev --prefer-dist moodlerooms/moodle-plugin-ci ci ^2 + - composer selfupdate + - composer create-project -n --no-dev moodlerooms/moodle-plugin-ci ci ^1 - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" install: - - moodle-plugin-ci install + - moodle-plugin-ci install -vvv script: - moodle-plugin-ci phplint + - moodle-plugin-ci phpmd - moodle-plugin-ci codechecker - - moodle-plugin-ci validate - - moodle-plugin-ci savepoints - - moodle-plugin-ci mustache - - moodle-plugin-ci grunt + - moodle-plugin-ci csslint + - moodle-plugin-ci shifter + - moodle-plugin-ci jshint - moodle-plugin-ci phpunit - moodle-plugin-ci behat diff --git a/README.md b/README.md index 5b26a1d..ab516a6 100644 --- a/README.md +++ b/README.md @@ -163,4 +163,24 @@ echo getloginurl('barrywhite@googlemail.com', 'barry', 'white', 'barrywhite', 2, TODO: ----- -1. Implement logout webservice to be able to call it from external application. \ No newline at end of file +1. Implement logout webservice to be able to call it from external application. + + +# Crafted by Catalyst IT + +This plugin was developed by Catalyst IT Australia: + +https://www.catalyst-au.net/ + +![Catalyst IT](/pix/catalyst-logo.png?raw=true) + +# Contributing and Support + +Issues, and pull requests using github are welcome and encouraged! + +https://github.com/catalyst/moodle-auth_userkey/issues + +If you would like commercial support or would like to sponsor additional improvements +to this plugin please contact us: + +https://www.catalyst-au.net/contact-us diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php new file mode 100644 index 0000000..d969cfe --- /dev/null +++ b/classes/privacy/provider.php @@ -0,0 +1,53 @@ +. + +/** + * Privacy provider. + * + * @package auth_userkey + * @author Dmitrii Metelkin (dmitriim@catalyst-au.net) + * @copyright 2020 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace auth_userkey\privacy; + +defined('MOODLE_INTERNAL') || die; + +use core_privacy\local\metadata\null_provider; +use core_privacy\local\legacy_polyfill; + +/** + * Privacy provider. + * + * @copyright 2020 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class provider implements null_provider { + + use legacy_polyfill; + + /** + * Get the language string identifier with the component's language + * file to explain why this plugin stores no data. + * + * @return string + */ + public static function _get_reason() { + return 'privacy:metadata'; + } + +} diff --git a/lang/en/auth_userkey.php b/lang/en/auth_userkey.php index d916b6b..27f4ecf 100644 --- a/lang/en/auth_userkey.php +++ b/lang/en/auth_userkey.php @@ -52,3 +52,4 @@ $string['ssourl'] = 'URL of SSO host'; $string['ssourl_desc'] = 'URL of the SSO host to redirect users to. If defined users will be redirected here on login instead of the Moodle Login page'; $string['redirecterrordetected'] = 'Unsupported redirect to {$a} detected, execution terminated.'; $string['noip'] = 'Unable to fetch IP address of client.'; +$string['privacy:metadata'] = 'User key authentication plugin does not store any personal data.'; diff --git a/pix/catalyst-logo.png b/pix/catalyst-logo.png new file mode 100644 index 0000000..c7d1a50 Binary files /dev/null and b/pix/catalyst-logo.png differ diff --git a/tests/auth_plugin_test.php b/tests/phpunit/auth_plugin_test.php similarity index 87% rename from tests/auth_plugin_test.php rename to tests/phpunit/auth_plugin_test.php index 98e9606..8e8ef99 100644 --- a/tests/auth_plugin_test.php +++ b/tests/phpunit/auth_plugin_test.php @@ -50,14 +50,53 @@ class auth_plugin_userkey_testcase extends advanced_testcase { global $CFG; require_once($CFG->libdir . "/externallib.php"); - require_once($CFG->dirroot . '/auth/userkey/tests/fake_userkey_manager.php'); + require_once($CFG->dirroot . '/auth/userkey/tests/phpunit/fake_userkey_manager.php'); require_once($CFG->dirroot . '/auth/userkey/auth.php'); require_once($CFG->dirroot . '/user/lib.php'); - $this->auth = new auth_plugin_userkey(); - $this->user = self::getDataGenerator()->create_user(); + parent::setUp(); $this->resetAfterTest(); + $CFG->getremoteaddrconf = GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR; + $this->auth = new auth_plugin_userkey(); + $this->user = self::getDataGenerator()->create_user(); + } + + /** + * A helper function to create TestKey. + * + * @param array $record Key record. + */ + protected function create_user_private_key(array $record = []) { + global $DB; + + $record = (object)$record; + + if (!isset($record->value)) { + $record->value = 'TestKey'; + } + + if (!isset($record->userid)) { + $record->userid = $this->user->id; + } + + if (!isset($record->userid)) { + $record->instance = $this->user->id; + } + + if (!isset($record->iprestriction)) { + $record->iprestriction = null; + } + if (!isset($record->validuntil)) { + $record->validuntil = time() + 300; + } + if (!isset($record->timecreated)) { + $record->timecreated = time(); + } + + $record->script = 'auth/userkey'; + + $DB->insert_record('user_private_key', $record); } /** @@ -682,19 +721,9 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * @expectedExceptionMessage Expired key */ public function test_expired_key_exception_thrown_if_expired_key() { - global $DB; + $this->create_user_private_key(['validuntil' => time() - 3000]); - $key = new stdClass(); - $key->value = 'ExpiredKey'; - $key->script = 'auth/userkey'; - $key->userid = $this->user->id; - $key->instance = $this->user->id; - $key->iprestriction = null; - $key->validuntil = time() - 3000; - $key->timecreated = time(); - $DB->insert_record('user_private_key', $key); - - $_POST['key'] = 'ExpiredKey'; + $_POST['key'] = 'TestKey'; $this->auth->user_login_userkey(); } @@ -705,19 +734,9 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * @expectedExceptionMessage Client IP address mismatch */ public function test_ipmismatch_exception_thrown_if_ip_is_incorrect() { - global $DB; + $this->create_user_private_key(['iprestriction' => '192.168.1.1']); - $key = new stdClass(); - $key->value = 'IpmismatchKey'; - $key->script = 'auth/userkey'; - $key->userid = $this->user->id; - $key->instance = $this->user->id; - $key->iprestriction = '192.168.1.1'; - $key->validuntil = time() + 300; - $key->timecreated = time(); - $DB->insert_record('user_private_key', $key); - - $_POST['key'] = 'IpmismatchKey'; + $_POST['key'] = 'TestKey'; $_SERVER['HTTP_CLIENT_IP'] = '192.168.1.2'; $this->auth->user_login_userkey(); } @@ -729,21 +748,10 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * @expectedExceptionMessage Client IP address mismatch */ public function test_ipmismatch_exception_thrown_if_ip_is_outside_whitelist() { - global $DB; - set_config('ipwhitelist', '10.0.0.0/8;172.16.0.0/12;192.168.0.0/16', 'auth_userkey'); + $this->create_user_private_key(['iprestriction' => '192.161.1.1']); - $key = new stdClass(); - $key->value = 'IpmismatchKey'; - $key->script = 'auth/userkey'; - $key->userid = $this->user->id; - $key->instance = $this->user->id; - $key->iprestriction = '192.161.1.1'; - $key->validuntil = time() + 300; - $key->timecreated = time(); - $DB->insert_record('user_private_key', $key); - - $_POST['key'] = 'IpmismatchKey'; + $_POST['key'] = 'TestKey'; $_SERVER['HTTP_CLIENT_IP'] = '192.161.1.2'; $this->auth->user_login_userkey(); } @@ -755,19 +763,13 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * @expectedExceptionMessageRegExp /Invalid user id/i */ public function test_invalid_user_exception_thrown_if_user_is_invalid() { - global $DB; + $this->create_user_private_key([ + 'userid' => 777, + 'instance' => 777, + 'iprestriction' => '192.168.1.1', + ]); - $key = new stdClass(); - $key->value = 'InvalidUser'; - $key->script = 'auth/userkey'; - $key->userid = 777; - $key->instance = 777; - $key->iprestriction = '192.168.1.1'; - $key->validuntil = time() + 300; - $key->timecreated = time(); - $DB->insert_record('user_private_key', $key); - - $_POST['key'] = 'InvalidUser'; + $_POST['key'] = 'TestKey'; $_SERVER['HTTP_CLIENT_IP'] = '192.168.1.1'; $this->auth->user_login_userkey(); } @@ -778,15 +780,10 @@ class auth_plugin_userkey_testcase extends advanced_testcase { public function test_that_key_gets_removed_after_user_logged_in() { global $DB; - $key = new stdClass(); - $key->value = 'RemoveKey'; - $key->script = 'auth/userkey'; - $key->userid = $this->user->id; - $key->instance = $this->user->id; - $key->iprestriction = '192.168.1.1'; - $key->validuntil = time() + 300; - $key->timecreated = time(); - $DB->insert_record('user_private_key', $key); + $this->create_user_private_key([ + 'value' => 'RemoveKey', + 'iprestriction' => '192.168.1.1', + ]); $_POST['key'] = 'RemoveKey'; $_SERVER['HTTP_CLIENT_IP'] = '192.168.1.1'; @@ -807,20 +804,11 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * @expectedExceptionMessage Unsupported redirect to http://www.example.com/moodle detected, execution terminated. */ public function test_that_user_logged_in_and_redirected() { - global $DB, $CFG; - - $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); + global $CFG; + $this->create_user_private_key(); $CFG->wwwroot = 'http://www.example.com/moodle'; - $_POST['key'] = 'UserLogin'; + $_POST['key'] = 'TestKey'; @$this->auth->user_login_userkey(); } @@ -828,19 +816,11 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * Test that a user logs in correctly. */ public function test_that_user_logged_in_correctly() { - global $DB, $USER, $SESSION; + global $USER, $SESSION; - $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); + $this->create_user_private_key(); - $_POST['key'] = 'UserLogin'; + $_POST['key'] = 'TestKey'; try { // Using @ is the only way to test this. Thanks moodle! @@ -859,19 +839,8 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * @expectedExceptionMessage Unsupported redirect to /course/index.php?id=12&key=134 detected, execution terminated. */ public function test_that_user_gets_redirected_to_internal_wantsurl() { - global $DB; - - $key = new stdClass(); - $key->value = 'WantsUrl'; - $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'] = 'WantsUrl'; + $this->create_user_private_key(); + $_POST['key'] = 'TestKey'; $_POST['wantsurl'] = '/course/index.php?id=12&key=134'; // Using @ is the only way to test this. Thanks moodle! @@ -886,19 +855,9 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * execution terminated. */ public function test_that_user_gets_redirected_to_external_wantsurl() { - global $DB; + $this->create_user_private_key(); - $key = new stdClass(); - $key->value = 'WantsUrlExternal'; - $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'] = 'WantsUrlExternal'; + $_POST['key'] = 'TestKey'; $_POST['wantsurl'] = 'http://test.com/course/index.php?id=12&key=134'; // Using @ is the only way to test this. Thanks moodle! @@ -993,23 +952,15 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * 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; + global $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); + $this->create_user_private_key(); - $_POST['key'] = 'UserLogin'; + $_POST['key'] = 'TestKey'; try { // Using @ is the only way to test this. Thanks moodle! @@ -1025,21 +976,13 @@ class auth_plugin_userkey_testcase extends advanced_testcase { * 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; + global $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); + $this->create_user_private_key(); $_POST['key'] = 'Incorrect Key'; @@ -1062,17 +1005,9 @@ class auth_plugin_userkey_testcase extends advanced_testcase { $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); + $this->create_user_private_key(); - $_POST['key'] = 'UserLogin'; + $_POST['key'] = 'TestKey'; try { // Using @ is the only way to test this. Thanks moodle! @@ -1081,7 +1016,7 @@ class auth_plugin_userkey_testcase extends advanced_testcase { $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')); + $keyexists = $DB->record_exists('user_private_key', array('value' => 'TestKey')); $this->assertFalse($keyexists); } } diff --git a/tests/core_userkey_manager_test.php b/tests/phpunit/core_userkey_manager_test.php similarity index 99% rename from tests/core_userkey_manager_test.php rename to tests/phpunit/core_userkey_manager_test.php index a6945d3..abf9ad8 100644 --- a/tests/core_userkey_manager_test.php +++ b/tests/phpunit/core_userkey_manager_test.php @@ -52,7 +52,12 @@ class core_userkey_manager_testcase extends advanced_testcase { * Initial set up. */ public function setUp() { + global $CFG; + + parent::setUp(); + $this->resetAfterTest(); + $CFG->getremoteaddrconf = GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR; $this->user = self::getDataGenerator()->create_user(); $this->config = new stdClass(); } diff --git a/tests/externallib_test.php b/tests/phpunit/externallib_test.php similarity index 99% rename from tests/externallib_test.php rename to tests/phpunit/externallib_test.php index 4d0342f..f6a269c 100644 --- a/tests/externallib_test.php +++ b/tests/phpunit/externallib_test.php @@ -153,7 +153,7 @@ class auth_userkey_externallib_testcase extends advanced_testcase { * @expectedException invalid_parameter_exception * @expectedExceptionMessage Invalid parameter value detected (Required field "email" is not set or empty.) */ - public function test_exception_thrown_if_required_parameter_email_is_not_seе() { + public function test_exception_thrown_if_required_parameter_email_is_not_set() { global $CFG; $this->setAdminUser(); @@ -172,7 +172,7 @@ class auth_userkey_externallib_testcase extends advanced_testcase { * @expectedException invalid_parameter_exception * @expectedExceptionMessage Invalid parameter value detected (Required parameter "ip" is not set.) */ - public function test_exception_thrown_if_required_parameter_ip_is_not_seе() { + public function test_exception_thrown_if_required_parameter_op_is_not_set() { global $CFG; $this->setAdminUser(); diff --git a/tests/fake_userkey_manager.php b/tests/phpunit/fake_userkey_manager.php similarity index 100% rename from tests/fake_userkey_manager.php rename to tests/phpunit/fake_userkey_manager.php diff --git a/version.php b/version.php index 6ab0a6b..b8ba70a 100644 --- a/version.php +++ b/version.php @@ -24,8 +24,8 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2018050200; // The current plugin version (Date: YYYYMMDDXX) -$plugin->release = 2018050200; // Match release exactly to version. +$plugin->version = 2020050800; // The current plugin version (Date: YYYYMMDDXX) +$plugin->release = 2020050800; // Match release exactly to version. $plugin->requires = 2017051500; // Requires Moodle 3.3 version. $plugin->component = 'auth_userkey'; // Full name of the plugin (used for diagnostics). $plugin->maturity = MATURITY_STABLE;