diff --git a/auth/oauth2/auth.php b/auth/oauth2/auth.php index 0d5ecd7f79a..76700d7cd55 100644 --- a/auth/oauth2/auth.php +++ b/auth/oauth2/auth.php @@ -35,6 +35,30 @@ require_once($CFG->libdir.'/authlib.php'); */ class auth_plugin_oauth2 extends \auth_oauth2\auth { + /** + * Test the various configured Oauth2 providers. + */ + public function test_settings() { + global $OUTPUT; + + $authplugin = get_auth_plugin('oauth2'); + $idps = $authplugin->loginpage_idp_list(''); + $templateidps = []; + + if (empty($idps)) { + echo $OUTPUT->notification(get_string('noconfiguredidps', 'auth_oauth2'), 'notifyproblem'); + return; + } else { + foreach ($idps as $idp) { + $idpid = $idp['url']->get_param('id'); + $sesskey = $idp['url']->get_param('sesskey'); + $testurl = new moodle_url('/auth/oauth2/test.php', ['id' => $idpid, 'sesskey' => $sesskey]); + + $templateidps[] = ['name' => $idp['name'], 'url' => $testurl->out(), 'iconurl' => $idp['iconurl']]; + } + echo $OUTPUT->render_from_template('auth_oauth2/idps', ['idps' => $templateidps]); + } + } } diff --git a/auth/oauth2/lang/en/auth_oauth2.php b/auth/oauth2/lang/en/auth_oauth2.php index c3a4246bc9b..ce844db320f 100644 --- a/auth/oauth2/lang/en/auth_oauth2.php +++ b/auth/oauth2/lang/en/auth_oauth2.php @@ -88,13 +88,16 @@ $string['emailpasswordchangeinfosubject'] = '{$a}: Change password information'; $string['info'] = 'External account'; $string['issuer'] = 'OAuth 2 Service'; $string['issuernologin'] = 'This issuer can not be used to login'; +$string['key'] = 'Key'; $string['linkedlogins'] = 'Linked logins'; $string['linkedloginshelp'] = 'Help with linked logins'; +$string['loggedin'] = 'User successfully authenticated with provider.'; $string['loginerror_userincomplete'] = 'The user information returned did not contain a username and email address. The OAuth 2 service may be configured incorrectly.'; $string['loginerror_nouserinfo'] = 'No user information was returned. The OAuth 2 service may be configured incorrectly.'; $string['loginerror_invaliddomain'] = 'The email address is not allowed at this site.'; $string['loginerror_authenticationfailed'] = 'The authentication process failed.'; $string['loginerror_cannotcreateaccounts'] = 'An account with your email address could not be found.'; +$string['noconfiguredidps'] = 'There are no configured OAuth2 providers.'; $string['noissuersavailable'] = 'None of the configured OAuth2 services allow you to link login accounts'; $string['notloggedindebug'] = 'The login attempt failed. Reason: {$a}'; $string['notwhileloggedinas'] = 'Linked logins cannot be managed while logged in as another user.'; @@ -115,3 +118,6 @@ $string['privacy:metadata:auth_oauth2:timemodified'] = 'The timestamp when this $string['privacy:metadata:auth_oauth2:userid'] = 'The ID of the user account which the OAuth 2 login is linked to.'; $string['privacy:metadata:auth_oauth2:usermodified'] = 'The ID of the user who modified this account.'; $string['privacy:metadata:auth_oauth2:username'] = 'The external username that maps to this account.'; +$string['testidplogin'] = 'Test login with:'; +$string['userinfo'] = 'User data from provider:'; +$string['value'] = 'Value'; diff --git a/auth/oauth2/templates/idpresponse.mustache b/auth/oauth2/templates/idpresponse.mustache new file mode 100644 index 00000000000..8141ac8c47e --- /dev/null +++ b/auth/oauth2/templates/idpresponse.mustache @@ -0,0 +1,65 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template auth_oauth2/idpresponse + + Render response returned from the oAuth IdP for + supplied test user. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Context variables required for this template: + * pairs - array of key value pairs return from the oAuth IdP + * name - the name field from the IdP for the field + * value - the value of the field for the supplied test user + + Example context (json): + { + "pairs": [{ + "name": "firstname", + "value": "Jane" + }, + { + "name": "lastname", + "value": "Awesome" + }] + } +}} + +
+

