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}}
+
+
+
+ {{#str}}key, auth_oauth2{{/str}} |
+ {{#str}}value, auth_oauth2{{/str}} |
+
+
+
+ {{#pairs}}
+
+ {{name}} |
+ {{{value}}} |
+
+ {{/pairs}}
+
+
+
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"
+ }]
+ }
+}}
+
+
+
+
+
+ {{#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"