MDL-58168 auth_oauth2: Allow linking other accounts

Part of MDL-58220
This commit is contained in:
Damyon Wiese 2017-03-08 22:03:09 +08:00
parent 151b0f9409
commit 1dca8d1a1d
12 changed files with 640 additions and 17 deletions

147
auth/oauth2/classes/api.php Normal file
View File

@ -0,0 +1,147 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Class for loading/storing oauth2 linked logins from the DB.
*
* @package auth_oauth2
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_oauth2;
use context_user;
use stdClass;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
/**
* Static list of api methods for auth oauth2 configuration.
*
* @package auth_oauth2
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class api {
/**
* List linked logins
*
* Requires auth/oauth2:managelinkedlogins capability at the user context.
*
* @param int $userid (defaults to $USER->id)
* @return boolean
*/
public static function get_linked_logins($userid = false) {
global $USER;
if ($userid === false) {
$userid = $USER->id;
}
if (\core\session\manager::is_loggedinas()) {
throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
}
$context = context_user::instance($userid);
require_capability('auth/oauth2:managelinkedlogins', $context);
return linked_login::get_records(['userid' => $userid]);
}
/**
* See if there is a match for this username and issuer in the linked_login table.
*
* @param string $username as returned from an oauth client.
* @param \core\oauth2\issuer $issuer
* @return stdClass User record if found.
*/
public static function match_username_to_user($username, $issuer) {
$params = [
'issuerid' => $issuer->get('id'),
'username' => $username
];
$match = linked_login::get_record($params);
if ($match) {
$user = get_complete_user_data('id', $match->get('userid'));
return $user;
}
return false;
}
/**
* Link a login to this account.
*
* Requires auth/oauth2:managelinkedlogins capability at the user context.
*
* @param array $userinfo as returned from an oauth client.
* @param \core\oauth2\issuer $issuer
* @param int $userid (defaults to $USER->id)
* @return boolean
*/
public static function link_login($userinfo, $issuer, $userid = false) {
global $USER;
if ($userid === false) {
$userid = $USER->id;
}
if (\core\session\manager::is_loggedinas()) {
throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
}
$context = context_user::instance($userid);
require_capability('auth/oauth2:managelinkedlogins', $context);
$record = new stdClass();
$record->issuerid = $issuer->get('id');
$record->username = $userinfo['username'];
$record->email = $userinfo['email'];
$record->userid = $userid;
$existing = linked_login::get_record((array)$record);
if ($existing) {
return $existing;
}
$linkedlogin = new linked_login(0, $record);
return $linkedlogin->create();
}
/**
* Delete linked login
*
* Requires auth/oauth2:managelinkedlogins capability at the user context.
*
* @param int $linkedloginid
* @return boolean
*/
public static function delete_linked_login($linkedloginid) {
$login = new linked_login($linkedloginid);
$userid = $login->get('userid');
if (\core\session\manager::is_loggedinas()) {
throw new moodle_exception('notwhileloggedinas', 'auth_oauth2');
}
$context = context_user::instance($userid);
require_capability('auth/oauth2:managelinkedlogins', $context);
$login->delete();
}
}

View File