{{#str}}userinfo, auth_oauth2{{/str}}

+ + + + + + + + + {{#pairs}} + + + + + {{/pairs}} + +
{{#str}}key, auth_oauth2{{/str}}{{#str}}value, auth_oauth2{{/str}}
{{name}}{{{value}}}
+
diff --git a/auth/oauth2/templates/idps.mustache b/auth/oauth2/templates/idps.mustache new file mode 100644 index 00000000000..0011e03d955 --- /dev/null +++ b/auth/oauth2/templates/idps.mustache @@ -0,0 +1,60 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template auth_oauth2/idps + + Render available oauth2 idps for testing. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Context variables required for this template: + * idps - array of oAuth IdP objects + * name - the display name of the IdP + * url - the url of the oAuth test endpoint + * iconurl - the icon of the oAuth IdP + + Example context (json): + { + "idps": [{ + "name": "Microsoft", + "url": "http:\/\/localhost\/auth\/oauth2\/test.php?id=2&sesskey=4js6afElZh", + "iconurl": "https:\/\/www.microsoft.com\/favicon.ico" + }] + } +}} + +
+
+

{{#str}}testidplogin, auth_oauth2{{/str}}

+
+
+
+ {{#idps}} + + {{/idps}} +
+
+
diff --git a/auth/oauth2/test.php b/auth/oauth2/test.php new file mode 100644 index 00000000000..7a488caac3d --- /dev/null +++ b/auth/oauth2/test.php @@ -0,0 +1,85 @@ +. + +/** + * This file allows for testing of login via configured oauth2 IDP poviders. + * + * @package auth_oauth2 + * @copyright 2021 Matt Porritt + * @license http://www.gnu.org/copyleft/gpl.html GNU Public License + */ + +// Require_login is not needed here. +// phpcs:disable moodle.Files.RequireLogin.Missing +require_once('../../config.php'); + +require_sesskey(); + +$issuerid = required_param('id', PARAM_INT); +$url = new moodle_url('/auth/oauth2/test.php', ['id' => $issuerid, 'sesskey' => sesskey()]); + +$PAGE->set_context(context_system::instance()); +$PAGE->set_url($url); +$PAGE->set_pagelayout('admin'); + +if (!\auth_oauth2\api::is_enabled()) { + throw new \moodle_exception('notenabled', 'auth_oauth2'); +} + +$issuer = new \core\oauth2\issuer($issuerid); +if (!$issuer->is_available_for_login()) { + throw new \moodle_exception('issuernologin', 'auth_oauth2'); +} + +$client = \core\oauth2\api::get_user_oauth_client($issuer, $url); + +if ($client) { + // We have a valid client, now lets see if we can log into the IDP. + if (!$client->is_logged_in()) { + redirect($client->get_login_url()); + } + + echo $OUTPUT->header(); + + // We were successful logging into the IDP. + echo $OUTPUT->notification(get_string('loggedin', 'auth_oauth2'), 'notifysuccess'); + + // Try getting user info from the IDP. + $endpointurl = $client->get_issuer()->get_endpoint_url('userinfo'); + $response = $client->get($endpointurl); + $userinfo = json_decode($response, true); + + $templateinfo = []; + foreach ($userinfo as $key => $value) { + // We are just displaying the data from the IdP for testing purposes, + // so we are more interested in displaying it to the admin than + // processing it. + if (is_array($value)) { + $value = json_encode($value); + } + $templateinfo[] = ['name' => $key, 'value' => $value]; + } + + // Display user info. + if (!empty($templateinfo)) { + echo $OUTPUT->render_from_template('auth_oauth2/idpresponse', ['pairs' => $templateinfo]); + } + +} else { + throw new moodle_exception('Could not get an OAuth client.'); +} + +echo $OUTPUT->footer(); diff --git a/auth/oauth2/tests/behat/settings_test.feature b/auth/oauth2/tests/behat/settings_test.feature new file mode 100644 index 00000000000..02070e59861 --- /dev/null +++ b/auth/oauth2/tests/behat/settings_test.feature @@ -0,0 +1,26 @@ +@auth @auth_oauth2 @javascript +Feature: OAuth2 settings test functionality + In order to use them later for authentication + As an administrator + I need to be able to test configured OAuth2 login services. + + Background: + Given I log in as "admin" + And I change window size to "large" + + Scenario: Test oAuth2 authentication settings with no configured service. + Given I navigate to "Plugins > Authentication > Manage authentication" in site administration + And I click on "Test settings" "link" in the "OAuth 2" "table_row" + Then I should see "There are no configured OAuth2 providers" + + Scenario: Test oAuth2 authentication settings for a configured service. + Given I navigate to "Server > OAuth 2 services" in site administration + And I press "Google" + And I set the following fields to these values: + | Name | Testing service | + | Client ID | thisistheclientid | + | Client secret | supersecret | + And I press "Save changes" + And I navigate to "Plugins > Authentication > Manage authentication" in site administration + And I click on "Test settings" "link" in the "OAuth 2" "table_row" + Then I should see "Testing service"