/** * 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)) { session_kill_user($userid); } return $returnstring; }
/** * Marks user deleted in internal user database and notifies the auth plugin. * Also unenrols user from all roles and does other cleanup. * * Any plugin that needs to purge user data should register the 'user_deleted' event. * * @param stdClass $user full user object before delete * @return boolean always true */ function delete_user($user) { global $CFG, $DB; require_once $CFG->libdir . '/grouplib.php'; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->dirroot . '/message/lib.php'; require_once $CFG->dirroot . '/tag/lib.php'; // delete all grades - backup is kept in grade_grades_history table grade_user_delete($user->id); //move unread messages from this user to read message_move_userfrom_unread2read($user->id); // TODO: remove from cohorts using standard API here // remove user tags tag_set('user', $user->id, array()); // unconditionally unenrol from all courses enrol_user_delete($user); // unenrol from all roles in all contexts role_unassign_all(array('userid' => $user->id)); // this might be slow but it is really needed - modules might do some extra cleanup! //now do a brute force cleanup // remove from all cohorts $DB->delete_records('cohort_members', array('userid' => $user->id)); // remove from all groups $DB->delete_records('groups_members', array('userid' => $user->id)); // brute force unenrol from all courses $DB->delete_records('user_enrolments', array('userid' => $user->id)); // purge user preferences $DB->delete_records('user_preferences', array('userid' => $user->id)); // purge user extra profile info $DB->delete_records('user_info_data', array('userid' => $user->id)); // last course access not necessary either $DB->delete_records('user_lastaccess', array('userid' => $user->id)); // remove all user tokens $DB->delete_records('external_tokens', array('userid' => $user->id)); // unauthorise the user for all services $DB->delete_records('external_services_users', array('userid' => $user->id)); // force logout - may fail if file based sessions used, sorry session_kill_user($user->id); // now do a final accesslib cleanup - removes all role assignments in user context and context itself delete_context(CONTEXT_USER, $user->id); // workaround for bulk deletes of users with the same email address $delname = "{$user->email}." . time(); while ($DB->record_exists('user', array('username' => $delname))) { // no need to use mnethostid here $delname++; } // mark internal user record as "deleted" $updateuser = new stdClass(); $updateuser->id = $user->id; $updateuser->deleted = 1; $updateuser->username = $delname; // Remember it just in case $updateuser->email = md5($user->username); // Store hash of username, useful importing/restoring users $updateuser->idnumber = ''; // Clear this field to free it up $updateuser->picture = 0; $updateuser->timemodified = time(); $DB->update_record('user', $updateuser); // Add this action to log add_to_log(SITEID, 'user', 'delete', "view.php?id={$user->id}", $user->firstname . ' ' . $user->lastname); // We will update the user's timemodified, as it will be passed to the user_deleted event, which // should know about this updated property persisted to the user's table. $user->timemodified = $updateuser->timemodified; // notify auth plugin - do not block the delete even when plugin fails $authplugin = get_auth_plugin($user->auth); $authplugin->user_delete($user); // any plugin that needs to cleanup should register this event events_trigger('user_deleted', $user); return true; }
/** * Marks user deleted in internal user database and notifies the auth plugin. * Also unenrols user from all roles and does other cleanup. * * Any plugin that needs to purge user data should register the 'user_deleted' event. * * @param stdClass $user full user object before delete * @return boolean success * @throws coding_exception if invalid $user parameter detected */ function delete_user(stdClass $user) { global $CFG, $DB; require_once $CFG->libdir . '/grouplib.php'; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->dirroot . '/message/lib.php'; require_once $CFG->dirroot . '/tag/lib.php'; // Make sure nobody sends bogus record type as parameter. if (!property_exists($user, 'id') or !property_exists($user, 'username')) { throw new coding_exception('Invalid $user parameter in delete_user() detected'); } // Better not trust the parameter and fetch the latest info, // this will be very expensive anyway. if (!($user = $DB->get_record('user', array('id' => $user->id)))) { debugging('Attempt to delete unknown user account.'); return false; } // There must be always exactly one guest record, // originally the guest account was identified by username only, // now we use $CFG->siteguest for performance reasons. if ($user->username === 'guest' or isguestuser($user)) { debugging('Guest user account can not be deleted.'); return false; } // Admin can be theoretically from different auth plugin, // but we want to prevent deletion of internal accoutns only, // if anything goes wrong ppl may force somebody to be admin via // config.php setting $CFG->siteadmins. if ($user->auth === 'manual' and is_siteadmin($user)) { debugging('Local administrator accounts can not be deleted.'); return false; } // delete all grades - backup is kept in grade_grades_history table grade_user_delete($user->id); //move unread messages from this user to read message_move_userfrom_unread2read($user->id); // TODO: remove from cohorts using standard API here // remove user tags tag_set('user', $user->id, array()); // unconditionally unenrol from all courses enrol_user_delete($user); // unenrol from all roles in all contexts role_unassign_all(array('userid' => $user->id)); // this might be slow but it is really needed - modules might do some extra cleanup! //now do a brute force cleanup // remove from all cohorts $DB->delete_records('cohort_members', array('userid' => $user->id)); // remove from all groups $DB->delete_records('groups_members', array('userid' => $user->id)); // brute force unenrol from all courses $DB->delete_records('user_enrolments', array('userid' => $user->id)); // purge user preferences $DB->delete_records('user_preferences', array('userid' => $user->id)); // purge user extra profile info $DB->delete_records('user_info_data', array('userid' => $user->id)); // last course access not necessary either $DB->delete_records('user_lastaccess', array('userid' => $user->id)); // remove all user tokens $DB->delete_records('external_tokens', array('userid' => $user->id)); // unauthorise the user for all services $DB->delete_records('external_services_users', array('userid' => $user->id)); // Remove users private keys. $DB->delete_records('user_private_key', array('userid' => $user->id)); // Remove users customised pages. $DB->delete_records('my_pages', array('userid' => $user->id, 'private' => 1)); // force logout - may fail if file based sessions used, sorry session_kill_user($user->id); // now do a final accesslib cleanup - removes all role assignments in user context and context itself delete_context(CONTEXT_USER, $user->id); // workaround for bulk deletes of users with the same email address $delname = "{$user->email}." . time(); while ($DB->record_exists('user', array('username' => $delname))) { // no need to use mnethostid here $delname++; } // mark internal user record as "deleted" $updateuser = new stdClass(); $updateuser->id = $user->id; $updateuser->deleted = 1; $updateuser->username = $delname; // Remember it just in case $updateuser->email = md5($user->username); // Store hash of username, useful importing/restoring users $updateuser->idnumber = ''; // Clear this field to free it up $updateuser->picture = 0; $updateuser->timemodified = time(); $DB->update_record('user', $updateuser); // Add this action to log add_to_log(SITEID, 'user', 'delete', "view.php?id={$user->id}", $user->firstname . ' ' . $user->lastname); // We will update the user's timemodified, as it will be passed to the user_deleted event, which // should know about this updated property persisted to the user's table. $user->timemodified = $updateuser->timemodified; // notify auth plugin - do not block the delete even when plugin fails $authplugin = get_auth_plugin($user->auth); $authplugin->user_delete($user); // any plugin that needs to cleanup should register this event events_trigger('user_deleted', $user); return true; }
} add_to_log($course->id, 'user', 'update', "view.php?id=$user->id&course=$course->id", ''); //set new password if specified if (!empty($usernew->newpassword)) { if ($authplugin->can_change_password()) { if (!$authplugin->user_update_password($usernew, $usernew->newpassword)){ print_error('cannotupdatepasswordonextauth', '', '', $usernew->auth); } unset_user_preference('create_password', $usernew); // prevent cron from generating the password } } // force logout if user just suspended if (isset($usernew->suspended) and $usernew->suspended and !$user->suspended) { session_kill_user($user->id); } $usercreated = false; } $usercontext = context_user::instance($usernew->id); //update preferences useredit_update_user_preference($usernew); // update tags if (!empty($CFG->usetags) and empty($USER->newadminuser)) { useredit_update_interests($usernew, $usernew->interests); }
if (!in_array($user->id, $SESSION->bulk_users)) { $SESSION->bulk_users[] = $user->id; } } } else { // no user information changed $upt->track('status', $struseruptodate); $usersuptodate++; if ($bulk == UU_BULK_ALL) { if (!in_array($user->id, $SESSION->bulk_users)) { $SESSION->bulk_users[] = $user->id; } } } if ($dologout) { session_kill_user($existinguser->id); } } else { // save the new user to the database $user->confirmed = 1; $user->timemodified = time(); $user->timecreated = time(); $user->mnethostid = $CFG->mnet_localhost_id; // we support ONLY local accounts here, sorry if (!isset($user->suspended) or $user->suspended === '') { $user->suspended = 0; } else { $user->suspended = $user->suspended ? 1 : 0; } $upt->track('suspended', $stryesnooptions[$user->suspended], 'normal', false); if (empty($user->auth)) {