commit 934f4ac85d40e2673af28b50ed2e7cc07ef1ed4d
Author: root <root@moodle.samba.wetron.es>
Date:   Wed Aug 11 15:45:27 2021 +0200

    auth_cas: map all defined roles and new task to sync roles (copied from auth_ldap)

diff --git a/auth/cas/auth.php b/auth/cas/auth.php
index c29c9205e81..a08cca8e3d7 100644
--- a/auth/cas/auth.php
+++ b/auth/cas/auth.php
@@ -319,6 +319,19 @@ class auth_plugin_cas extends auth_plugin_ldap {
         parent::sync_users($do_updates);
     }
 
+    /**
+     * Sync roles for this user.
+     *
+     * @param object $user The user to sync (without system magic quotes).
+     */
+    function sync_roles($user) {
+        if (empty($this->config->host_url)) {
+            error_log('[AUTH CAS] '.get_string('noldapserver', 'auth_cas'));
+            return;
+        }
+        parent::sync_roles($user);
+    }
+
     /**
     * Hook for logout page
     */
diff --git a/auth/cas/classes/task/sync_roles.php b/auth/cas/classes/task/sync_roles.php
new file mode 100644
index 00000000000..be91f6796d6
--- /dev/null
+++ b/auth/cas/classes/task/sync_roles.php
@@ -0,0 +1,61 @@
+<?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/>.
+
+/**
+ * A scheduled task for LDAP roles sync.
+ *
+ * @package    auth_ldap
+ * @author     David Balch <david.balch@conted.ox.ac.uk>
+ * @copyright  2017 The Chancellor Masters and Scholars of the University of Oxford {@link http://www.tall.ox.ac.uk}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace auth_cas\task;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * A scheduled task class for LDAP roles sync.
+ *
+ * @author     David Balch <david.balch@conted.ox.ac.uk>
+ * @copyright  2017 The Chancellor Masters and Scholars of the University of Oxford {@link http://www.tall.ox.ac.uk}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class sync_roles extends \core\task\scheduled_task {
+
+    /**
+     * Get a descriptive name for this task (shown to admins).
+     *
+     * @return string
+     */
+    public function get_name() {
+        return get_string('syncroles', 'auth_cas');
+    }
+
+    /**
+     * Synchronise role assignments from LDAP.
+     */
+    public function execute() {
+        global $DB;
+        if (is_enabled_auth('cas')) {
+            $auth = get_auth_plugin('cas');
+            $users = $DB->get_records('user', array('auth' => 'cas'));
+            foreach ($users as $user) {
+                $auth->sync_roles($user);
+            }
+        }
+    }
+
+}
diff --git a/auth/cas/db/tasks.php b/auth/cas/db/tasks.php
index 92c755cda9e..8ee8eab2405 100644
--- a/auth/cas/db/tasks.php
+++ b/auth/cas/db/tasks.php
@@ -26,6 +26,16 @@
 defined('MOODLE_INTERNAL') || die();
 
 $tasks = array(
+    array(
+        'classname' => 'auth_cas\task\sync_roles',
+        'blocking' => 0,
+        'minute' => '0',
+        'hour' => '0',
+        'day' => '*',
+        'month' => '*',
+        'dayofweek' => '*',
+        'disabled' => 1
+    ),
     array(
         'classname' => 'auth_cas\task\sync_task',
         'blocking' => 0,
diff --git a/auth/cas/lang/en/auth_cas.php b/auth/cas/lang/en/auth_cas.php
index 3e465f9a612..9f94dd33bbd 100644
--- a/auth/cas/lang/en/auth_cas.php
+++ b/auth/cas/lang/en/auth_cas.php
@@ -76,6 +76,7 @@ $string['auth_cas_version'] = 'CAS protocol version to use';
 $string['CASform'] = 'Authentication choice';
 $string['noldapserver'] = 'No LDAP server configured for CAS! Syncing disabled.';
 $string['pluginname'] = 'CAS server (SSO)';
+$string['syncroles'] = 'Synchronise system roles from CAS/LDAP';
 $string['synctask'] = 'CAS users sync job';
 $string['privacy:metadata'] = 'The CAS server (SSO) authentication plugin does not store any personal data.';
 
diff --git a/auth/cas/settings.php b/auth/cas/settings.php
index 3e7fed28981..907e60eb686 100644
--- a/auth/cas/settings.php
+++ b/auth/cas/settings.php
@@ -250,19 +250,36 @@ if ($ADMIN->fulltree) {
                 get_string('auth_ldap_objectclass_key', 'auth_ldap'),
                 get_string('auth_ldap_objectclass', 'auth_ldap'), '', PARAM_RAW_TRIMMED));
 
-        // Course Creators Header.
-        $settings->add(new admin_setting_heading('auth_cas/coursecreators',
-                new lang_string('coursecreators'), ''));
-
-        // Course creators attribute field mapping.
-        $settings->add(new admin_setting_configtext('auth_cas/attrcreators',
-                get_string('auth_ldap_attrcreators_key', 'auth_ldap'),
-                get_string('auth_ldap_attrcreators', 'auth_ldap'), '', PARAM_RAW_TRIMMED));
-
-        // Course creator group field mapping.
-        $settings->add(new admin_setting_configtext('auth_cas/groupecreators',
-                get_string('auth_ldap_groupecreators_key', 'auth_ldap'),
-                get_string('auth_ldap_groupecreators', 'auth_ldap'), '', PARAM_RAW_TRIMMED));
+        // System roles mapping header.
+        $settings->add(new admin_setting_heading('auth_cas/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_cas/role_not_mapped_' . sha1($role['settingname']), '',
+                    get_string('cannotmaprole', 'auth_ldap', $a)));
+            } else {
+                $settings->add(new admin_setting_configtext('auth_cas/' . $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_cas/syncusers',
diff --git a/auth/cas/version.php b/auth/cas/version.php
index a5f88d32c47..640103eec0c 100644
--- a/auth/cas/version.php
+++ b/auth/cas/version.php
@@ -26,7 +26,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2021051700;        // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version   = 2021051701;        // The current plugin version (Date: YYYYMMDDXX).
 $plugin->requires  = 2021051100;        // Requires this Moodle version.
 $plugin->component = 'auth_cas';        // Full name of the plugin (used for diagnostics)
 