@ -156,14 +156,8 @@ class auth extends \auth_plugin_base {
* @param array $userfields
*/
public function config_form($config, $err, $userfields) {
echo get_string('plugindescription', 'auth_oauth2');
include(__DIR__ . "/../config.html");
// Force all fields updated on login and locked.
foreach ($userfields as $field) {
set_config('field_updatelocal_' . $field, 'onlogin', 'auth_oauth2');
set_config('field_lock_' . $field, 'unlockedifempty', 'auth_oauth2');
}
return;
}
@ -312,6 +306,14 @@ class auth extends \auth_plugin_base {
return true;
}
public function process_config($config) {
// Set to defaults if undefined
if (!isset($config->allowlinkedlogins)) {
$config->allowlinkedlogins = false;
}
set_config('allowlinkedlogins', trim($config->allowlinkedlogins), 'auth_oauth2');
}
/**
* Complete the login process after oauth handshake is complete.
* @param \core\oauth2\client $client
@ -336,20 +338,33 @@ class auth extends \auth_plugin_base {
$userinfo['username'] = trim(core_text::strtolower($userinfo['username']));
if (!empty($userinfo['picture'])) {
$this->set_static_user_picture($userinfo['picture']);
unset($userinfo['picture']);
}
$userwasmapped = false;
if (get_config('auth_oauth2', 'allowlinkedlogins')) {
$mappeduser = api::match_username_to_user($userinfo['username'], $client->get_issuer());
if (!empty($userinfo['lang'])) {
$userinfo['lang'] = str_replace('-', '_', trim(core_text::strtolower($userinfo['lang'])));
if (!get_string_manager()->translation_exists($userinfo['lang'], false)) {
unset($userinfo['lang']);
if ($mappeduser) {
$userinfo = (array) $mappeduser;
$userwasmapped = true;
}
}
if (!$userwasmapped) {
if (!empty($userinfo['picture'])) {
$this->set_static_user_picture($userinfo['picture']);
unset($userinfo['picture']);
}
if (!empty($userinfo['lang'])) {
$userinfo['lang'] = str_replace('-', '_', trim(core_text::strtolower($userinfo['lang'])));
if (!get_string_manager()->translation_exists($userinfo['lang'], false)) {
unset($userinfo['lang']);
}
}
}
$this->set_static_user_info($userinfo);
$user = authenticate_user_login($userinfo['username'], '');
$user = get_complete_user_data('username', $userinfo['username']);
if ($user) {
complete_user_login($user);

View File

@ -0,0 +1,63 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Class for loading/storing issuers from the DB.
*
* @package core_oauth2
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_oauth2;
defined('MOODLE_INTERNAL') || die();
use core\persistent;
/**
* Class for loading/storing issuer from the DB
*
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class linked_login extends persistent {
/** @const TABLE */
const TABLE = 'auth_oauth2_linked_login';
/**
* Return the definition of the properties of this model.
*
* @return array
*/
protected static function define_properties() {
return array(
'issuerid' => array(
'type' => PARAM_INT
),
'userid' => array(
'type' => PARAM_INT
),
'username' => array(
'type' => PARAM_RAW
),
'email' => array(
'type' => PARAM_RAW
)
);
}
}

View File

@ -0,0 +1,96 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Output rendering for the plugin.
*
* @package auth_oauth2
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_oauth2\output;
use plugin_renderer_base;
use html_table;
use html_table_cell;
use html_table_row;
use html_writer;
use auth\oauth2\linked_login;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
/**
* Implements the plugin renderer
*
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends plugin_renderer_base {
/**
* This function will render one beautiful table with all the linked_logins.
*
* @param \auth\oauth2\linked_login[] $linkedlogins - list of all linked logins.
* @return string HTML to output.
*/
public function linked_logins_table($linkedlogins) {
global $CFG, $OUTPUT;
$table = new html_table();
$table->head = [
get_string('issuer', 'auth_oauth2'),
get_string('info', 'auth_oauth2'),
get_string('edit'),
];
$table->attributes['class'] = 'admintable generaltable';
$data = [];
$index = 0;
foreach ($linkedlogins as $linkedlogin) {
// Issuer.
$issuerid = $linkedlogin->get('issuerid');
$issuer = \core\oauth2\api::get_issuer($issuerid);
$issuercell = new html_table_cell(s($issuer->get('name')));
// Issuer.
$username = $linkedlogin->get('username');
$email = $linkedlogin->get('email');
$usernamecell = new html_table_cell(s($email) . ', (' . s($username) . ')');
$links = '';
// Delete.
$deleteparams = ['linkedloginid' => $linkedlogin->get('id'), 'action' => 'delete', 'sesskey' => sesskey()];
$deleteurl = new moodle_url('/auth/oauth2/linkedlogins.php', $deleteparams);
$deletelink = html_writer::link($deleteurl, $OUTPUT->pix_icon('t/delete', get_string('delete')));
$links .= ' ' . $deletelink;
$editcell = new html_table_cell($links);
$row = new html_table_row([
$issuercell,
$usernamecell,
$editcell,
]);
$data[] = $row;
$index++;
}
$table->data = $data;
return html_writer::table($table);
}
}

32
auth/oauth2/config.html Normal file
View File

