diff --git a/CHANGES.md b/CHANGES.md index fa9a53adc385c7235eba150113e4183bf9a33f60..d9ce847a4be27fe1e1a6695fe39e02f555415052 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ Changes ### Unreleased +* 2018-02-07 - Adopt code changes in Moodle 3.4 core auth_ldap: Assign arbitrary system roles via LDAP sync. * 2018-02-06 - Check compatibility for Moodle 3.4, no functionality change. ### v3.3-r1 diff --git a/README.md b/README.md index 9656639ed306c628077633038750d5441bd480a7..f92eca25ab212b5617a994f9fa19f9bf3bff6192 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,14 @@ To leverage the additional LDAP synchronization features of auth_ldap_syncplus, If you don't know how to setup LDAP User account syncronisation at all, see https://docs.moodle.org/en/LDAP_authentication#Enabling_the_LDAP_users_sync_job. +Configuring LDAP User role synchronisation +------------------------------------------ + +In addition to the LDAP user account synchronisation, there is a LDAP user role synchronisation. LDAP user role synchronisation task in auth_ldap_syncplus does not provide any benefits over the LDAP user role synchronisation in Moodle core auth_ldap yet. However, to keep things in one place and if you want to synchronize LDAP user roles, you should activate and configure the scheduled task of auth_ldap_syncplus instead of auth_ldap. This is done on Site administration -> Server -> Scheduled tasks. + +If you don't know about the LDAP user role synchronisation at all, see https://docs.moodle.org/en/LDAP_authentication#Assign_system_roles. + + Migrating from auth_ldap to auth_ldap_syncplus ---------------------------------------------- diff --git a/auth.php b/auth.php index c8258948926a00dc2761039d538fe1f78dd82f6d..475d20c379dc062b96b4708cedd606f496b097cf 100644 --- a/auth.php +++ b/auth.php @@ -32,6 +32,7 @@ global $CFG; require_once($CFG->libdir.'/authlib.php'); require_once($CFG->libdir.'/ldaplib.php'); require_once($CFG->dirroot.'/user/lib.php'); +require_once($CFG->dirroot.'/auth/ldap/locallib.php'); require_once(__DIR__.'/../ldap/auth.php'); require_once(__DIR__.'/locallib.php'); @@ -343,14 +344,6 @@ class auth_plugin_ldap_syncplus extends auth_plugin_ldap { if (!empty($users)) { mtrace(get_string('userentriestoupdate', 'auth_ldap', count($users))); - $sitecontext = context_system::instance(); - if (!empty($this->config->creators) and !empty($this->config->memberattribute) - and $roles = get_archetype_roles('coursecreator')) { - $creatorrole = array_shift($roles); // We can only use one, let's use the first one - } else { - $creatorrole = false; - } - $transaction = $DB->start_delegated_transaction(); $xcount = 0; $maxxcount = 100; @@ -365,14 +358,8 @@ class auth_plugin_ldap_syncplus extends auth_plugin_ldap { mtrace("\t".get_string('auth_dbupdatinguser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)).$skipped); $xcount++; - // Update course creators if needed - if ($creatorrole !== false) { - if ($this->iscreator($user->username)) { - role_assign($creatorrole->id, $user->id, $sitecontext->id, $this->roleauth); - } else { - role_unassign($creatorrole->id, $user->id, $sitecontext->id, $this->roleauth); - } - } + // Update system roles, if needed. + $this->sync_roles($user); } $transaction->allow_commit(); unset($users); // free mem @@ -395,14 +382,6 @@ class auth_plugin_ldap_syncplus extends auth_plugin_ldap { if (!empty($add_users)) { mtrace(get_string('userentriestoadd', 'auth_ldap', count($add_users))); - $sitecontext = context_system::instance(); - if (!empty($this->config->creators) and !empty($this->config->memberattribute) - and $roles = get_archetype_roles('coursecreator')) { - $creatorrole = array_shift($roles); // We can only use one, let's use the first one - } else { - $creatorrole = false; - } - $transaction = $DB->start_delegated_transaction(); foreach ($add_users as $user) { $user = $this->get_userinfo_asobj($user->username); @@ -436,14 +415,12 @@ class auth_plugin_ldap_syncplus extends auth_plugin_ldap { set_user_preference('auth_forcepasswordchange', 1, $id); } - // Add course creators if needed - if ($creatorrole !== false and $this->iscreator($user->username)) { - role_assign($creatorrole->id, $id, $sitecontext->id, $this->roleauth); - } - // Save custom profile fields. $updatekeys = $this->get_profile_keys(true); $this->update_user_record($user->username, $updatekeys, false); + + // Add roles if needed. + $this->sync_roles($euser); } $transaction->allow_commit(); unset($add_users); // free mem diff --git a/db/tasks.php b/db/tasks.php index 0924af35c3768ceb182872ca574f4a1e1e1d2176..33fece1bf5e7f046f04d82b5945ecc224acd3b75 100644 --- a/db/tasks.php +++ b/db/tasks.php @@ -25,6 +25,16 @@ defined('MOODLE_INTERNAL') || die(); $tasks = array( + array( + 'classname' => 'auth_ldap_syncplus\task\sync_roles', + 'blocking' => 0, + 'minute' => '0', + 'hour' => '0', + 'day' => '*', + 'month' => '*', + 'dayofweek' => '*', + 'disabled' => 1 + ), array( 'classname' => 'auth_ldap_syncplus\task\sync_task', 'blocking' => 0, diff --git a/db/upgrade.php b/db/upgrade.php index 26aa06dca914d8d1b02999f341ab0c1fc3134e73..69a9e11986ef084cb4f431a0f4931479b7e12af4 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -39,5 +39,20 @@ function xmldb_auth_ldap_syncplus_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2018020200, 'auth', 'ldap_syncplus'); } + if ($oldversion < 2018020601) { + // The "auth_ldap_syncplus/coursecreators" setting was replaced with "auth_ldap_syncplus/coursecreatorcontext" (created + // dynamically from system-assignable roles) - so migrate any existing value to the first new slot. + if ($ldapcontext = get_config('auth_ldap_syncplus', 'creators')) { + // Get info about the role that the old coursecreators setting would apply. + $creatorrole = get_archetype_roles('coursecreator'); + $creatorrole = array_shift($creatorrole); // We can only use one, let's use the first. + // Create new setting. + set_config($creatorrole->shortname . 'context', $ldapcontext, 'auth_ldap_syncplus'); + // Delete old setting. + set_config('creators', null, 'auth_ldap_syncplus'); + upgrade_plugin_savepoint(true, 2018020601, 'auth', 'ldap_syncplus'); + } + } + return true; } diff --git a/lang/en/auth_ldap_syncplus.php b/lang/en/auth_ldap_syncplus.php index 6b83183efa67d7fbaef693a6846487314e2ca3ec..977f18b61e0ce26edcb56d8ad5475a29a9e52aa5 100644 --- a/lang/en/auth_ldap_syncplus.php +++ b/lang/en/auth_ldap_syncplus.php @@ -34,6 +34,7 @@ $string['removeuser_graceperiod'] = 'Fully deleting grace period'; $string['removeuser_graceperiod_desc'] = 'After suspending a user internally, the synchronization script will wait for this number of days until the user will be fully deleted internal. If the user re-appears in LDAP within this grace period, the user will be reactivated. Note: This setting is only used if "Removed ext user" is set to "Suspend internal and fully delete internal after grace period"'; $string['sync_script_createuser_enabled'] = 'If enabled (default), the synchronization script will create Moodle accounts for all LDAP users if they have never logged into Moodle before. If disabled, the synchronization script will not create Moodle accounts for all LDAP users.'; $string['sync_script_createuser_enabled_key'] = 'Add new users'; +$string['syncroles'] = 'LDAP roles sync job (Sync Plus)'; $string['synctask'] = 'LDAP users sync job (Sync Plus)'; $string['userentriestosuspend'] = 'User entries to be suspended: {$a}'; $string['waitinginremovalqueue'] = 'Waiting in removal queue for {$a->days} day grace period: {$a->name} ID {$a->id}'; diff --git a/settings.php b/settings.php index eaf788114f799708ac9f6af999efb7d258e960c6..b552ce3ee023d22ee2b44e836d66ce3cce27dd62 100644 --- a/settings.php +++ b/settings.php @@ -241,14 +241,35 @@ if ($ADMIN->fulltree) { get_string('auth_ldap_create_context_key', 'auth_ldap'), get_string('auth_ldap_create_context', 'auth_ldap'), '', PARAM_RAW_TRIMMED)); - // Course Creators Header. - $settings->add(new admin_setting_heading('auth_ldap_syncplus/coursecreators', - new lang_string('coursecreators'), '')); - - // Course creators field mapping. - $settings->add(new admin_setting_configtext('auth_ldap_syncplus/creators', - get_string('auth_ldap_creators_key', 'auth_ldap'), - get_string('auth_ldap_creators', 'auth_ldap'), '', PARAM_RAW_TRIMMED)); + // System roles mapping header. + $settings->add(new admin_setting_heading('auth_ldap_syncplus/systemrolemapping', + new lang_string('systemrolemapping', 'auth_ldap'), '')); + + // Create system role mapping field for each assignable system role. + $roles = get_ldap_assignable_role_names(); + foreach ($roles as $role) { + // Before we can add this setting we need to check a few things. + // A) It does not exceed 100 characters otherwise it will break the DB as the 'name' field + // in the 'config_plugins' table is a varchar(100). + // B) The setting name does not contain hyphens. If it does then it will fail the check + // in parse_setting_name() and everything will explode. Role short names are validated + // against PARAM_ALPHANUMEXT which is similar to the regex used in parse_setting_name() + // except it also allows hyphens. + // Instead of shortening the name and removing/replacing the hyphens we are showing a warning. + // If we were to manipulate the setting name by removing the hyphens we may get conflicts, eg + // 'thisisashortname' and 'this-is-a-short-name'. The same applies for shortening the setting name. + if (core_text::strlen($role['settingname']) > 100 || !preg_match('/^[a-zA-Z0-9_]+$/', $role['settingname'])) { + $url = new moodle_url('/admin/roles/define.php', array('action' => 'edit', 'roleid' => $role['id'])); + $a = (object)['rolename' => $role['localname'], 'shortname' => $role['shortname'], 'charlimit' => 93, + 'link' => $url->out()]; + $settings->add(new admin_setting_heading('auth_ldap_syncplus/role_not_mapped_' . sha1($role['settingname']), '', + get_string('cannotmaprole', 'auth_ldap', $a))); + } else { + $settings->add(new admin_setting_configtext('auth_ldap_syncplus/' . $role['settingname'], + get_string('auth_ldap_rolecontext', 'auth_ldap', $role), + get_string('auth_ldap_rolecontext_help', 'auth_ldap', $role), '', PARAM_RAW_TRIMMED)); + } + } // User Account Sync. $settings->add(new admin_setting_heading('auth_ldap_syncplus/syncusers', diff --git a/version.php b/version.php index 339c38395932b9c9981cdadc25163a7f6915e10a..c84079cd313fae347d5fd6132a4bcb7a422865c5 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'auth_ldap_syncplus'; -$plugin->version = 2018020600; +$plugin->version = 2018020601; $plugin->release = 'v3.3-r1'; $plugin->requires = 2017111300; $plugin->maturity = MATURITY_STABLE;