From db16fae43a1dab1c4be8f76082beffb370291bff Mon Sep 17 00:00:00 2001 From: Daniel Ziegenberg Date: Thu, 23 Jan 2025 15:39:02 +0100 Subject: [PATCH] MDL-84652 auth_mnet: Remove auth_mnet from Moodle 5.0 Original issue: MDL-84307 Signed-off-by: Daniel Ziegenberg --- .upgradenotes/MDL-84307-2025012314381722.yml | 5 + auth/mnet/auth.php | 1207 ------------------ auth/mnet/classes/privacy/provider.php | 273 ---- auth/mnet/classes/task/cron_task.php | 47 - auth/mnet/db/install.php | 6 - auth/mnet/db/mnet.php | 65 - auth/mnet/db/tasks.php | 34 - auth/mnet/db/upgrade.php | 44 - auth/mnet/jump.php | 70 - auth/mnet/land.php | 69 - auth/mnet/lang/en/auth_mnet.php | 96 -- auth/mnet/settings.php | 39 - auth/mnet/tests/privacy/provider_test.php | 333 ----- auth/mnet/upgrade.txt | 16 - auth/mnet/version.php | 29 - lib/db/upgrade.php | 9 + version.php | 2 +- 17 files changed, 15 insertions(+), 2329 deletions(-) create mode 100644 .upgradenotes/MDL-84307-2025012314381722.yml delete mode 100644 auth/mnet/auth.php delete mode 100644 auth/mnet/classes/privacy/provider.php delete mode 100644 auth/mnet/classes/task/cron_task.php delete mode 100644 auth/mnet/db/install.php delete mode 100644 auth/mnet/db/mnet.php delete mode 100644 auth/mnet/db/tasks.php delete mode 100644 auth/mnet/db/upgrade.php delete mode 100644 auth/mnet/jump.php delete mode 100644 auth/mnet/land.php delete mode 100644 auth/mnet/lang/en/auth_mnet.php delete mode 100644 auth/mnet/settings.php delete mode 100644 auth/mnet/tests/privacy/provider_test.php delete mode 100644 auth/mnet/upgrade.txt delete mode 100644 auth/mnet/version.php diff --git a/.upgradenotes/MDL-84307-2025012314381722.yml b/.upgradenotes/MDL-84307-2025012314381722.yml new file mode 100644 index 00000000000..cf44902e59a --- /dev/null +++ b/.upgradenotes/MDL-84307-2025012314381722.yml @@ -0,0 +1,5 @@ +issueNumber: MDL-84307 +notes: + core_auth: + - message: Removed auth_mnet plugin from core + type: removed diff --git a/auth/mnet/auth.php b/auth/mnet/auth.php deleted file mode 100644 index f5060d5ab6b..00000000000 --- a/auth/mnet/auth.php +++ /dev/null @@ -1,1207 +0,0 @@ -. - -/** - * Authentication Plugin: Moodle Network Authentication - * Multiple host authentication support for Moodle Network. - * - * @package auth_mnet - * @author Martin Dougiamas - * @license http://www.gnu.org/copyleft/gpl.html GNU Public License - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->libdir.'/authlib.php'); - -/** - * Moodle Network authentication plugin. - */ -class auth_plugin_mnet extends auth_plugin_base { - - /** @var mnet_environment mnet environment. */ - protected $mnet; - - /** - * Constructor. - */ - public function __construct() { - $this->authtype = 'mnet'; - $this->config = get_config('auth_mnet'); - $this->mnet = get_mnet_environment(); - } - - /** - * Old syntax of class constructor. Deprecated in PHP7. - * - * @deprecated since Moodle 3.1 - */ - public function auth_plugin_mnet() { - debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); - self::__construct(); - } - - /** - * This function is normally used to determine if the username and password - * are correct for local logins. Always returns false, as local users do not - * need to login over mnet xmlrpc. - * - * @param string $username The username - * @param string $password The password - * @return bool Authentication success or failure. - */ - function user_login($username, $password) { - return false; // Throw moodle_exception("mnetlocal"). - } - - /** - * Return user data for the provided token, compare with user_agent string. - * - * @param string $token The unique ID provided by remotehost. - * @param string $useragent User Agent string. - * @return array $userdata Array of user info for remote host - */ - function user_authorise($token, $useragent) { - global $CFG, $SITE, $DB; - $remoteclient = get_mnet_remote_client(); - require_once $CFG->dirroot . '/mnet/xmlrpc/serverlib.php'; - - $mnet_session = $DB->get_record('mnet_session', array('token'=>$token, 'useragent'=>$useragent)); - if (empty($mnet_session)) { - throw new mnet_server_exception(1, 'authfail_nosessionexists'); - } - - // check session confirm timeout - if ($mnet_session->confirm_timeout < time()) { - throw new mnet_server_exception(2, 'authfail_sessiontimedout'); - } - - // session okay, try getting the user - if (!$user = $DB->get_record('user', array('id'=>$mnet_session->userid))) { - throw new mnet_server_exception(3, 'authfail_usermismatch'); - } - - $userdata = mnet_strip_user((array)$user, mnet_fields_to_send($remoteclient)); - - // extra special ones - $userdata['auth'] = 'mnet'; - $userdata['wwwroot'] = $this->mnet->wwwroot; - $userdata['session.gc_maxlifetime'] = ini_get('session.gc_maxlifetime'); - - if (array_key_exists('picture', $userdata) && !empty($user->picture)) { - $fs = get_file_storage(); - $usercontext = context_user::instance($user->id, MUST_EXIST); - if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.png')) { - $userdata['_mnet_userpicture_timemodified'] = $usericonfile->get_timemodified(); - $userdata['_mnet_userpicture_mimetype'] = $usericonfile->get_mimetype(); - } else if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.jpg')) { - $userdata['_mnet_userpicture_timemodified'] = $usericonfile->get_timemodified(); - $userdata['_mnet_userpicture_mimetype'] = $usericonfile->get_mimetype(); - } - } - - $userdata['myhosts'] = array(); - if ($courses = enrol_get_users_courses($user->id, false)) { - $userdata['myhosts'][] = array('name'=> $SITE->shortname, 'url' => $CFG->wwwroot, 'count' => count($courses)); - } - - $sql = "SELECT h.name AS hostname, h.wwwroot, h.id AS hostid, - COUNT(c.id) AS count - FROM {mnetservice_enrol_courses} c - JOIN {mnetservice_enrol_enrolments} e ON (e.hostid = c.hostid AND e.remotecourseid = c.remoteid) - JOIN {mnet_host} h ON h.id = c.hostid - WHERE e.userid = ? AND c.hostid = ? - GROUP BY h.name, h.wwwroot, h.id"; - - if ($courses = $DB->get_records_sql($sql, array($user->id, $remoteclient->id))) { - foreach($courses as $course) { - $userdata['myhosts'][] = array('name'=> $course->hostname, 'url' => $CFG->wwwroot.'/auth/mnet/jump.php?hostid='.$course->hostid, 'count' => $course->count); - } - } - - return $userdata; - } - - /** - * Generate a random string for use as an RPC session token. - */ - function generate_token() { - return sha1(str_shuffle('' . mt_rand() . time())); - } - - /** - * Starts an RPC jump session and returns the jump redirect URL. - * - * @param int $mnethostid id of the mnet host to jump to - * @param string $wantsurl url to redirect to after the jump (usually on remote system) - * @param boolean $wantsurlbackhere defaults to false, means that the remote system should bounce us back here - * rather than somewhere inside *its* wwwroot - */ - function start_jump_session($mnethostid, $wantsurl, $wantsurlbackhere=false) { - global $CFG, $USER, $DB; - require_once $CFG->dirroot . '/mnet/xmlrpc/client.php'; - - if (\core\session\manager::is_loggedinas()) { - throw new \moodle_exception('notpermittedtojumpas', 'mnet'); - } - - // check remote login permissions - if (! has_capability('moodle/site:mnetlogintoremote', context_system::instance()) - or is_mnet_remote_user($USER) - or isguestuser() - or !isloggedin()) { - throw new \moodle_exception('notpermittedtojump', 'mnet'); - } - - // check for SSO publish permission first - if ($this->has_service($mnethostid, 'sso_sp') == false) { - throw new \moodle_exception('hostnotconfiguredforsso', 'mnet'); - } - - // set RPC timeout to 30 seconds if not configured - if (empty($this->config->rpc_negotiation_timeout)) { - $this->config->rpc_negotiation_timeout = 30; - set_config('rpc_negotiation_timeout', '30', 'auth_mnet'); - } - - // get the host info - $mnet_peer = new mnet_peer(); - $mnet_peer->set_id($mnethostid); - - // set up the session - $mnet_session = $DB->get_record('mnet_session', - array('userid'=>$USER->id, 'mnethostid'=>$mnethostid, - 'useragent'=>sha1($_SERVER['HTTP_USER_AGENT']))); - if ($mnet_session == false) { - $mnet_session = new stdClass(); - $mnet_session->mnethostid = $mnethostid; - $mnet_session->userid = $USER->id; - $mnet_session->username = $USER->username; - $mnet_session->useragent = sha1($_SERVER['HTTP_USER_AGENT']); - $mnet_session->token = $this->generate_token(); - $mnet_session->confirm_timeout = time() + $this->config->rpc_negotiation_timeout; - $mnet_session->expires = time() + (integer)ini_get('session.gc_maxlifetime'); - $mnet_session->session_id = session_id(); - $mnet_session->id = $DB->insert_record('mnet_session', $mnet_session); - } else { - $mnet_session->useragent = sha1($_SERVER['HTTP_USER_AGENT']); - $mnet_session->token = $this->generate_token(); - $mnet_session->confirm_timeout = time() + $this->config->rpc_negotiation_timeout; - $mnet_session->expires = time() + (integer)ini_get('session.gc_maxlifetime'); - $mnet_session->session_id = session_id(); - $DB->update_record('mnet_session', $mnet_session); - } - - // construct the redirection URL - //$transport = mnet_get_protocol($mnet_peer->transport); - $wantsurl = urlencode($wantsurl); - $url = "{$mnet_peer->wwwroot}{$mnet_peer->application->sso_land_url}?token={$mnet_session->token}&idp={$this->mnet->wwwroot}&wantsurl={$wantsurl}"; - if ($wantsurlbackhere) { - $url .= '&remoteurl=1'; - } - - return $url; - } - - /** - * This function confirms the remote (ID provider) host's mnet session - * by communicating the token and UA over the XMLRPC transport layer, and - * returns the local user record on success. - * - * @param string $token The random session token. - * @param mnet_peer $remotepeer The ID provider mnet_peer object. - * @return array The local user record. - */ - function confirm_mnet_session($token, $remotepeer) { - global $CFG, $DB; - require_once $CFG->dirroot . '/mnet/xmlrpc/client.php'; - require_once $CFG->libdir . '/gdlib.php'; - require_once($CFG->dirroot.'/user/lib.php'); - - // verify the remote host is configured locally before attempting RPC call - if (! $remotehost = $DB->get_record('mnet_host', array('wwwroot' => $remotepeer->wwwroot, 'deleted' => 0))) { - throw new \moodle_exception('notpermittedtoland', 'mnet'); - } - - // set up the RPC request - $mnetrequest = new mnet_xmlrpc_client(); - $mnetrequest->set_method('auth/mnet/auth.php/user_authorise'); - - // set $token and $useragent parameters - $mnetrequest->add_param($token); - $mnetrequest->add_param(sha1($_SERVER['HTTP_USER_AGENT'])); - - // Thunderbirds are go! Do RPC call and store response - if ($mnetrequest->send($remotepeer) === true) { - $remoteuser = (object) $mnetrequest->response; - } else { - foreach ($mnetrequest->error as $errormessage) { - list($code, $message) = array_map('trim',explode(':', $errormessage, 2)); - if($code == 702) { - $site = get_site(); - throw new \moodle_exception('mnet_session_prohibited', 'mnet', $remotepeer->wwwroot, - format_string($site->fullname)); - exit; - } - $message .= "ERROR $code:
$errormessage
"; - } - throw new \moodle_exception("rpcerror", '', '', $message); - } - unset($mnetrequest); - - if (empty($remoteuser) or empty($remoteuser->username)) { - throw new \moodle_exception('unknownerror', 'mnet'); - exit; - } - - if (user_not_fully_set_up($remoteuser, false)) { - throw new \moodle_exception('notenoughidpinfo', 'mnet'); - exit; - } - - $remoteuser = mnet_strip_user($remoteuser, mnet_fields_to_import($remotepeer)); - - $remoteuser->auth = 'mnet'; - $remoteuser->wwwroot = $remotepeer->wwwroot; - - // the user may roam from Moodle 1.x where lang has _utf8 suffix - // also, make sure that the lang is actually installed, otherwise set site default - if (isset($remoteuser->lang)) { - $remoteuser->lang = clean_param(str_replace('_utf8', '', $remoteuser->lang), PARAM_LANG); - } - - $firsttime = false; - - // get the local record for the remote user - $localuser = $DB->get_record('user', array('username'=>$remoteuser->username, 'mnethostid'=>$remotehost->id)); - - // add the remote user to the database if necessary, and if allowed - // TODO: refactor into a separate function - if (empty($localuser) || ! $localuser->id) { - /* - if (empty($this->config->auto_add_remote_users)) { - throw new \moodle_exception('nolocaluser', 'mnet'); - } See MDL-21327 for why this is commented out - */ - $remoteuser->mnethostid = $remotehost->id; - $remoteuser->firstaccess = 0; - $remoteuser->confirmed = 1; - - $remoteuser->id = user_create_user($remoteuser, false); - $firsttime = true; - $localuser = $remoteuser; - } - - // check sso access control list for permission first - if (!$this->can_login_remotely($localuser->username, $remotehost->id)) { - throw new \moodle_exception('sso_mnet_login_refused', 'mnet', '', - array('user' => $localuser->username, 'host' => $remotehost->name)); - } - - $fs = get_file_storage(); - - // update the local user record with remote user data - foreach ((array) $remoteuser as $key => $val) { - - if ($key == '_mnet_userpicture_timemodified' and empty($CFG->disableuserimages) and isset($remoteuser->picture)) { - // update the user picture if there is a newer verion at the identity provider - $usercontext = context_user::instance($localuser->id, MUST_EXIST); - if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.png')) { - $localtimemodified = $usericonfile->get_timemodified(); - } else if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.jpg')) { - $localtimemodified = $usericonfile->get_timemodified(); - } else { - $localtimemodified = 0; - } - - if (!empty($val) and $localtimemodified < $val) { - mnet_debug('refetching the user picture from the identity provider host'); - $fetchrequest = new mnet_xmlrpc_client(); - $fetchrequest->set_method('auth/mnet/auth.php/fetch_user_image'); - $fetchrequest->add_param($localuser->username); - if ($fetchrequest->send($remotepeer) === true) { - if (strlen($fetchrequest->response['f1']) > 0) { - $imagefilename = $CFG->tempdir . '/mnet-usericon-' . $localuser->id; - $imagecontents = base64_decode($fetchrequest->response['f1']); - file_put_contents($imagefilename, $imagecontents); - if ($newrev = process_new_icon($usercontext, 'user', 'icon', 0, $imagefilename)) { - $localuser->picture = $newrev; - } - unlink($imagefilename); - } - // note that since Moodle 2.0 we ignore $fetchrequest->response['f2'] - // the mimetype information provided is ignored and the type of the file is detected - // by process_new_icon() - } - } - } - - if($key == 'myhosts') { - $localuser->mnet_foreign_host_array = array(); - foreach($val as $rhost) { - $name = clean_param($rhost['name'], PARAM_ALPHANUM); - $url = clean_param($rhost['url'], PARAM_URL); - $count = clean_param($rhost['count'], PARAM_INT); - $url_is_local = stristr($url , $CFG->wwwroot); - if (!empty($name) && !empty($count) && empty($url_is_local)) { - $localuser->mnet_foreign_host_array[] = array('name' => $name, - 'url' => $url, - 'count' => $count); - } - } - } - - $localuser->{$key} = $val; - } - - $localuser->mnethostid = $remotepeer->id; - user_update_user($localuser, false); - - if (!$firsttime) { - // repeat customer! let the IDP know about enrolments - // we have for this user. - // set up the RPC request - $mnetrequest = new mnet_xmlrpc_client(); - $mnetrequest->set_method('auth/mnet/auth.php/update_enrolments'); - - // pass username and an assoc array of "my courses" - // with info so that the IDP can maintain mnetservice_enrol_enrolments - $mnetrequest->add_param($remoteuser->username); - $fields = 'id, category, sortorder, fullname, shortname, idnumber, summary, startdate, visible'; - $courses = enrol_get_users_courses($localuser->id, false, $fields); - if (is_array($courses) && !empty($courses)) { - // Second request to do the JOINs that we'd have done - // inside enrol_get_users_courses() if we had been allowed - $sql = "SELECT c.id, - cc.name AS cat_name, cc.description AS cat_description - FROM {course} c - JOIN {course_categories} cc ON c.category = cc.id - WHERE c.id IN (" . join(',',array_keys($courses)) . ')'; - $extra = $DB->get_records_sql($sql); - - $keys = array_keys($courses); - $studentroles = get_archetype_roles('student'); - if (!empty($studentroles)) { - $defaultrole = reset($studentroles); - //$defaultrole = get_default_course_role($ccache[$shortname]); //TODO: rewrite this completely, there is no default course role any more!!! - foreach ($keys AS $id) { - if ($courses[$id]->visible == 0) { - unset($courses[$id]); - continue; - } - $courses[$id]->cat_id = $courses[$id]->category; - $courses[$id]->defaultroleid = $defaultrole->id; - unset($courses[$id]->category); - unset($courses[$id]->visible); - - $courses[$id]->cat_name = $extra[$id]->cat_name; - $courses[$id]->cat_description = $extra[$id]->cat_description; - $courses[$id]->defaultrolename = $defaultrole->name; - // coerce to array - $courses[$id] = (array)$courses[$id]; - } - } else { - throw new moodle_exception('unknownrole', 'error', '', 'student'); - } - } else { - // if the array is empty, send it anyway - // we may be clearing out stale entries - $courses = array(); - } - $mnetrequest->add_param($courses, 'array'); - - // Call 0800-RPC Now! -- we don't care too much if it fails - // as it's just informational. - if ($mnetrequest->send($remotepeer) === false) { - // error_log(print_r($mnetrequest->error,1)); - } - } - - return $localuser; - } - - - /** - * creates (or updates) the mnet session once - * {@see confirm_mnet_session} and {@see complete_user_login} have both been called - * - * @param stdclass $user the local user (must exist already - * @param string $token the jump/land token - * @param mnet_peer $remotepeer the mnet_peer object of this users's idp - */ - public function update_mnet_session($user, $token, $remotepeer) { - global $DB; - $session_gc_maxlifetime = 1440; - if (isset($user->session_gc_maxlifetime)) { - $session_gc_maxlifetime = $user->session_gc_maxlifetime; - } - if (!$mnet_session = $DB->get_record('mnet_session', - array('userid'=>$user->id, 'mnethostid'=>$remotepeer->id, - 'useragent'=>sha1($_SERVER['HTTP_USER_AGENT'])))) { - $mnet_session = new stdClass(); - $mnet_session->mnethostid = $remotepeer->id; - $mnet_session->userid = $user->id; - $mnet_session->username = $user->username; - $mnet_session->useragent = sha1($_SERVER['HTTP_USER_AGENT']); - $mnet_session->token = $token; // Needed to support simultaneous sessions - // and preserving DB rec uniqueness - $mnet_session->confirm_timeout = time(); - $mnet_session->expires = time() + (integer)$session_gc_maxlifetime; - $mnet_session->session_id = session_id(); - $mnet_session->id = $DB->insert_record('mnet_session', $mnet_session); - } else { - $mnet_session->expires = time() + (integer)$session_gc_maxlifetime; - $DB->update_record('mnet_session', $mnet_session); - } - } - - - - /** - * Invoke this function _on_ the IDP to update it with enrolment info local to - * the SP right after calling user_authorise() - * - * Normally called by the SP after calling user_authorise() - * - * @param string $username The username - * @param array $courses Assoc array of courses following the structure of mnetservice_enrol_courses - * @return bool - */ - function update_enrolments($username, $courses) { - global $CFG, $DB; - $remoteclient = get_mnet_remote_client(); - - if (empty($username) || !is_array($courses)) { - return false; - } - // make sure it is a user we have an in active session - // with that host... - $mnetsessions = $DB->get_records('mnet_session', array('username' => $username, 'mnethostid' => $remoteclient->id), '', 'id, userid'); - $userid = null; - foreach ($mnetsessions as $mnetsession) { - if (is_null($userid)) { - $userid = $mnetsession->userid; - continue; - } - if ($userid != $mnetsession->userid) { - throw new mnet_server_exception(3, 'authfail_usermismatch'); - } - } - - if (empty($courses)) { // no courses? clear out quickly - $DB->delete_records('mnetservice_enrol_enrolments', array('hostid'=>$remoteclient->id, 'userid'=>$userid)); - return true; - } - - // IMPORTANT: Ask for remoteid as the first element in the query, so - // that the array that comes back is indexed on the same field as the - // array that we have received from the remote client - $sql = "SELECT c.remoteid, c.id, c.categoryid AS cat_id, c.categoryname AS cat_name, c.sortorder, - c.fullname, c.shortname, c.idnumber, c.summary, c.summaryformat, c.startdate, - e.id AS enrolmentid - FROM {mnetservice_enrol_courses} c - LEFT JOIN {mnetservice_enrol_enrolments} e ON (e.hostid = c.hostid AND e.remotecourseid = c.remoteid AND e.userid = ?) - WHERE c.hostid = ?"; - - $currentcourses = $DB->get_records_sql($sql, array($userid, $remoteclient->id)); - - $keepenrolments = array(); - foreach($courses as $ix => $course) { - - $course['remoteid'] = $course['id']; - $course['hostid'] = (int)$remoteclient->id; - $userisregd = false; - - // if we do not have the the information about the remote course, it is not available - // to us for remote enrolment - skip - if (array_key_exists($course['remoteid'], $currentcourses)) { - // We are going to keep this enrolment, it will be updated or inserted, but will keep it. - $keepenrolments[] = $course['id']; - - // Pointer to current course: - $currentcourse =& $currentcourses[$course['remoteid']]; - - $saveflag = false; - - foreach($course as $key => $value) { - // Only compare what is available locally, data coming from enrolment tables have - // way more information that tables used to keep the track of mnet enrolments. - if (!property_exists($currentcourse, $key)) { - continue; - } - // Don't compare ids either, they come from different databases. - if ($key === 'id') { - continue; - } - - if ($currentcourse->$key != $value) { - $saveflag = true; - $currentcourse->$key = $value; - } - } - - if ($saveflag) { - $DB->update_record('mnetservice_enrol_courses', $currentcourse); - } - - if (isset($currentcourse->enrolmentid) && is_numeric($currentcourse->enrolmentid)) { - $userisregd = true; - } - } else { - unset ($courses[$ix]); - continue; - } - - // Do we have a record for this assignment? - if ($userisregd) { - // Yes - we know about this one already - // We don't want to do updates because the new data is probably - // 'less complete' than the data we have. - } else { - // No - create a record - $newenrol = new stdClass(); - $newenrol->userid = $userid; - $newenrol->hostid = (int)$remoteclient->id; - $newenrol->remotecourseid = $course['remoteid']; - $newenrol->rolename = $course['defaultrolename']; - $newenrol->enroltype = 'mnet'; - $newenrol->id = $DB->insert_record('mnetservice_enrol_enrolments', $newenrol); - } - } - - // Clean up courses that the user is no longer enrolled in. - list($insql, $inparams) = $DB->get_in_or_equal($keepenrolments, SQL_PARAMS_NAMED, 'param', false, null); - $whereclause = ' userid = :userid AND hostid = :hostid AND remotecourseid ' . $insql; - $params = array_merge(['userid' => $userid, 'hostid' => $remoteclient->id], $inparams); - $DB->delete_records_select('mnetservice_enrol_enrolments', $whereclause, $params); - } - - function prevent_local_passwords() { - return true; - } - - /** - * Returns true if this authentication plugin is 'internal'. - * - * @return bool - */ - function is_internal() { - return false; - } - - /** - * Returns true if this authentication plugin can change the user's - * password. - * - * @return bool - */ - function can_change_password() { - //TODO: it should be able to redirect, right? - return false; - } - - /** - * Returns the URL for changing the user's pw, or false if the default can - * be used. - * - * @return moodle_url - */ - function change_password_url() { - return null; - } - - /** - * Poll the IdP server to let it know that a user it has authenticated is still - * online - * - * @return void - */ - function keepalive_client() { - global $CFG, $DB; - $cutoff = time() - 300; // TODO - find out what the remote server's session - // cutoff is, and preempt that - - $sql = " - select - id, - username, - mnethostid - from - {user} - where - lastaccess > ? AND - mnethostid != ? - order by - mnethostid"; - - $immigrants = $DB->get_records_sql($sql, array($cutoff, $CFG->mnet_localhost_id)); - - if ($immigrants == false) { - return true; - } - - $usersArray = array(); - foreach($immigrants as $immigrant) { - $usersArray[$immigrant->mnethostid][] = $immigrant->username; - } - - require_once $CFG->dirroot . '/mnet/xmlrpc/client.php'; - foreach($usersArray as $mnethostid => $users) { - $mnet_peer = new mnet_peer(); - $mnet_peer->set_id($mnethostid); - - $mnet_request = new mnet_xmlrpc_client(); - $mnet_request->set_method('auth/mnet/auth.php/keepalive_server'); - - // set $token and $useragent parameters - $mnet_request->add_param($users); - - if ($mnet_request->send($mnet_peer) === true) { - if (!isset($mnet_request->response['code'])) { - debugging("Server side error has occured on host $mnethostid"); - continue; - } elseif ($mnet_request->response['code'] > 0) { - debugging($mnet_request->response['message']); - } - - if (!isset($mnet_request->response['last log id'])) { - debugging("Server side error has occured on host $mnethostid\nNo log ID was received."); - continue; - } - } else { - debugging("Server side error has occured on host $mnethostid: " . - join("\n", $mnet_request->error)); - break; - } - } - } - - /** - * Receives an array of log entries from an SP and adds them to the mnet_log - * table - * - * @deprecated since Moodle 2.8 Please don't use this function for recording mnet logs. - * @param array $array An array of usernames - * @return string "All ok" or an error message - */ - function refresh_log($array) { - debugging('refresh_log() is deprecated, The transfer of logs through mnet are no longer recorded.', DEBUG_DEVELOPER); - return array('code' => 0, 'message' => 'All ok'); - } - - /** - * Receives an array of usernames from a remote machine and prods their - * sessions to keep them alive - * - * @param array $array An array of usernames - * @return string "All ok" or an error message - */ - function keepalive_server($array) { - global $CFG, $DB; - $remoteclient = get_mnet_remote_client(); - - // We don't want to output anything to the client machine - $start = ob_start(); - - // We'll get session records in batches of 30 - $superArray = array_chunk($array, 30); - - $returnString = ''; - - foreach($superArray as $subArray) { - $subArray = array_values($subArray); - $results = $DB->get_records_list('mnet_session', 'username', $subArray, '', 'id, session_id, username'); - - if ($results == false) { - // We seem to have a username that breaks our query: - // TODO: Handle this error appropriately - $returnString .= "We failed to refresh the session for the following usernames: \n".implode("\n", $subArray)."\n\n"; - } else { - foreach($results as $emigrant) { - \core\session\manager::touch_session($emigrant->session_id); - } - } - } - - $end = ob_end_clean(); - - if (empty($returnString)) return array('code' => 0, 'message' => 'All ok', 'last log id' => $remoteclient->last_log_id); - return array('code' => 1, 'message' => $returnString, 'last log id' => $remoteclient->last_log_id); - } - - /** - * Cleanup any remote mnet_sessions, kill the local mnet_session data - * - * This is called by require_logout in moodlelib - * - * @return void - */ - function prelogout_hook() { - global $CFG, $USER; - - if (!is_enabled_auth('mnet')) { - return; - } - - // If the user is local to this Moodle: - if ($USER->mnethostid == $this->mnet->id) { - $this->kill_children($USER->username, sha1($_SERVER['HTTP_USER_AGENT'])); - - // Else the user has hit 'logout' at a Service Provider Moodle: - } else { - $this->kill_parent($USER->username, sha1($_SERVER['HTTP_USER_AGENT'])); - - } - } - - /** - * The SP uses this function to kill the session on the parent IdP - * - * @param string $username Username for session to kill - * @param string $useragent SHA1 hash of user agent to look for - * @return string A plaintext report of what has happened - */ - function kill_parent($username, $useragent) { - global $CFG, $USER, $DB; - - require_once $CFG->dirroot.'/mnet/xmlrpc/client.php'; - $sql = " - select - * - from - {mnet_session} s - where - s.username = ? AND - s.useragent = ? AND - s.mnethostid = ?"; - - $mnetsessions = $DB->get_records_sql($sql, array($username, $useragent, $USER->mnethostid)); - - $ignore = $DB->delete_records('mnet_session', - array('username'=>$username, - 'useragent'=>$useragent, - 'mnethostid'=>$USER->mnethostid)); - - if (false != $mnetsessions) { - $mnet_peer = new mnet_peer(); - $mnet_peer->set_id($USER->mnethostid); - - $mnet_request = new mnet_xmlrpc_client(); - $mnet_request->set_method('auth/mnet/auth.php/kill_children'); - - // set $token and $useragent parameters - $mnet_request->add_param($username); - $mnet_request->add_param($useragent); - if ($mnet_request->send($mnet_peer) === false) { - debugging(join("\n", $mnet_request->error)); - return false; - } - } - - return true; - } - - /** - * The IdP uses this function to kill child sessions on other hosts - * - * @param string $username Username for session to kill - * @param string $useragent SHA1 hash of user agent to look for - * @return string A plaintext report of what has happened - */ - function kill_children($username, $useragent) { - global $CFG, $USER, $DB; - $remoteclient = null; - if (defined('MNET_SERVER')) { - $remoteclient = get_mnet_remote_client(); - } - require_once $CFG->dirroot.'/mnet/xmlrpc/client.php'; - - $userid = $DB->get_field('user', 'id', array('mnethostid'=>$CFG->mnet_localhost_id, 'username'=>$username)); - - $returnstring = ''; - - $mnetsessions = $DB->get_records('mnet_session', array('userid' => $userid, 'useragent' => $useragent)); - - if (false == $mnetsessions) { - $returnstring .= "Could find no remote sessions\n"; - $mnetsessions = array(); - } - - foreach($mnetsessions as $mnetsession) { - // If this script is being executed by a remote peer, that means the user has clicked - // logout on that peer, and the session on that peer can be deleted natively. - // Skip over it. - if (isset($remoteclient->id) && ($mnetsession->mnethostid == $remoteclient->id)) { - continue; - } - $returnstring .= "Deleting session\n"; - - $mnet_peer = new mnet_peer(); - $mnet_peer->set_id($mnetsession->mnethostid); - - $mnet_request = new mnet_xmlrpc_client(); - $mnet_request->set_method('auth/mnet/auth.php/kill_child'); - - // set $token and $useragent parameters - $mnet_request->add_param($username); - $mnet_request->add_param($useragent); - if ($mnet_request->send($mnet_peer) === false) { - debugging("Server side error has occured on host $mnetsession->mnethostid: " . - join("\n", $mnet_request->error)); - } - } - - $ignore = $DB->delete_records('mnet_session', - array('useragent'=>$useragent, 'userid'=>$userid)); - - if (isset($remoteclient) && isset($remoteclient->id)) { - \core\session\manager::destroy_user_sessions($userid); - } - return $returnstring; - } - - /** - * When the IdP requests that child sessions are terminated, - * this function will be called on each of the child hosts. The machine that - * calls the function (over xmlrpc) provides us with the mnethostid we need. - * - * @param string $username Username for session to kill - * @param string $useragent SHA1 hash of user agent to look for - * @return bool True on success - */ - function kill_child($username, $useragent) { - global $CFG, $DB; - $remoteclient = get_mnet_remote_client(); - $session = $DB->get_record('mnet_session', array('username'=>$username, 'mnethostid'=>$remoteclient->id, 'useragent'=>$useragent)); - $DB->delete_records('mnet_session', array('username'=>$username, 'mnethostid'=>$remoteclient->id, 'useragent'=>$useragent)); - if (false != $session) { - \core\session\manager::destroy($session->session_id); - return true; - } - return false; - } - - /** - * To delete a host, we must delete all current sessions that users from - * that host are currently engaged in. - * - * @param string $sessionidarray An array of session hashes - * @return bool True on success - */ - function end_local_sessions(&$sessionArray) { - global $CFG; - if (is_array($sessionArray)) { - while($session = array_pop($sessionArray)) { - \core\session\manager::destroy($session->session_id); - } - return true; - } - return false; - } - - /** - * Returns the user's profile image info - * - * If the user exists and has a profile picture, the returned array will contain keys: - * f1 - the content of the default 100x100px image - * f1_mimetype - the mimetype of the f1 file - * f2 - the content of the 35x35px variant of the image - * f2_mimetype - the mimetype of the f2 file - * - * The mimetype information was added in Moodle 2.0. In Moodle 1.x, images are always jpegs. - * - * @see process_new_icon() - * @uses mnet_remote_client callable via MNet XML-RPC - * @param int $username The id of the user - * @return false|array false if user not found, empty array if no picture exists, array with data otherwise - */ - function fetch_user_image($username) { - global $CFG, $DB; - - if ($user = $DB->get_record('user', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id))) { - $fs = get_file_storage(); - $usercontext = context_user::instance($user->id, MUST_EXIST); - $return = array(); - if ($f1 = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.png')) { - $return['f1'] = base64_encode($f1->get_content()); - $return['f1_mimetype'] = $f1->get_mimetype(); - } else if ($f1 = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.jpg')) { - $return['f1'] = base64_encode($f1->get_content()); - $return['f1_mimetype'] = $f1->get_mimetype(); - } - if ($f2 = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f2.png')) { - $return['f2'] = base64_encode($f2->get_content()); - $return['f2_mimetype'] = $f2->get_mimetype(); - } else if ($f2 = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f2.jpg')) { - $return['f2'] = base64_encode($f2->get_content()); - $return['f2_mimetype'] = $f2->get_mimetype(); - } - return $return; - } - return false; - } - - /** - * Returns the theme information and logo url as strings. - * - * @return string The theme info - */ - function fetch_theme_info() { - global $CFG; - - $themename = "$CFG->theme"; - $logourl = "$CFG->wwwroot/theme/$CFG->theme/images/logo.jpg"; - - $return['themename'] = $themename; - $return['logourl'] = $logourl; - return $return; - } - - /** - * Determines if an MNET host is providing the nominated service. - * - * @param int $mnethostid The id of the remote host - * @param string $servicename The name of the service - * @return bool Whether the service is available on the remote host - */ - function has_service($mnethostid, $servicename) { - global $CFG, $DB; - - $sql = " - SELECT - svc.id as serviceid, - svc.name, - svc.description, - svc.offer, - svc.apiversion, - h2s.id as h2s_id - FROM - {mnet_host} h, - {mnet_service} svc, - {mnet_host2service} h2s - WHERE - h.deleted = '0' AND - h.id = h2s.hostid AND - h2s.hostid = ? AND - h2s.serviceid = svc.id AND - svc.name = ? AND - h2s.subscribe = '1'"; - - return $DB->get_records_sql($sql, array($mnethostid, $servicename)); - } - - /** - * Checks the MNET access control table to see if the username/mnethost - * is permitted to login to this moodle. - * - * @param string $username The username - * @param int $mnethostid The id of the remote mnethost - * @return bool Whether the user can login from the remote host - */ - function can_login_remotely($username, $mnethostid) { - global $DB; - - $accessctrl = 'allow'; - $aclrecord = $DB->get_record('mnet_sso_access_control', array('username'=>$username, 'mnet_host_id'=>$mnethostid)); - if (!empty($aclrecord)) { - $accessctrl = $aclrecord->accessctrl; - } - return $accessctrl == 'allow'; - } - - function logoutpage_hook() { - global $USER, $CFG, $redirect, $DB; - - if (!empty($USER->mnethostid) and $USER->mnethostid != $CFG->mnet_localhost_id) { - $host = $DB->get_record('mnet_host', array('id'=>$USER->mnethostid)); - $redirect = $host->wwwroot.'/'; - } - } - - /** - * Trims a log line from mnet peer to limit each part to a length which can be stored in our DB - * - * @param object $logline The log information to be trimmed - * @return object The passed logline object trimmed to not exceed storable limits - */ - function trim_logline($logline) { - $limits = array('ip' => 15, 'coursename' => 40, 'module' => 20, 'action' => 40, - 'url' => 255); - foreach ($limits as $property => $limit) { - if (isset($logline->$property)) { - $logline->$property = substr($logline->$property, 0, $limit); - } - } - - return $logline; - } - - /** - * Returns a list of MNet IdPs that the user can roam from. - * - * @param string $wantsurl The relative url fragment the user wants to get to. - * @return array List of arrays with keys url, icon and name. - */ - function loginpage_idp_list($wantsurl) { - global $DB, $CFG; - - // strip off wwwroot, since the remote site will prefix it's return url with this - $wantsurl = preg_replace('/(' . preg_quote($CFG->wwwroot, '/') . ')/', '', $wantsurl); - - $sql = "SELECT DISTINCT h.id, h.wwwroot, h.name, a.sso_jump_url, a.name as application - FROM {mnet_host} h - JOIN {mnet_host2service} m ON h.id = m.hostid - JOIN {mnet_service} s ON s.id = m.serviceid - JOIN {mnet_application} a ON h.applicationid = a.id - WHERE s.name = ? AND h.deleted = ? AND m.publish = ?"; - $params = array('sso_sp', 0, 1); - - if (!empty($CFG->mnet_all_hosts_id)) { - $sql .= " AND h.id <> ?"; - $params[] = $CFG->mnet_all_hosts_id; - } - - if (!$hosts = $DB->get_records_sql($sql, $params)) { - return array(); - } - - $idps = array(); - foreach ($hosts as $host) { - $idps[] = array( - 'url' => new moodle_url($host->wwwroot . $host->sso_jump_url, array('hostwwwroot' => $CFG->wwwroot, 'wantsurl' => $wantsurl, 'remoteurl' => 1)), - 'icon' => new pix_icon('i/' . $host->application . '_host', $host->name), - 'name' => $host->name, - ); - } - return $idps; - } - - /** - * Test if settings are correct, print info to output. - */ - public function test_settings() { - global $CFG, $OUTPUT, $DB; - - // Generate warning if MNET is disabled. - if (empty($CFG->mnet_dispatcher_mode) || $CFG->mnet_dispatcher_mode !== 'strict') { - echo $OUTPUT->notification(get_string('mnetdisabled', 'mnet'), 'notifyproblem'); - return; - } - - // Generate full list of ID and service providers. - $query = " - SELECT - h.id, - h.name as hostname, - h.wwwroot, - h2idp.publish as idppublish, - h2idp.subscribe as idpsubscribe, - idp.name as idpname, - h2sp.publish as sppublish, - h2sp.subscribe as spsubscribe, - sp.name as spname - FROM - {mnet_host} h - LEFT JOIN - {mnet_host2service} h2idp - ON - (h.id = h2idp.hostid AND - (h2idp.publish = 1 OR - h2idp.subscribe = 1)) - INNER JOIN - {mnet_service} idp - ON - (h2idp.serviceid = idp.id AND - idp.name = 'sso_idp') - LEFT JOIN - {mnet_host2service} h2sp - ON - (h.id = h2sp.hostid AND - (h2sp.publish = 1 OR - h2sp.subscribe = 1)) - INNER JOIN - {mnet_service} sp - ON - (h2sp.serviceid = sp.id AND - sp.name = 'sso_sp') - WHERE - ((h2idp.publish = 1 AND h2sp.subscribe = 1) OR - (h2sp.publish = 1 AND h2idp.subscribe = 1)) AND - h.id != ? - ORDER BY - h.name ASC"; - - $idproviders = array(); - $serviceproviders = array(); - if ($resultset = $DB->get_records_sql($query, array($CFG->mnet_localhost_id))) { - foreach ($resultset as $hostservice) { - if (!empty($hostservice->idppublish) && !empty($hostservice->spsubscribe)) { - $serviceproviders[] = array('id' => $hostservice->id, - 'name' => $hostservice->hostname, - 'wwwroot' => $hostservice->wwwroot); - } - if (!empty($hostservice->idpsubscribe) && !empty($hostservice->sppublish)) { - $idproviders[] = array('id' => $hostservice->id, - 'name' => $hostservice->hostname, - 'wwwroot' => $hostservice->wwwroot); - } - } - } - - // ID Providers. - $table = html_writer::start_tag('table', array('class' => 'generaltable')); - - $count = 0; - foreach ($idproviders as $host) { - $table .= html_writer::start_tag('tr'); - $table .= html_writer::start_tag('td'); - $table .= $host['name']; - $table .= html_writer::end_tag('td'); - $table .= html_writer::start_tag('td'); - $table .= $host['wwwroot']; - $table .= html_writer::end_tag('td'); - $table .= html_writer::end_tag('tr'); - $count++; - } - $table .= html_writer::end_tag('table'); - - if ($count > 0) { - echo html_writer::tag('h3', get_string('auth_mnet_roamin', 'auth_mnet')); - echo $table; - } - - // Service Providers. - unset($table); - $table = html_writer::start_tag('table', array('class' => 'generaltable')); - $count = 0; - foreach ($serviceproviders as $host) { - $table .= html_writer::start_tag('tr'); - $table .= html_writer::start_tag('td'); - $table .= $host['name']; - $table .= html_writer::end_tag('td'); - $table .= html_writer::start_tag('td'); - $table .= $host['wwwroot']; - $table .= html_writer::end_tag('td'); - $table .= html_writer::end_tag('tr'); - $count++; - } - $table .= html_writer::end_tag('table'); - if ($count > 0) { - echo html_writer::tag('h3', get_string('auth_mnet_roamout', 'auth_mnet')); - echo $table; - } - } -} diff --git a/auth/mnet/classes/privacy/provider.php b/auth/mnet/classes/privacy/provider.php deleted file mode 100644 index 4132f48ea38..00000000000 --- a/auth/mnet/classes/privacy/provider.php +++ /dev/null @@ -1,273 +0,0 @@ -. -/** - * Privacy Subsystem implementation for auth_mnet. - * - * @package auth_mnet - * @copyright 2018 Carlos Escobedo - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace auth_mnet\privacy; - -defined('MOODLE_INTERNAL') || die(); - -use core_privacy\local\metadata\collection; -use core_privacy\local\request\contextlist; -use core_privacy\local\request\approved_contextlist; -use core_privacy\local\request\transform; -use core_privacy\local\request\writer; -use core_privacy\local\request\userlist; -use core_privacy\local\request\approved_userlist; - -/** - * Privacy provider for the mnet authentication - * - * @copyright 2018 Carlos Escobedo - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements - \core_privacy\local\metadata\provider, - \core_privacy\local\request\core_userlist_provider, - \core_privacy\local\request\plugin\provider { - /** - * Returns meta data about this system. - * - * @param collection $collection The initialised item collection to add items to. - * @return collection A listing of user data stored through this system. - */ - public static function get_metadata(collection $collection): collection { - - $sessionfields = [ - 'userid' => 'privacy:metadata:mnet_session:userid', - 'username' => 'privacy:metadata:mnet_session:username', - 'token' => 'privacy:metadata:mnet_session:token', - 'mnethostid' => 'privacy:metadata:mnet_session:mnethostid', - 'useragent' => 'privacy:metadata:mnet_session:useragent', - 'expires' => 'privacy:metadata:mnet_session:expires' - ]; - - $collection->add_database_table('mnet_session', $sessionfields, 'privacy:metadata:mnet_session'); - - $logfields = [ - 'hostid' => 'privacy:metadata:mnet_log:hostid', - 'remoteid' => 'privacy:metadata:mnet_log:remoteid', - 'time' => 'privacy:metadata:mnet_log:time', - 'userid' => 'privacy:metadata:mnet_log:userid', - 'ip' => 'privacy:metadata:mnet_log:ip', - 'course' => 'privacy:metadata:mnet_log:course', - 'coursename' => 'privacy:metadata:mnet_log:coursename', - 'module' => 'privacy:metadata:mnet_log:module', - 'cmid' => 'privacy:metadata:mnet_log:cmid', - 'action' => 'privacy:metadata:mnet_log:action', - 'url' => 'privacy:metadata:mnet_log:url', - 'info' => 'privacy:metadata:mnet_log:info' - ]; - - $collection->add_database_table('mnet_log', $logfields, 'privacy:metadata:mnet_log'); - - $externalfields = [ - 'address' => 'privacy:metadata:mnet_external:address', - 'alternatename' => 'privacy:metadata:mnet_external:alternatename', - 'autosubscribe' => 'privacy:metadata:mnet_external:autosubscribe', - 'calendartype' => 'privacy:metadata:mnet_external:calendartype', - 'city' => 'privacy:metadata:mnet_external:city', - 'country' => 'privacy:metadata:mnet_external:country', - 'currentlogin' => 'privacy:metadata:mnet_external:currentlogin', - 'department' => 'privacy:metadata:mnet_external:department', - 'description' => 'privacy:metadata:mnet_external:description', - 'email' => 'privacy:metadata:mnet_external:email', - 'emailstop' => 'privacy:metadata:mnet_external:emailstop', - 'firstaccess' => 'privacy:metadata:mnet_external:firstaccess', - 'firstname' => 'privacy:metadata:mnet_external:firstname', - 'firstnamephonetic' => 'privacy:metadata:mnet_external:firstnamephonetic', - 'id' => 'privacy:metadata:mnet_external:id', - 'idnumber' => 'privacy:metadata:mnet_external:idnumber', - 'imagealt' => 'privacy:metadata:mnet_external:imagealt', - 'institution' => 'privacy:metadata:mnet_external:institution', - 'lang' => 'privacy:metadata:mnet_external:lang', - 'lastaccess' => 'privacy:metadata:mnet_external:lastaccess', - 'lastlogin' => 'privacy:metadata:mnet_external:lastlogin', - 'lastname' => 'privacy:metadata:mnet_external:lastname', - 'lastnamephonetic' => 'privacy:metadata:mnet_external:lastnamephonetic', - 'maildigest' => 'privacy:metadata:mnet_external:maildigest', - 'maildisplay' => 'privacy:metadata:mnet_external:maildisplay', - 'middlename' => 'privacy:metadata:mnet_external:middlename', - 'phone1' => 'privacy:metadata:mnet_external:phone1', - 'pnone2' => 'privacy:metadata:mnet_external:phone2', - 'picture' => 'privacy:metadata:mnet_external:picture', - 'policyagreed' => 'privacy:metadata:mnet_external:policyagreed', - 'suspended' => 'privacy:metadata:mnet_external:suspended', - 'timezone' => 'privacy:metadata:mnet_external:timezone', - 'trackforums' => 'privacy:metadata:mnet_external:trackforums', - 'trustbitmask' => 'privacy:metadata:mnet_external:trustbitmask', - 'username' => 'privacy:metadata:mnet_external:username', - ]; - - $collection->add_external_location_link('moodle', $externalfields, 'privacy:metadata:external:moodle'); - - $collection->add_external_location_link('mahara', $externalfields, 'privacy:metadata:external:mahara'); - - return $collection; - } - - /** - * Get the list of contexts that contain user information for the specified user. - * - * @param int $userid The user to search. - * @return contextlist $contextlist The list of contexts used in this plugin. - */ - public static function get_contexts_for_userid(int $userid): contextlist { - $sql = "SELECT ctx.id - FROM {mnet_log} ml - JOIN {context} ctx ON ctx.instanceid = ml.userid AND ctx.contextlevel = :contextlevel - WHERE ml.userid = :userid"; - $params = ['userid' => $userid, 'contextlevel' => CONTEXT_USER]; - - $contextlist = new contextlist(); - $contextlist->add_from_sql($sql, $params); - - return $contextlist; - } - - /** - * Get the list of users within a specific context. - * - * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. - */ - public static function get_users_in_context(userlist $userlist) { - $context = $userlist->get_context(); - - if (!$context instanceof \context_user) { - return; - } - - $sql = "SELECT userid - FROM {mnet_log} - WHERE userid = ?"; - $params = [$context->instanceid]; - $userlist->add_from_sql('userid', $sql, $params); - } - - /** - * Export all user data for the specified user, in the specified contexts, using the supplied exporter instance. - * - * @param approved_contextlist $contextlist The approved contexts to export information for. - */ - public static function export_user_data(approved_contextlist $contextlist) { - global $DB; - - $context = \context_user::instance($contextlist->get_user()->id); - - $sql = "SELECT ml.id, mh.wwwroot, mh.name, ml.remoteid, ml.time, ml.userid, ml.ip, ml.course, - ml.coursename, ml.module, ml.cmid, ml.action, ml.url, ml.info - FROM {mnet_log} ml - JOIN {mnet_host} mh ON mh.id = ml.hostid - WHERE ml.userid = :userid - ORDER BY mh.name, ml.coursename"; - $params = ['userid' => $contextlist->get_user()->id]; - - $data = []; - $lastcourseid = null; - - $logentries = $DB->get_recordset_sql($sql, $params); - foreach ($logentries as $logentry) { - $item = (object) [ - 'time' => transform::datetime($logentry->time), - 'remoteid' => $logentry->remoteid, - 'ip' => $logentry->ip, - 'course' => $logentry->course, - 'coursename' => format_string($logentry->coursename), - 'module' => $logentry->module, - 'cmid' => $logentry->cmid, - 'action' => $logentry->action, - 'url' => $logentry->url, - 'info' => format_string($logentry->info) - ]; - - $item->externalhost = - ($logentry->name == '') ? preg_replace('#^https?://#', '', $logentry->wwwroot) : - preg_replace('#^https?://#', '', $logentry->name); - - if ($lastcourseid && $lastcourseid != $logentry->course) { - $path = [get_string('pluginname', 'auth_mnet'), $data[0]->externalhost, $data[0]->coursename]; - writer::with_context($context)->export_data($path, (object) $data); - $data = []; - } - - $data[] = $item; - $lastcourseid = $logentry->course; - } - $logentries->close(); - - $path = [get_string('pluginname', 'auth_mnet'), $item->externalhost, $item->coursename]; - writer::with_context($context)->export_data($path, (object) $data); - } - - /** - * Delete all personal data for all users in the specified context. - * - * @param context $context Context to delete data from. - */ - public static function delete_data_for_all_users_in_context(\context $context) { - global $DB; - - if ($context->contextlevel != CONTEXT_USER) { - return; - } - - $DB->delete_records('mnet_log', ['userid' => $context->instanceid]); - } - - /** - * Delete multiple users within a single context. - * - * @param approved_userlist $userlist The approved context and user information to delete information for. - */ - public static function delete_data_for_users(approved_userlist $userlist) { - global $DB; - - $context = $userlist->get_context(); - - if ($context instanceof \context_user) { - $DB->delete_records('mnet_log', ['userid' => $context->instanceid]); - } - } - - /** - * Delete all user data for the specified user, in the specified contexts. - * - * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. - */ - public static function delete_data_for_user(approved_contextlist $contextlist) { - global $DB; - - if (empty($contextlist->count())) { - return; - } - - $userid = $contextlist->get_user()->id; - foreach ($contextlist->get_contexts() as $context) { - if ($context->contextlevel != CONTEXT_USER) { - continue; - } - if ($context->instanceid == $userid) { - // Because we only use user contexts the instance ID is the user ID. - $DB->delete_records('mnet_log', ['userid' => $context->instanceid]); - } - } - } -} diff --git a/auth/mnet/classes/task/cron_task.php b/auth/mnet/classes/task/cron_task.php deleted file mode 100644 index a7bc684cd77..00000000000 --- a/auth/mnet/classes/task/cron_task.php +++ /dev/null @@ -1,47 +0,0 @@ -. - -namespace auth_mnet\task; -defined('MOODLE_INTERNAL') || die(); - -/** - * A schedule task for mnet cron. - * - * @package auth_mnet - * @copyright 2019 Simey Lameze - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class cron_task extends \core\task\scheduled_task { - /** - * Get a descriptive name for this task (shown to admins). - * - * @return string - */ - public function get_name() { - return get_string('crontask', 'auth_mnet'); - } - /** - * Run auth mnet cron. - */ - public function execute() { - global $DB, $CFG; - - require_once($CFG->dirroot . '/auth/mnet/auth.php'); - $mnetplugin = new \auth_plugin_mnet(); - $mnetplugin->keepalive_client(); - $DB->delete_records_select('mnet_session', "expires < ?", [time() - DAYSECS]); - } -} diff --git a/auth/mnet/db/install.php b/auth/mnet/db/install.php deleted file mode 100644 index 236f7dda5b5..00000000000 --- a/auth/mnet/db/install.php +++ /dev/null @@ -1,6 +0,0 @@ -. - -/** - * This file contains the mnet services for the mnet authentication plugin - * - * @since Moodle 2.0 - * @package auth_mnet - * @copyright 2010 Penny Leach - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$publishes = array( - 'sso_idp' => array( - 'apiversion' => 1, - 'classname' => 'auth_plugin_mnet', - 'filename' => 'auth.php', - 'methods' => array( - 'user_authorise', - 'keepalive_server', - 'kill_children', - 'refresh_log', - 'fetch_user_image', - 'fetch_theme_info', - 'update_enrolments', - ), - ), - 'sso_sp' => array( - 'apiversion' => 1, - 'classname' => 'auth_plugin_mnet', - 'filename' => 'auth.php', - 'methods' => array( - 'keepalive_client', - 'kill_child' - ) - ) -); -$subscribes = array( - 'sso_idp' => array( - 'user_authorise' => 'auth/mnet/auth.php/user_authorise', - 'keepalive_server' => 'auth/mnet/auth.php/keepalive_server', - 'kill_children' => 'auth/mnet/auth.php/kill_children', - 'refresh_log' => 'auth/mnet/auth.php/refresh_log', - 'fetch_user_image' => 'auth/mnet/auth.php/fetch_user_image', - 'fetch_theme_info' => 'auth/mnet/auth.php/fetch_theme_info', - 'update_enrolments' => 'auth/mnet/auth.php/update_enrolments', - ), - 'sso_sp' => array( - 'keepalive_client' => 'auth/mnet/auth.php/keepalive_client', - 'kill_child' => 'auth/mnet/auth.php/kill_child', - ), -); diff --git a/auth/mnet/db/tasks.php b/auth/mnet/db/tasks.php deleted file mode 100644 index 43caf28ec51..00000000000 --- a/auth/mnet/db/tasks.php +++ /dev/null @@ -1,34 +0,0 @@ -. -/** - * Definition of mnet scheduled tasks. - * - * @package auth_mnet - * @copyright 2019 Simey Lameze - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -defined('MOODLE_INTERNAL') || die(); -$tasks = array( - array( - 'classname' => '\auth_mnet\task\cron_task', - 'blocking' => 0, - 'minute' => '*/10', - 'hour' => '*', - 'day' => '*', - 'month' => '*', - 'dayofweek' => '*' - ) -); diff --git a/auth/mnet/db/upgrade.php b/auth/mnet/db/upgrade.php deleted file mode 100644 index 7e83b00099e..00000000000 --- a/auth/mnet/db/upgrade.php +++ /dev/null @@ -1,44 +0,0 @@ -. - -/** - * Keeps track of upgrades to the auth_mnet plugin - * - * @package auth_mnet - * @copyright 2010 David Mudrak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * Function to upgrade auth_mnet. - * @param int $oldversion the version we are upgrading from - * @return bool result - */ -function xmldb_auth_mnet_upgrade($oldversion) { - // Automatically generated Moodle v4.2.0 release upgrade line. - // Put any upgrade step following this. - - // Automatically generated Moodle v4.3.0 release upgrade line. - // Put any upgrade step following this. - - // Automatically generated Moodle v4.4.0 release upgrade line. - // Put any upgrade step following this. - - // Automatically generated Moodle v4.5.0 release upgrade line. - // Put any upgrade step following this. - - return true; -} diff --git a/auth/mnet/jump.php b/auth/mnet/jump.php deleted file mode 100644 index 83ad27c6383..00000000000 --- a/auth/mnet/jump.php +++ /dev/null @@ -1,70 +0,0 @@ -. - -/** - * Authentication Plugin: Moodle Network Authentication - * Multiple host authentication support for Moodle Network. - * - * @package auth_mnet - * @author Martin Dougiamas - * @license http://www.gnu.org/copyleft/gpl.html GNU Public License - */ - -require_once __DIR__ . '/../../config.php'; - -// grab the GET params - wantsurl could be anything - take it -// with PARAM_RAW -$hostid = optional_param('hostid', '0', PARAM_INT); -$hostwwwroot = optional_param('hostwwwroot', '', PARAM_URL); -$wantsurl = optional_param('wantsurl', '', PARAM_RAW); - -$url = new moodle_url('/auth/mnet/jump.php'); -if ($hostid !== '0') $url->param('hostid', $hostid); -if ($hostwwwroot !== '') $url->param('hostwwwroot', $hostwwwroot); -if ($wantsurl !== '') $url->param('wantsurl', $wantsurl); -$PAGE->set_url($url); - -if (!isloggedin() or isguestuser()) { - $SESSION->wantsurl = $PAGE->url->out(false); - redirect(get_login_url()); -} - -if (!is_enabled_auth('mnet')) { - throw new \moodle_exception('mnetdisable'); -} - -// If hostid hasn't been specified, try getting it using wwwroot -if (!$hostid) { - $hostwwwroot = trim($hostwwwroot); - $hostwwwroot = rtrim($hostwwwroot, '/'); - - // ensure the wwwroot starts with a http or https prefix - if (strtolower(substr($hostwwwroot, 0, 4)) != 'http') { - $hostwwwroot = 'http://'.$hostwwwroot; - } - $hostid = $DB->get_field('mnet_host', 'id', array('wwwroot' => $hostwwwroot)); -} - -// start the mnet session and redirect browser to remote URL -$mnetauth = get_auth_plugin('mnet'); -$url = $mnetauth->start_jump_session($hostid, $wantsurl); - -if (empty($url)) { - throw new \moodle_exception('DEBUG: Jump session was not started correctly or blank URL returned.'); // TODO: errors. -} -redirect($url); - - diff --git a/auth/mnet/land.php b/auth/mnet/land.php deleted file mode 100644 index 3e5fceb64c1..00000000000 --- a/auth/mnet/land.php +++ /dev/null @@ -1,69 +0,0 @@ -. - -/** - * Authentication Plugin: Moodle Network Authentication - * Multiple host authentication support for Moodle Network. - * - * @package auth_mnet - * @author Martin Dougiamas - * @license http://www.gnu.org/copyleft/gpl.html GNU Public License - */ - -require_once __DIR__ . '/../../config.php'; -require_once $CFG->dirroot . '/mnet/xmlrpc/client.php'; - -// grab the GET params -$token = required_param('token', PARAM_BASE64); -$remotewwwroot = required_param('idp', PARAM_URL); -$wantsurl = required_param('wantsurl', PARAM_LOCALURL); -$wantsremoteurl = optional_param('remoteurl', false, PARAM_BOOL); - -$url = new moodle_url('/auth/mnet/jump.php', array('token'=>$token, 'idp'=>$remotewwwroot, 'wantsurl'=>$wantsurl)); -if ($wantsremoteurl !== false) $url->param('remoteurl', $wantsremoteurl); -$PAGE->set_url($url); -$PAGE->set_context(context_system::instance()); - -$site = get_site(); - -if (!is_enabled_auth('mnet')) { - throw new \moodle_exception('mnetdisable'); -} - -// confirm the MNET session -$mnetauth = get_auth_plugin('mnet'); -$remotepeer = new mnet_peer(); -$remotepeer->set_wwwroot($remotewwwroot); -// this creates the local user account if necessary, or updates it if it already exists -$localuser = $mnetauth->confirm_mnet_session($token, $remotepeer); - -// log in -$user = get_complete_user_data('id', $localuser->id, $localuser->mnethostid); -complete_user_login($user); -// now that we've logged in, set up the mnet session properly -$mnetauth->update_mnet_session($user, $token, $remotepeer); - -if (!empty($localuser->mnet_foreign_host_array)) { - $USER->mnet_foreign_host_array = $localuser->mnet_foreign_host_array; -} - -// redirect -if ($wantsremoteurl) { - redirect($remotewwwroot . $wantsurl); -} -redirect($CFG->wwwroot . $wantsurl); - - diff --git a/auth/mnet/lang/en/auth_mnet.php b/auth/mnet/lang/en/auth_mnet.php deleted file mode 100644 index a483a22156c..00000000000 --- a/auth/mnet/lang/en/auth_mnet.php +++ /dev/null @@ -1,96 +0,0 @@ -. - -/** - * Strings for component 'auth_mnet', language 'en'. - * - * @package auth_mnet - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['auth_mnet_auto_add_remote_users'] = 'When set to Yes, a local user record is auto-created when a remote user logs in for the first time.'; -$string['auth_mnetdescription'] = 'Users are authenticated according to the web of trust defined in your Moodle Network settings.'; -$string['auth_mnet_roamin'] = 'These host\'s users can roam in to your site'; -$string['auth_mnet_roamout'] = 'Your users can roam out to these hosts'; -$string['auth_mnet_rpc_negotiation_timeout'] = 'The timeout in seconds for authentication over the XMLRPC transport.'; -$string['auto_add_remote_users'] = 'Auto add remote users'; -$string['crontask'] = 'Background processing for MNET authentication'; -$string['rpc_negotiation_timeout'] = 'RPC negotiation timeout'; -$string['sso_idp_description'] = 'Publish this service to allow your users to roam to the {$a} site without having to re-login there.
  • Dependency: You must also subscribe to the SSO (Service Provider) service on {$a}.

Subscribe to this service to allow authenticated users from {$a} to access your site without having to re-login.
  • Dependency: You must also publish the SSO (Service Provider) service to {$a}.

'; -$string['sso_idp_name'] = 'SSO (Identity Provider)'; -$string['sso_mnet_login_refused'] = 'Username {$a->user} is not permitted to login from {$a->host}.'; -$string['sso_sp_description'] = 'Publish this service to allow authenticated users from {$a} to access your site without having to re-login.
  • Dependency: You must also subscribe to the SSO (Identity Provider) service on {$a}.

Subscribe to this service to allow your users to roam to the {$a} site without having to re-login there.
  • Dependency: You must also publish the SSO (Identity Provider) service to {$a}.

'; -$string['sso_sp_name'] = 'SSO (Service Provider)'; -$string['pluginname'] = 'MNet authentication'; -$string['privacy:metadata:external:mahara'] = 'This plugin can send data externally to a linked Mahara application.'; -$string['privacy:metadata:external:moodle'] = 'This plugin can send data externally to a linked Moodle application.'; -$string['privacy:metadata:mnet_external:address'] = 'The address of the user.'; -$string['privacy:metadata:mnet_external:alternatename'] = 'An alternative name for the user.'; -$string['privacy:metadata:mnet_external:autosubscribe'] = 'A preference as to if the user should be auto-subscribed to forums the user posts in.'; -$string['privacy:metadata:mnet_external:calendartype'] = 'A user preference for the type of calendar to use.'; -$string['privacy:metadata:mnet_external:city'] = 'The city of the user.'; -$string['privacy:metadata:mnet_external:country'] = 'The country that the user is in.'; -$string['privacy:metadata:mnet_external:currentlogin'] = 'The current login for this user.'; -$string['privacy:metadata:mnet_external:department'] = 'The department that this user can be found in.'; -$string['privacy:metadata:mnet_external:description'] = 'General details about this user.'; -$string['privacy:metadata:mnet_external:email'] = 'An email address for contact.'; -$string['privacy:metadata:mnet_external:emailstop'] = 'A preference to stop email being sent to the user.'; -$string['privacy:metadata:mnet_external:firstaccess'] = 'The time that this user first accessed the site.'; -$string['privacy:metadata:mnet_external:firstname'] = 'The first name of the user.'; -$string['privacy:metadata:mnet_external:firstnamephonetic'] = 'The phonetic details about the user\'s first name.'; -$string['privacy:metadata:mnet_external:id'] = 'The user ID'; -$string['privacy:metadata:mnet_external:idnumber'] = 'An identification number given by the institution'; -$string['privacy:metadata:mnet_external:imagealt'] = 'Alternative text for the user\'s image.'; -$string['privacy:metadata:mnet_external:institution'] = 'The institution that this user is a member of.'; -$string['privacy:metadata:mnet_external:lang'] = 'A user preference for the language shown.'; -$string['privacy:metadata:mnet_external:lastaccess'] = 'The time that the user last accessed the site.'; -$string['privacy:metadata:mnet_external:lastlogin'] = 'The last login of this user.'; -$string['privacy:metadata:mnet_external:lastname'] = 'The last name of the user.'; -$string['privacy:metadata:mnet_external:lastnamephonetic'] = 'The phonetic details of the user\'s last name.'; -$string['privacy:metadata:mnet_external:maildigest'] = 'A setting for the mail digest for this user.'; -$string['privacy:metadata:mnet_external:maildisplay'] = 'A preference for the user about displaying their email address to other users.'; -$string['privacy:metadata:mnet_external:middlename'] = 'The middle name of the user'; -$string['privacy:metadata:mnet_external:phone1'] = 'A phone number for the user.'; -$string['privacy:metadata:mnet_external:phone2'] = 'An additional phone number for the user.'; -$string['privacy:metadata:mnet_external:picture'] = 'The picture details associated with this user.'; -$string['privacy:metadata:mnet_external:policyagreed'] = 'A flag to determine if the user has agreed to the site policy.'; -$string['privacy:metadata:mnet_external:suspended'] = 'A flag to show if the user has been suspended on this system.'; -$string['privacy:metadata:mnet_external:timezone'] = 'The timezone of the user'; -$string['privacy:metadata:mnet_external:trackforums'] = 'A preference for forums and tracking them.'; -$string['privacy:metadata:mnet_external:trustbitmask'] = 'The trust bit mask'; -$string['privacy:metadata:mnet_external:username'] = 'The username for this user.'; -$string['privacy:metadata:mnet_log'] = 'Details of remote actions carried out by a local user logged in a remote system.'; -$string['privacy:metadata:mnet_log:action'] = 'Action carried out by the user.'; -$string['privacy:metadata:mnet_log:cmid'] = 'ID of the course module.'; -$string['privacy:metadata:mnet_log:course'] = 'Remote system course ID where the action occurred.'; -$string['privacy:metadata:mnet_log:coursename'] = 'Remote system course full name where the action occurred.'; -$string['privacy:metadata:mnet_log:hostid'] = 'Remote system MNet ID.'; -$string['privacy:metadata:mnet_log:info'] = 'Additional information about the action.'; -$string['privacy:metadata:mnet_log:ip'] = 'The IP address used at the time of the action occurred.'; -$string['privacy:metadata:mnet_log:module'] = 'Remote system module where the action occurred.'; -$string['privacy:metadata:mnet_log:remoteid'] = 'Remote ID of the user who carried out the action in the remote system.'; -$string['privacy:metadata:mnet_log:time'] = 'Time when the action occurred.'; -$string['privacy:metadata:mnet_log:url'] = 'Remote system URL where the action occurred.'; -$string['privacy:metadata:mnet_log:userid'] = 'Local ID of the user who carried out the action in the remote system.'; -$string['privacy:metadata:mnet_session'] = 'The details of each MNet user session in a remote system. The data is stored temporarily.'; -$string['privacy:metadata:mnet_session:expires'] = 'Time when the session expires.'; -$string['privacy:metadata:mnet_session:mnethostid'] = 'Remote system MNet ID.'; -$string['privacy:metadata:mnet_session:token'] = 'Unique session identifier'; -$string['privacy:metadata:mnet_session:useragent'] = 'User agent used to access the remote system'; -$string['privacy:metadata:mnet_session:userid'] = 'ID of the user jumping to remote system.'; -$string['privacy:metadata:mnet_session:username'] = 'Username of the user jumping to remote system.'; -$string['unknownhost'] = 'Unknown host'; diff --git a/auth/mnet/settings.php b/auth/mnet/settings.php deleted file mode 100644 index b7aa4a4b59a..00000000000 --- a/auth/mnet/settings.php +++ /dev/null @@ -1,39 +0,0 @@ -. - -/** - * Admin settings and defaults. - * - * @package auth_mnet - * @copyright 2017 Stephen Bourget - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die; - -if ($ADMIN->fulltree) { - require_once($CFG->dirroot.'/lib/outputlib.php'); - - // Introductory explanation. - $settings->add(new admin_setting_heading('auth_mnet/pluginname', '', - new lang_string('auth_mnetdescription', 'auth_mnet'))); - - // RPC Timeout. - $settings->add(new admin_setting_configtext('auth_mnet/rpc_negotiation_timeout', - get_string('rpc_negotiation_timeout', 'auth_mnet'), - get_string('auth_mnet_rpc_negotiation_timeout', 'auth_mnet'), '30', PARAM_INT)); - -} diff --git a/auth/mnet/tests/privacy/provider_test.php b/auth/mnet/tests/privacy/provider_test.php deleted file mode 100644 index 9bc39700cd9..00000000000 --- a/auth/mnet/tests/privacy/provider_test.php +++ /dev/null @@ -1,333 +0,0 @@ -. -/** - * Privacy test for the authentication mnet - * - * @package auth_mnet - * @category test - * @copyright 2018 Victor Deniz - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -namespace auth_mnet\privacy; - -defined('MOODLE_INTERNAL') || die(); - -use auth_mnet\privacy\provider; -use core_privacy\local\request\approved_contextlist; -use core_privacy\local\request\writer; -use core_privacy\tests\provider_testcase; -use core_privacy\local\request\transform; -use core_privacy\local\request\approved_userlist; - -/** - * Privacy test for the authentication mnet - * - * @package auth_mnet - * @category test - * @copyright 2018 Victor Deniz - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -final class provider_test extends provider_testcase { - /** - * Set up method. - */ - public function setUp(): void { - parent::setUp(); - $this->resetAfterTest(); - $this->setAdminUser(); - } - - /** - * Check that a user context is returned if there is any user data for this user. - */ - public function test_get_contexts_for_userid(): void { - global $DB; - - $user = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - $this->assertEmpty(provider::get_contexts_for_userid($user->id)); - - // Insert mnet_log record. - $logrecord = new \stdClass(); - $logrecord->hostid = ''; - $logrecord->remoteid = 65; - $logrecord->time = time(); - $logrecord->userid = $user->id; - - $DB->insert_record('mnet_log', $logrecord); - - $contextlist = provider::get_contexts_for_userid($user->id); - - // Check that we only get back one context. - $this->assertCount(1, $contextlist); - - // Check that a context is returned is the expected. - $usercontext = \context_user::instance($user->id); - $this->assertEquals($usercontext->id, $contextlist->get_contextids()[0]); - } - - /** - * Test that user data is exported correctly. - */ - public function test_export_user_data(): void { - global $DB; - - $user = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - - // Insert mnet_host record. - $hostrecord = new \stdClass(); - $hostrecord->wwwroot = 'https://external.moodle.com'; - $hostrecord->name = 'External Moodle'; - $hostrecord->public_key = '-----BEGIN CERTIFICATE-----'; - - $hostid = $DB->insert_record('mnet_host', $hostrecord); - - // Insert mnet_log record. - $logrecord = new \stdClass(); - $logrecord->hostid = $hostid; - $logrecord->remoteid = 65; - $logrecord->time = time(); - $logrecord->userid = $user->id; - $logrecord->course = 3; - $logrecord->coursename = 'test course'; - - $DB->insert_record('mnet_log', $logrecord); - - $usercontext = \context_user::instance($user->id); - - /** @var \core_privacy\tests\request\content_writer $writer */ - $writer = writer::with_context($usercontext); - $this->assertFalse($writer->has_any_data()); - $approvedlist = new approved_contextlist($user, 'auth_mnet', [$usercontext->id]); - provider::export_user_data($approvedlist); - - $data = (array)$writer->get_data([get_string('pluginname', 'auth_mnet'), $hostrecord->name, $logrecord->coursename]); - - $this->assertEquals($logrecord->remoteid, reset($data)->remoteid); - $this->assertEquals(transform::datetime($logrecord->time), reset($data)->time); - } - - /** - * Test deleting all user data for a specific context. - */ - public function test_delete_data_for_all_users_in_context(): void { - global $DB; - - $user1 = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - - // Insert mnet_log record. - $logrecord1 = new \stdClass(); - $logrecord1->hostid = ''; - $logrecord1->remoteid = 65; - $logrecord1->time = time(); - $logrecord1->userid = $user1->id; - - $DB->insert_record('mnet_log', $logrecord1); - - $user1context = \context_user::instance($user1->id); - - $user2 = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - - // Insert mnet_log record. - $logrecord2 = new \stdClass(); - $logrecord2->hostid = ''; - $logrecord2->remoteid = 65; - $logrecord2->time = time(); - $logrecord2->userid = $user2->id; - - $DB->insert_record('mnet_log', $logrecord2); - - // Get all mnet log records. - $mnetlogrecords = $DB->get_records('mnet_log', array()); - // There should be two. - $this->assertCount(2, $mnetlogrecords); - - // Delete everything for the first user context. - provider::delete_data_for_all_users_in_context($user1context); - - // Get all user1 mnet log records. - $mnetlogrecords = $DB->get_records('mnet_log', ['userid' => $user1->id]); - $this->assertCount(0, $mnetlogrecords); - - // Get all mnet log records. - $mnetlogrecords = $DB->get_records('mnet_log', array()); - // There should be one (user2). - $this->assertCount(1, $mnetlogrecords); - } - - /** - * This should work identical to the above test. - */ - public function test_delete_data_for_user(): void { - global $DB; - - $user1 = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - - // Insert mnet_log record. - $logrecord1 = new \stdClass(); - $logrecord1->hostid = ''; - $logrecord1->remoteid = 65; - $logrecord1->time = time(); - $logrecord1->userid = $user1->id; - - $DB->insert_record('mnet_log', $logrecord1); - - $user1context = \context_user::instance($user1->id); - - $user2 = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - - // Insert mnet_log record. - $logrecord2 = new \stdClass(); - $logrecord2->hostid = ''; - $logrecord2->remoteid = 65; - $logrecord2->time = time(); - $logrecord2->userid = $user2->id; - - $DB->insert_record('mnet_log', $logrecord2); - - // Get all mnet log records. - $mnetlogrecords = $DB->get_records('mnet_log', array()); - // There should be two. - $this->assertCount(2, $mnetlogrecords); - - // Delete everything for the first user. - $approvedlist = new approved_contextlist($user1, 'auth_mnet', [$user1context->id]); - provider::delete_data_for_user($approvedlist); - - // Get all user1 mnet log records. - $mnetlogrecords = $DB->get_records('mnet_log', ['userid' => $user1->id]); - $this->assertCount(0, $mnetlogrecords); - - // Get all mnet log records. - $mnetlogrecords = $DB->get_records('mnet_log', array()); - // There should be one (user2). - $this->assertCount(1, $mnetlogrecords); - } - - /** - * Test that only users with a user context are fetched. - */ - public function test_get_users_in_context(): void { - global $DB; - - $this->resetAfterTest(); - - $component = 'auth_mnet'; - // Create a user. - $user = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - $usercontext = \context_user::instance($user->id); - - // The list of users should not return anything yet (related data still haven't been created). - $userlist = new \core_privacy\local\request\userlist($usercontext, $component); - provider::get_users_in_context($userlist); - $this->assertCount(0, $userlist); - - // Insert mnet_log record. - $logrecord = new \stdClass(); - $logrecord->hostid = ''; - $logrecord->remoteid = 65; - $logrecord->time = time(); - $logrecord->userid = $user->id; - $DB->insert_record('mnet_log', $logrecord); - - // The list of users for user context should return the user. - provider::get_users_in_context($userlist); - $this->assertCount(1, $userlist); - $expected = [$user->id]; - $actual = $userlist->get_userids(); - $this->assertEquals($expected, $actual); - - // The list of users for system context should not return any users. - $systemcontext = \context_system::instance(); - $userlist = new \core_privacy\local\request\userlist($systemcontext, $component); - provider::get_users_in_context($userlist); - $this->assertCount(0, $userlist); - } - - /** - * Test that data for users in approved userlist is deleted. - */ - public function test_delete_data_for_users(): void { - global $DB; - - $this->resetAfterTest(); - - $component = 'auth_mnet'; - // Create user1. - $user1 = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - $usercontext1 = \context_user::instance($user1->id); - // Create user2. - $user2 = $this->getDataGenerator()->create_user(['auth' => 'mnet']); - $usercontext2 = \context_user::instance($user2->id); - - // Insert mnet_log record. - $logrecord1 = new \stdClass(); - $logrecord1->hostid = ''; - $logrecord1->remoteid = 65; - $logrecord1->time = time(); - $logrecord1->userid = $user1->id; - $DB->insert_record('mnet_log', $logrecord1); - - // Insert mnet_log record. - $logrecord2 = new \stdClass(); - $logrecord2->hostid = ''; - $logrecord2->remoteid = 65; - $logrecord2->time = time(); - $logrecord2->userid = $user2->id; - $DB->insert_record('mnet_log', $logrecord2); - - // The list of users for usercontext1 should return user1. - $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component); - provider::get_users_in_context($userlist1); - $this->assertCount(1, $userlist1); - $expected = [$user1->id]; - $actual = $userlist1->get_userids(); - $this->assertEquals($expected, $actual); - - // The list of users for usercontext2 should return user2. - $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component); - provider::get_users_in_context($userlist2); - $this->assertCount(1, $userlist2); - $expected = [$user2->id]; - $actual = $userlist2->get_userids(); - $this->assertEquals($expected, $actual); - - // Add userlist1 to the approved user list. - $approvedlist = new approved_userlist($usercontext1, $component, $userlist1->get_userids()); - - // Delete user data using delete_data_for_user for usercontext1. - provider::delete_data_for_users($approvedlist); - - // Re-fetch users in usercontext1 - The user list should now be empty. - $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component); - provider::get_users_in_context($userlist1); - $this->assertCount(0, $userlist1); - // Re-fetch users in usercontext2 - The user list should not be empty (user2). - $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component); - provider::get_users_in_context($userlist2); - $this->assertCount(1, $userlist2); - - // User data should be only removed in the user context. - $systemcontext = \context_system::instance(); - // Add userlist2 to the approved user list in the system context. - $approvedlist = new approved_userlist($systemcontext, $component, $userlist2->get_userids()); - // Delete user1 data using delete_data_for_user. - provider::delete_data_for_users($approvedlist); - // Re-fetch users in usercontext2 - The user list should not be empty (user2). - $userlist2 = new \core_privacy\local\request\userlist($usercontext2, $component); - provider::get_users_in_context($userlist2); - $this->assertCount(1, $userlist2); - } -} diff --git a/auth/mnet/upgrade.txt b/auth/mnet/upgrade.txt deleted file mode 100644 index 2132f33b0c2..00000000000 --- a/auth/mnet/upgrade.txt +++ /dev/null @@ -1,16 +0,0 @@ -=== 4.5 Onwards === - -This file has been replaced by UPGRADING.md. See MDL-81125 for further information. - -=== -This files describes API changes in auth_mnet code. - -=== 3.3 === - -* The config.html file was migrated to use the admin settings API. - The identifier for configuration data stored in config_plugins table was converted from 'auth/mnet' to 'auth_mnet'. - -=== 3.1 === - -* Users now are created through user_create_user function which, apart from inserting the user in the database and generating - a user_created event, is applying the site default preferences if they are not set. diff --git a/auth/mnet/version.php b/auth/mnet/version.php deleted file mode 100644 index da391333c53..00000000000 --- a/auth/mnet/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * Manual authentication plugin version information - * - * @package auth_mnet - * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -$plugin->version = 2024121800; // The current plugin version (Date: YYYYMMDDXX). -$plugin->requires = 2024100100; // Requires this Moodle version. -$plugin->component = 'auth_mnet'; // Full name of the plugin (used for diagnostics) diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index d4af25944b2..3ec9832e1cf 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -1504,5 +1504,14 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2025030400.04); } + // Remove auth_mnet. + if ($oldversion < 2025030400.05) { + if (!file_exists($CFG->dirroot . "/auth/mnet/version.php")) { + uninstall_plugin('auth', 'mnet'); + } + // Main savepoint reached. + upgrade_main_savepoint(true, 2025030400.05); + } + return true; } diff --git a/version.php b/version.php index 18ae58f1cd8..35603072fb5 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2025030400.04; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2025030400.05; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '5.0dev+ (Build: 20250304)'; // Human-friendly version name