@ -0,0 +1,32 @@
<!-- No config needed -->
<div style="text-align: center"><?php print_string('plugindescription', 'auth_oauth2'); ?></div>
<div class="alert alert-warning m-y-2" style="text-align: center"><?php print_string('createaccountswarning', 'auth_oauth2'); ?></div>
<?php
// Set to defaults if undefined.
if (!isset($config->allowlinkedlogins)) {
$config->allowlinkedlogins = true;
}
?>
<table cellspacing="0" cellpadding="5" border="0">
<tr valign="top" class="required">
<td align="right">
<label for="allowlinkedlogins"><?php print_string('allowlinkedlogins', 'auth_oauth2') ?></label>
</td>
<td>
<input name="allowlinkedlogins" id="allowlinkedlogins" type="checkbox"
<?php if ($config->allowlinkedlogins) { echo 'checked="checked"'; } ?>
>
<?php if (isset($err['allowlinkedlogins'])) { echo $OUTPUT->error_text($err['allowlinkedlogins']); } ?>
</td>
<td>
<?php print_string('allowlinkedloginsdesc', 'auth_oauth2') ?>
</td>
</tr>
<?php
print_auth_lock_options($this->authtype, $userfields, get_string('auth_fieldlocks_help', 'auth'), false, false);
?>
</table>

34
auth/oauth2/db/access.php Normal file
View File

@ -0,0 +1,34 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* Capability definitions for this plugin.
*
* @package auth_oauth2
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$capabilities = [
'auth/oauth2:managelinkedlogins' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_USER,
'archetypes' => array(
'user' => CAP_ALLOW
)
),
];

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="auth/oauth2/db" VERSION="20170308" COMMENT="XMLDB file for Moodle auth/oauth2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="auth_oauth2_linked_login" COMMENT="Accounts linked to a users Moodle account.">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The user account this oauth login is linked to."/>
<FIELD NAME="issuerid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="username" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The external username to map to this moodle account"/>
<FIELD NAME="email" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The external email to map to this moodle account"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="usermodified_key" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="userid_key" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="issuerid_key" TYPE="foreign" FIELDS="issuerid" REFTABLE="oauth2_issuer" REFFIELDS="id"/>
<KEY NAME="uniq_key" TYPE="unique" FIELDS="userid, issuerid, username"/>
</KEYS>
<INDEXES>
<INDEX NAME="search_index" UNIQUE="false" FIELDS="issuerid, username"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>

View File

