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