From 39a5325e87145e73ff70d48a81cc8a1ddb315e3a Mon Sep 17 00:00:00 2001 From: Jackson D'souza Date: Thu, 29 Feb 2024 14:04:49 +0000 Subject: [PATCH] Allow IdP to have separate config settings including field mappings --- classes/admin/setting_idpmetadata.php | 1 + classes/auth.php | 73 +++++++++-- classes/form/availableidps.php | 5 + db/install.xml | 12 ++ db/upgrade.php | 23 ++++ edit.php | 76 ++++++++++++ edit_form.php | 171 ++++++++++++++++++++++++++ lang/en/auth_saml2.php | 7 ++ locallib.php | 136 ++++++++++++++++---- version.php | 2 +- 10 files changed, 469 insertions(+), 37 deletions(-) create mode 100644 edit.php create mode 100644 edit_form.php diff --git a/classes/admin/setting_idpmetadata.php b/classes/admin/setting_idpmetadata.php index d82602206..8f200edb1 100644 --- a/classes/admin/setting_idpmetadata.php +++ b/classes/admin/setting_idpmetadata.php @@ -193,6 +193,7 @@ private function remove_old_idps($oldidps) { foreach ($oldidps as $metadataidps) { foreach ($metadataidps as $oldidp) { $DB->delete_records('auth_saml2_idps', array('id' => $oldidp->id)); + $DB->delete_records('auth_saml2_idpsettings', ['idpid' => $oldidp->id]); } } } diff --git a/classes/auth.php b/classes/auth.php index 61aaedd3e..5fad37506 100644 --- a/classes/auth.php +++ b/classes/auth.php @@ -155,6 +155,40 @@ public function __construct() { // Check if we have mutiple IdPs configured. // If we have mutliple metadata entries set multiidp to true. $this->multiidp = (count($this->metadataentities) > 1); + + // Get the list of IdPs and their mapping settings. + $this->idplist = $this->get_idp_list(); + if (isset($_GET['idp']) && !empty($_GET['idp'])) { + $selectedidp = $_GET['idp']; + if (isset($this->idplist[$selectedidp]) && !empty($this->idplist[$selectedidp])) { + foreach ($this->idplist[$selectedidp] as $key => $value) { + $this->config->$key = $value; + } + } + } + } + + /** + * Return array of all the IdPs and their configuration settings. + * + * @return array + **/ + public function get_idp_list() { + $idps = auth_saml2_get_idps(true); + $idpconfig = []; + + // Re-index the object to use shortname as the key. + foreach ($idps as $idp) { + foreach ($idp as $key => $value) { + $config = auth_saml2_get_idp_settings($value->id); + if ($config) { + $arrayconfig[$key] = $config; + } else { + $arrayconfig[$key] = []; + } + } + } + return $idpconfig; } /** @@ -260,6 +294,8 @@ public function loginpage_idp_list($wantsurl) { // The array of IdPs to return. $idplist = []; + // Get the list of IdPs and their configuration settings. + $this->idplist = $this->get_idp_list(); // Create IdP metadata url => name mapping. $idpurls = array_combine(array_column($this->metadatalist, 'idpurl'), array_column($this->metadatalist, 'idpname')); @@ -584,21 +620,16 @@ public function saml_login() { // We store the IdP in the session to generate the config/config.php array with the default local SP. $idpalias = optional_param('idpalias', '', PARAM_TEXT); if (!empty($idpalias)) { - $idpfound = false; - - foreach ($this->metadataentities as $idpentity) { - if ($idpalias == $idpentity->alias) { - $SESSION->saml2idp = $idpentity->md5entityid; - $idpfound = true; - break; - } - } - + $idpfound = $this->saml_validateidp('alias', $idpalias); if (!$idpfound) { $this->error_page(get_string('noidpfound', 'auth_saml2', $idpalias)); } } else if (isset($_GET['idp'])) { $SESSION->saml2idp = $_GET['idp']; + $idpfound = $this->saml_validateidp('md5entityid', $_GET['idp']); + if (!$idpfound) { + $this->error_page(get_string('noidpfound', 'auth_saml2', $_GET['idp'])); + } } else if (!is_null($this->defaultidp)) { $SESSION->saml2idp = $this->defaultidp->md5entityid; } else if ($this->multiidp) { @@ -635,6 +666,26 @@ public function saml_login() { $this->saml_login_complete($attributes); } + /** + * Check if valid IdP and is Active. + * + * @param string $idptype alias or md5entityid + * @param string $idp IdP Alias or IdP entity + * @return bool + */ + public function saml_validateidp(string $idptype, string $idp) { + global $SESSION; + $idpfound = false; + + foreach ($this->metadataentities as $idpentity) { + if ($idp == $idpentity->{$idptype}) { + $SESSION->saml2idp = $idpentity->md5entityid; + $idpfound = true; + break; + } + } + return $idpfound; + } /** * The user has done the SAML handshake now we can log them in @@ -974,7 +1025,7 @@ public function simplify_attr($attributes) { public function update_user_record_from_attribute_map(&$user, $attributes, $newuser= false) { global $CFG; - $mapconfig = get_config('auth_saml2'); + $mapconfig = $this->config; $allkeys = array_keys(get_object_vars($mapconfig)); $update = false; diff --git a/classes/form/availableidps.php b/classes/form/availableidps.php index 0639da3b9..f27cdf269 100644 --- a/classes/form/availableidps.php +++ b/classes/form/availableidps.php @@ -74,6 +74,11 @@ public function definition() { $mform->addElement('text', $fieldkey.'[alias]', get_string('multiidp:label:alias', 'auth_saml2')); $mform->setType($fieldkey.'[alias]', PARAM_TEXT); + // Update IdP configuration settings. + $editmappings = new \moodle_url('edit.php', ['id' => $idpentity['id']]); + $mform->addElement('static', $fieldkey.'[mapping]', + get_string('mappings', 'auth_saml2'), get_string('edit', 'auth_saml2', $editmappings)); + // Add the activeidp checkbox. $mform->addElement('advcheckbox', $fieldkey.'[activeidp]', get_string('status', 'auth_saml2'), get_string('multiidp:label:active', 'auth_saml2'), [], [false, true]); diff --git a/db/install.xml b/db/install.xml index 48b89fdde..ac479384c 100644 --- a/db/install.xml +++ b/db/install.xml @@ -37,5 +37,17 @@ + + + + + + + + + + + +
diff --git a/db/upgrade.php b/db/upgrade.php index f64dc6e8c..943ef07fe 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -410,5 +410,28 @@ function xmldb_auth_saml2_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2023100300, 'auth', 'saml2'); } + if ($oldversion < 2023100301) { + + // Define table auth_saml2_idpsettings to be created. + $table = new xmldb_table('auth_saml2_idpsettings'); + + // Adding fields to table auth_saml2_idpsettings. + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); + $table->add_field('idpid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); + $table->add_field('k', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); + $table->add_field('value', XMLDB_TYPE_TEXT, null, null, null, null, null); + + // Adding keys to table auth_saml2_idpsettings. + $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); + $table->add_key('idpid_k', XMLDB_KEY_UNIQUE, ['idpid, k']); + + // Conditionally launch create table for auth_saml2_idpsettings. + if (!$dbman->table_exists($table)) { + $dbman->create_table($table); + } + + upgrade_plugin_savepoint(true, 2023100301, 'auth', 'saml2'); + } + return true; } diff --git a/edit.php b/edit.php new file mode 100644 index 000000000..8db1ab87f --- /dev/null +++ b/edit.php @@ -0,0 +1,76 @@ +. + +/** + * Edit IdP config settings and data mappings. + * + * @package auth_saml2 + * @author Jackson D'Souza + * @copyright 2019 Catalyst IT Europe {@link http://www.catalyst-eu.net} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once('../../config.php'); +require_once('locallib.php'); +require_once('edit_form.php'); + +defined('MOODLE_INTERNAL') || die; + +$id = optional_param('id', null, PARAM_INT); +$pagetitle = get_string('editidp', 'auth_saml2'); + +$pageparams = []; +if (isset($id)) { + $pageparams['id'] = $id; +} + +$idprecord = $DB->get_record('auth_saml2_idps', $pageparams, '*', MUST_EXIST); + +$PAGE->set_pagelayout('standard'); +$PAGE->set_context(context_system::instance()); +$PAGE->set_url('/auth/saml2/edit.php', $pageparams); +$PAGE->set_title($pagetitle); +$PAGE->set_heading($pagetitle); + +$PAGE->navbar->add(get_string('administrationsite')); +$PAGE->navbar->add(get_string('plugins', 'admin')); +$PAGE->navbar->add(get_string('authentication', 'admin')); +$PAGE->navbar->add(get_string('pluginname', 'auth_saml2'), + new moodle_url('/admin/settings.php', ['section' => 'authsettingsaml2'])); +$PAGE->navbar->add(get_string('manageidpsheading', 'auth_saml2'), new moodle_url('/auth/saml2/availableidps.php')); +$PAGE->navbar->add($idprecord->displayname); +$PAGE->navbar->add($pagetitle); + +require_login(); +require_capability('moodle/site:config', context_system::instance()); + +$formparams['data'] = auth_saml2_get_idp_settings($id); +$formurl = new moodle_url($PAGE->url); +$mform = new auth_saml2_idp_edit_form($formurl, $formparams); + +// Cancelled, return to main listing view. +if ($mform->is_cancelled()) { + redirect(new moodle_url('/auth/saml2/availableidps.php')); + exit; +} else if ($formdata = $mform->get_data()) { + auth_saml2_save_idp($formdata, $id); + redirect(new moodle_url('/auth/saml2/availableidps.php')); + exit; +} + +echo $OUTPUT->header(); +$mform->display(); +echo $OUTPUT->footer(); diff --git a/edit_form.php b/edit_form.php new file mode 100644 index 000000000..57de482e3 --- /dev/null +++ b/edit_form.php @@ -0,0 +1,171 @@ +. + +/** + * Edit IdP data mappings form. + * + * @package auth_saml2 + * @author Jackson D'Souza + * @copyright 2019 Catalyst IT Europe {@link http://www.catalyst-eu.net} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use auth_saml2\admin\saml2_settings; + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir . '/formslib.php'); + +/** + * Edit IdP data mappings form. + * + * @package auth_saml2 + * @author Jackson D'souza + * @copyright 2019 Catalyst IT Europe {@link http://www.catalyst-eu.net} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class auth_saml2_idp_edit_form extends moodleform { + + /** + * Define the form for editing data mappings. + */ + public function definition() { + global $CFG; + + $mform =& $this->_form; + + $id = isset($this->_customdata['id']) ? $this->_customdata['id'] : false; + + $mform->addElement('text', 'idpattr', get_string('idpattr', 'auth_saml2'), ['size' => 40, 'maxlength' => 50]); + $mform->setType('idpattr', PARAM_TEXT); + $mform->addElement('static', 'idpattr_help', + null, + get_string('idpattr_help', 'auth_saml2')); + + // Moodle Field. + $fields = [ + 'username' => get_string('username'), + 'email' => get_string('email'), + ]; + $mform->addElement('select', 'mdlattr', get_string('mdlattr', 'auth_saml2'), $fields); + $mform->addElement('static', 'mdlattr_help', null, + get_string('mdlattr_help', 'auth_saml2')); + $mform->setDefault('mdlattr', 'username'); + + $mform->addElement('selectyesno', 'tolower', get_string('tolower', 'auth_saml2')); + $mform->addElement('static', 'tolower_help', null, + get_string('tolower_help', 'auth_saml2')); + + $mform->addElement('textarea', 'requestedattributes', get_string('requestedattributes', 'auth_saml2'), + 'wrap="virtual" rows="8" cols="50"'); + $mform->setType('requestedattributes', PARAM_TEXT); + $mform->addElement('static', 'requestedattributes_help', null, + get_string('requestedattributes_help', 'auth_saml2', + ['example' => "
+urn:mace:dir:attribute-def:eduPersonPrincipalName
+urn:mace:dir:attribute-def:mail *
"])); + $mform->setDefault('requestedattributes', ''); + + $mform->addElement('selectyesno', 'autocreate', get_string('autocreate', 'auth_saml2')); + $mform->addElement('static', 'autocreate_help', + null, + get_string('autocreate_help', 'auth_saml2')); + + $mform->addElement('textarea', 'grouprules', get_string('grouprules', 'auth_saml2'), + 'wrap="virtual" rows="8" cols="50"'); + $mform->setType('grouprules', PARAM_TEXT); + $mform->addElement('static', 'grouprules_help', null, + get_string('grouprules_help', 'auth_saml2')); + $mform->setDefault('grouprules', ''); + + $mform->addElement('text', 'alterlogout', get_string('alterlogout', 'auth_saml2'), ['size' => 40, 'maxlength' => 50]); + $mform->setType('alterlogout', PARAM_URL); + $mform->addElement('static', 'alterlogout_help', + null, + get_string('alterlogout_help', 'auth_saml2')); + + $mform->addElement('selectyesno', 'attemptsignout', get_string('attemptsignout', 'auth_saml2')); + $mform->addElement('static', 'attemptsignout_help', + null, + get_string('attemptsignout_help', 'auth_saml2')); + + $authplugin = get_auth_plugin('saml2'); + $mform->addElement('static', 'sspversion', + get_string('sspversion', 'auth_saml2'), + $authplugin->get_ssp_version()); + + $mform->addElement('html', html_writer::tag('h3', get_string('blockredirectheading', 'auth_saml2'))); + + // Flagged login response options. + $flaggedloginresponseoptions = [ + saml2_settings::OPTION_FLAGGED_LOGIN_MESSAGE => get_string('flaggedresponsetypemessage', 'auth_saml2'), + saml2_settings::OPTION_FLAGGED_LOGIN_REDIRECT => get_string('flaggedresponsetyperedirect', 'auth_saml2'), + ]; + + $mform->addElement('select', 'flagresponsetype', get_string('flagresponsetype', 'auth_saml2'), + $flaggedloginresponseoptions); + $mform->getElement('flagresponsetype')->setSelected(saml2_settings::OPTION_FLAGGED_LOGIN_REDIRECT); + $mform->addElement('static', 'flagresponsetype_help', null, + get_string('flagresponsetype_help', 'auth_saml2')); + + $mform->addElement('text', 'flagredirecturl', get_string('flagredirecturl', 'auth_saml2'), + ['size' => 40, 'maxlength' => 50]); + $mform->setType('flagredirecturl', PARAM_URL); + $mform->addElement('static', 'flagredirecturl_help', null, + get_string('flagredirecturl_help', 'auth_saml2')); + + $mform->addElement('textarea', 'flagmessage', get_string('flagmessage', 'auth_saml2'), + 'wrap="virtual" rows="3" cols="50"'); + $mform->setType('flagmessage', PARAM_TEXT); + $mform->addElement('static', 'flagmessage_help', null, + get_string('flagmessage_help', 'auth_saml2')); + $mform->setDefault('flagmessage', ''); + + // Display locking / mapping of profile fields. + $help = get_string('auth_updatelocal_expl', 'auth'); + $help .= get_string('auth_fieldlock_expl', 'auth'); + $help .= get_string('auth_updateremote_expl', 'auth'); + auth_saml2_display_auth_lock_options( + $mform, + $authplugin->authtype, + $authplugin->userfields, + $help, + true, + true, + $authplugin->get_custom_user_profile_fields(), + 'form' + ); + + if ($id !== false) { + $mform->addElement('hidden', 'id', $id); + $mform->setType('id', PARAM_INT); + } + + $this->add_action_buttons(); + + } + + /** + * Called from form method definition_after_data + * Can be overridden if more functionality is needed. + */ + public function definition_after_data() { + $mform =& $this->_form; + foreach ($this->_customdata['data'] as $key => $value) { + $mform->setDefault($key, $value); + } + } +} diff --git a/lang/en/auth_saml2.php b/lang/en/auth_saml2.php index 7c0c420e8..b7a59008f 100644 --- a/lang/en/auth_saml2.php +++ b/lang/en/auth_saml2.php @@ -228,6 +228,13 @@ deny admins=no
allow examrole=proctor
deny library=overdue
'; +// CATALYST CUSTOM START. +$string['edit'] = 'Edit'; +$string['editidp'] = 'Edit IdP'; +$string['mappings'] = 'Mappings'; +$string['metadatalink'] = 'Metadata'; +// CATALYST CUSTOM END. + /* * Privacy provider (GDPR) */ diff --git a/locallib.php b/locallib.php index bf615bba1..7e384679e 100644 --- a/locallib.php +++ b/locallib.php @@ -285,16 +285,23 @@ function auth_saml2_update_sp_metadata() { * @param boolean $mapremotefields Map fields or lock only. * @param boolean $updateremotefields Allow remote updates * @param array $customfields list of custom profile fields + * @param string $type show config setting or form fields * @since Moodle 3.3 */ -function auth_saml2_display_auth_lock_options($settings, $auth, $userfields, $helptext, $mapremotefields, $updateremotefields, $customfields = array()) { +function auth_saml2_display_auth_lock_options($settings, $auth, $userfields, $helptext, $mapremotefields, + $updateremotefields, $customfields = array(), $type = 'settings') { global $DB; // Introductory explanation and help text. - if ($mapremotefields) { - $settings->add(new admin_setting_heading($auth.'/data_mapping', new lang_string('auth_data_mapping', 'auth'), $helptext)); + if ($type == 'settings') { + if ($mapremotefields) { + $settings->add(new admin_setting_heading($auth.'/data_mapping', new lang_string('auth_data_mapping', 'auth'), $helptext)); + } else { + $settings->add(new admin_setting_heading($auth.'/auth_fieldlocks', new lang_string('auth_fieldlocks', 'auth'), $helptext)); + } } else { - $settings->add(new admin_setting_heading($auth.'/auth_fieldlocks', new lang_string('auth_fieldlocks', 'auth'), $helptext)); + $settings->addElement('html', html_writer::tag('h3', get_string('auth_data_mapping', 'auth'))); + $settings->addElement('html', $helptext); } // Generate the list of options. @@ -322,7 +329,7 @@ function auth_saml2_display_auth_lock_options($settings, $auth, $userfields, $he } else if (!empty($customfields) && in_array($field, $customfields)) { // If custom field then pick name from database. $fieldshortname = str_replace('profile_field_', '', $fieldname); - $fieldname = $customfieldname[$fieldshortname]->name; + $fieldname = format_string($customfieldname[$fieldshortname]->name); if (core_text::strlen($fieldshortname) > 67) { // If custom profile field name is longer than 67 characters we will not be able to store the setting // such as 'field_updateremote_profile_field_NOTSOSHORTSHORTNAME' in the database because the character @@ -342,28 +349,56 @@ function auth_saml2_display_auth_lock_options($settings, $auth, $userfields, $he // Display a message that the field can not be mapped because it's too long. $url = new moodle_url('/user/profile/index.php'); $a = (object)['fieldname' => s($fieldname), 'shortname' => s($field), 'charlimit' => 67, 'link' => $url->out()]; - $settings->add(new admin_setting_heading($auth.'/field_not_mapped_'.sha1($field), '', - get_string('cannotmapfield', 'auth_saml2', $a))); - } else if ($mapremotefields) { - // We are mapping to a remote field here. - // Mapping. - $settings->add(new admin_setting_configtext("auth_{$auth}/field_map_{$field}", - get_string('auth_fieldmapping', 'auth_saml2', $fieldname), '', '', PARAM_RAW, 30)); - - // Update local. - $settings->add(new admin_setting_configselect("auth_{$auth}/field_updatelocal_{$field}", - get_string('auth_updatelocalfield', 'auth_saml2', $fieldname), '', 'oncreate', $updatelocaloptions)); - - // Update remote. - if ($updateremotefields) { - $settings->add(new admin_setting_configselect("auth_{$auth}/field_updateremote_{$field}", - get_string('auth_updateremotefield', 'auth_saml2', $fieldname), '', 0, $updateextoptions)); + if ($type == 'settings') { + $settings->add(new admin_setting_heading($auth.'/field_not_mapped_'.sha1($field), '', + get_string('cannotmapfield', 'auth_saml2', $a))); + } else { + $mform->addElement('html', html_writer::tag('h3', get_string('cannotmapfield', 'auth_saml2', $a))); } + } else if ($mapremotefields) { + if ($type == 'settings') { + // We are mapping to a remote field here. + // Mapping. + $settings->add(new admin_setting_configtext("auth_{$auth}/field_map_{$field}", + get_string('auth_fieldmapping', 'auth_saml2', $fieldname), '', '', PARAM_RAW, 30)); + + // Update local. + $settings->add(new admin_setting_configselect("auth_{$auth}/field_updatelocal_{$field}", + get_string('auth_updatelocalfield', 'auth_saml2', $fieldname), '', 'oncreate', $updatelocaloptions)); + + // Update remote. + if ($updateremotefields) { + $settings->add(new admin_setting_configselect("auth_{$auth}/field_updateremote_{$field}", + get_string('auth_updateremotefield', 'auth_saml2', $fieldname), '', 0, $updateextoptions)); + } + + // Lock fields. + $settings->add(new admin_setting_configselect("auth_{$auth}/field_lock_{$field}", + get_string('auth_fieldlockfield', 'auth_saml2', $fieldname), '', 'unlocked', $lockoptions)); + } else { + // We are mapping to a remote field here. + // Mapping. + $settings->addElement('text', "field_map_{$field}", get_string('auth_fieldmapping', 'auth', $fieldname), + array('size' => 40, 'maxlength' => 30)); + $settings->setType("field_map_{$field}", PARAM_RAW); + + // Update local. + $settings->addElement('select', "field_updatelocal_{$field}", + get_string('auth_updatelocalfield', 'auth', $fieldname), $updatelocaloptions); + $settings->setDefault("field_updatelocal_{$field}", 'oncreate'); + + // Update remote. + if ($updateremotefields) { + $settings->addElement('select', "field_updateremote_{$field}", + get_string('auth_updateremotefield', 'auth', $fieldname), $updateextoptions); + } + + // Lock fields. + $settings->addElement('select', "field_lock_{$field}", get_string('auth_fieldlockfield', 'auth', $fieldname), + $lockoptions); + $settings->setDefault("field_lock_{$field}", 'unlocked'); - // Lock fields. - $settings->add(new admin_setting_configselect("auth_{$auth}/field_lock_{$field}", - get_string('auth_fieldlockfield', 'auth_saml2', $fieldname), '', 'unlocked', $lockoptions)); - + } } else { // Lock fields Only. $settings->add(new admin_setting_configselect("auth_{$auth}/field_lock_{$field}", @@ -479,6 +514,57 @@ function auth_saml2_process_regenerate_form($fromform) { return $error; } } + +/** + * Get IdP configuration settings for the selected IdP + * @param int $id IdP ID. + * @return array + */ +function auth_saml2_get_idp_settings($id) { + global $DB; + + $fields = $DB->get_records_menu('auth_saml2_idpsettings', ['idpid' => $id], null, 'k, value'); + return $fields; +} + +/** + * Save IdP settings for the selected IdP + * @param object $formdata form object + * @param int $id IdP ID. + * @return array an associative array + */ +function auth_saml2_save_idp($formdata, $id) { + global $DB; + + foreach ($formdata as $field => $value) { + // We don't want some values in the idpsettings table. + if ($field !== 'id' && $field !== 'addnew' && $field !== 'submitbutton') { + $data = new stdClass(); + $data->idpid = $id; + $data->k = $field; + $data->value = $value; + + if ($fieldid = $DB->get_field('auth_saml2_idpsettings', 'id', ['idpid' => $id, 'k' => $field])) { + $data->id = $fieldid; + $DB->update_record('auth_saml2_idpsettings', $data); + } else { + $DB->insert_record('auth_saml2_idpsettings', $data); + } + } + } + + // Check if we have multiple IdPs, and force Dual Login if we do. + if (count(auth_saml2_get_idps()) > 1) { + $duallogin = new stdClass(); + $fieldid = $DB->get_field('auth_saml2_idpsettings', 'id', ['idpid' => 0, 'k' => 'duallogin']); + $duallogin->id = $fieldid; + $duallogin->idpid = 0; + $duallogin->k = 'duallogin'; + $duallogin->value = 1; + $DB->update_record('auth_saml2_idpsettings', $duallogin); + } +} + // @codingStandardsIgnoreEnd /** diff --git a/version.php b/version.php index 3f0726d04..0bef8a790 100644 --- a/version.php +++ b/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2023100300; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2023100301; // The current plugin version (Date: YYYYMMDDXX). $plugin->release = 2023100300; // Match release exactly to version. $plugin->requires = 2017051509; // Requires PHP 7, 2017051509 = T12. M3.3 // Strictly we require either Moodle 3.5 OR