@ -0,0 +1,74 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* OAuth2 authentication plugin upgrade code
*
* @package auth_oauth2
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* @param int $oldversion the version we are upgrading from
* @return bool result
*/
function xmldb_auth_oauth2_upgrade($oldversion) {
global $DB;
$dbman = $DB->get_manager();
// Automatically generated Moodle v3.2.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2017030700) {
// Define table auth_oauth2_linked_login to be created.
$table = new xmldb_table('auth_oauth2_linked_login');
// Adding fields to table auth_oauth2_linked_login.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('username', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
$table->add_field('email', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
// Adding keys to table auth_oauth2_linked_login.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('usermodified_key', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
$table->add_key('userid_key', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
$table->add_key('issuerid_key', XMLDB_KEY_FOREIGN, array('issuerid'), 'oauth2_issuer', array('id'));
$table->add_key('uniq_key', XMLDB_KEY_UNIQUE, array('userid', 'issuerid', 'username'));
// Adding indexes to table auth_oauth2_linked_login.
$table->add_index('search_index', XMLDB_INDEX_NOTUNIQUE, array('issuerid', 'username'));
// Conditionally launch create table for auth_oauth2_linked_login.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Oauth2 savepoint reached.
upgrade_plugin_savepoint(true, 2017030700, 'auth', 'oauth2');
}
return true;
}

View File

@ -27,3 +27,13 @@ $string['auth_oauth2settings'] = 'OAuth 2 authentication settings.';
$string['notloggedin'] = 'The login attempt failed.';
$string['plugindescription'] = 'This authentication plugin displays a list of the configured identity providers on the moodle login page. Selecting an identity provider allows users to login with their credentials from an OAuth 2 provider.';
$string['pluginname'] = 'OAuth 2';
$string['oauth2:managelinkedlogins'] = 'Manage own linked login accounts';
$string['linkedlogins'] = 'Linked logins';
$string['linkedloginshelp'] = 'Help with linked logins.';
$string['notwhileloggedinas'] = 'Linked logins cannot be managed while logged in as another user.';
$string['issuer'] = 'OAuth 2 Service';
$string['info'] = 'External account';
$string['createnewlinkedlogin'] = 'Link a new account ({$a})';
$string['allowlinkedlogins'] = 'Allow linked logins';
$string['allowlinkedloginsdesc'] = 'Linked logins allow users to link their Moodle account to another external account which they can use to login with.';
$string['createaccountswarning'] = 'This authentication plugin allows users to create accounts on your site. You may want to enable the setting "authpreventaccountcreation" if you use this plugin.';

19
auth/oauth2/lib.php Normal file
View File

@ -0,0 +1,19 @@
<?php
function auth_oauth2_extend_navigation_user_settings(navigation_node $useraccount,
stdClass $user,
context_user $context,
stdClass $course,
context_course $coursecontext) {
if (!\core\session\manager::is_loggedinas()) {
if (has_capability('auth/oauth2:managelinkedlogins', $context)) {
if (get_config('auth_oauth2', 'allowlinkedlogins')) {
$parent = $useraccount->parent->find('useraccount', navigation_node::TYPE_CONTAINER);
$thingnode = $parent->add(get_string('linkedlogins', 'auth_oauth2'), new moodle_url('/auth/oauth2/linkedlogins.php'));
}
}
}
}

View File

@ -0,0 +1,103 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* OAuth 2 Linked login configuration page.
*
* @package auth_oauth2
* @copyright 2017 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
$PAGE->set_url('/auth/oauth2/linkedlogins.php');
$PAGE->set_context(context_user::instance($USER->id));
$PAGE->set_pagelayout('admin');
$strheading = get_string('linkedlogins', 'auth_oauth2');
$PAGE->set_title($strheading);
$PAGE->set_heading($strheading);
require_login();
if (!get_config('auth_oauth2', 'allowlinkedlogins')) {
throw new moodle_exception('Linked logins are disabled.');
}
$action = optional_param('action', '', PARAM_ALPHAEXT);
if ($action == 'new') {
require_sesskey();
$issuerid = required_param('issuerid', PARAM_INT);
$issuer = \core\oauth2\api::get_issuer($issuerid);
// We do a login dance with this issuer.
$addparams = ['action' => 'new', 'issuerid' => $issuerid, 'sesskey' => sesskey()];
$addurl = new moodle_url('/auth/oauth2/linkedlogins.php', $addparams);
$client = \core\oauth2\api::get_user_oauth_client($issuer, $addurl);
if (optional_param('logout', false, PARAM_BOOL)) {
$client->log_out();
}
if (!$client->is_logged_in()) {
redirect($client->get_login_url());
}
$userinfo = $client->get_userinfo();
if (!empty($userinfo)) {
\auth_oauth2\api::link_login($userinfo, $issuer);
redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
} else {
redirect($PAGE->url, get_string('notloggedin', 'auth_oauth2'), null, \core\output\notification::NOTIFY_ERROR);
}
} else if ($action == 'delete') {
require_sesskey();
$linkedloginid = required_param('linkedloginid', PARAM_INT);
auth_oauth2\api::delete_linked_login($linkedloginid);
redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
}
$renderer = $PAGE->get_renderer('auth_oauth2');
$linkedloginid = optional_param('id', '', PARAM_RAW);
$linkedlogin = null;
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('linkedlogins', 'auth_oauth2'));
echo $OUTPUT->doc_link('Linked_Logins', get_string('linkedloginshelp', 'auth_oauth2'));
$linkedlogins = auth_oauth2\api::get_linked_logins();
echo $renderer->linked_logins_table($linkedlogins);
$issuers = \core\oauth2\api::get_all_issuers();
foreach ($issuers as $issuer) {
if (!$issuer->is_authentication_supported()) {
continue;
}
$addparams = ['action' => 'new', 'issuerid' => $issuer->get('id'), 'sesskey' => sesskey(), 'logout' => true];
$addurl = new moodle_url('/auth/oauth2/linkedlogins.php', $addparams);
echo $renderer->single_button($addurl, get_string('createnewlinkedlogin', 'auth_oauth2', s($issuer->get('name'))));
}
echo $OUTPUT->footer();

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2016120500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->version = 2017030700; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2016112900; // Requires this Moodle version
$plugin->component = 'auth_oauth2'; // Full name of the plugin (used for diagnostics)