From bef4c3ab2f3a06706de80ee154d5d020e95be6c2 Mon Sep 17 00:00:00 2001 From: David Woloszyn Date: Fri, 25 Nov 2022 13:05:03 +1100 Subject: [PATCH 1/2] MDL-58353 user: Add ability to manage user sessions --- lang/en/moodle.php | 6 ++++ lib/navigationlib.php | 9 +++++ user/managesessions.php | 64 ++++++++++++++++++++++++++++++++++++ user/managesessions_form.php | 51 ++++++++++++++++++++++++++++ user/renderer.php | 25 ++++++++++++++ 5 files changed, 155 insertions(+) create mode 100644 user/managesessions.php create mode 100644 user/managesessions_form.php diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 668805b785b..ffaf2e87fd7 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -1248,6 +1248,12 @@ $string['manageeditorfiles'] = 'Manage files used by editor'; $string['managefilters'] = 'Filters'; $string['managemodules'] = 'Modules'; $string['manageroles'] = 'Roles and permissions'; +$string['managesessions'] = 'Manage sessions'; +$string['managesessionslogout'] = 'Log out other sessions'; +$string['managesessionslogoutsuccess'] = 'You have been logged out of your other sessions'; +$string['managesessionslastip'] = 'Last IP address'; +$string['managesessionslastaccessed'] = 'Accessed'; +$string['managesessionscurrent'] = 'Current session'; $string['markallread'] = 'Mark all as read'; $string['markedthistopic'] = 'This topic is highlighted as the current topic'; $string['markthistopic'] = 'Highlight this topic as the current topic'; diff --git a/lib/navigationlib.php b/lib/navigationlib.php index 2209a3efaf6..b0cb113ba20 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -5225,6 +5225,15 @@ class settings_navigation extends navigation_node { $useraccount->add(get_string("changepassword"), $passwordchangeurl, self::TYPE_SETTING, null, 'changepassword'); } + // Manage sessions. + if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) { + if ($currentuser && has_capability('moodle/user:changeownpassword', $systemcontext) || + has_capability('moodle/user:changeownpassword', $usercontext)) { + $url = new moodle_url('/user/managesessions.php', array('id' => $user->id, 'course' => $course->id)); + $useraccount->add(get_string('managesessions'), $url, self::TYPE_SETTING, null, 'managesessions'); + } + } + // Default homepage. $defaulthomepageuser = (!empty($CFG->defaulthomepage) && ($CFG->defaulthomepage == HOMEPAGE_USER)); if (isloggedin() && !isguestuser($user) && $defaulthomepageuser) { diff --git a/user/managesessions.php b/user/managesessions.php new file mode 100644 index 00000000000..95cda45cdad --- /dev/null +++ b/user/managesessions.php @@ -0,0 +1,64 @@ +. + +/** + * Allows a user to see and invalidate sessions + * + * @package core_user + * @copyright 2022 David Woloszyn + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once('../config.php'); +require_once($CFG->libdir.'/gdlib.php'); +require_once($CFG->dirroot.'/user/managesessions_form.php'); +require_once($CFG->dirroot.'/user/editlib.php'); +require_once($CFG->dirroot.'/user/lib.php'); + +$userid = optional_param('id', $USER->id, PARAM_INT); +$courseid = optional_param('course', SITEID, PARAM_INT); + +$PAGE->set_url('/user/managesessions.php', array('id' => $USER->id, 'course' => $courseid)); + +list($user, $course) = useredit_setup_preference_page($USER->id, $courseid); +$redirect = new moodle_url("/user/preferences.php", array('userid' => $user->id)); + +// Create form. +$mform = new user_manage_sessions_form(null, array('userid' => $user->id)); + +if ($mform->is_cancelled()) { + redirect($redirect); +} else if ($mform->is_submitted()) { + // Kill all sessions except for the user's current one. + \core\session\manager::kill_user_sessions($user->id, session_id()); + redirect($redirect, get_string('managesessionslogoutsuccess'), null, \core\output\notification::NOTIFY_SUCCESS); +} + +$renderer = $PAGE->get_renderer('core', 'user'); +$title = get_string('managesessions'); +$userfullname = fullname($user, true); + +$PAGE->navbar->includesettingsbase = true; +$PAGE->set_title($title); +$PAGE->set_heading($userfullname); + +echo $OUTPUT->header(); +echo $OUTPUT->heading($title); +echo $renderer->user_manage_sessions_table(); + +$mform->display(); + +echo $OUTPUT->footer(); diff --git a/user/managesessions_form.php b/user/managesessions_form.php new file mode 100644 index 00000000000..0829862c69e --- /dev/null +++ b/user/managesessions_form.php @@ -0,0 +1,51 @@ +. + +/** + * Allows a user to see and invalidate sessions + * + * @package core_user + * @copyright 2022 David Woloszyn + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +if (!defined('MOODLE_INTERNAL')) { + die('Direct access to this script is forbidden.'); +} + +require_once($CFG->dirroot.'/lib/formslib.php'); +require_once($CFG->dirroot.'/user/lib.php'); + +class user_manage_sessions_form extends moodleform { + + /** + * Define the form. + */ + public function definition () { + global $DB, $USER; + + $sessions = $DB->get_records('sessions', array('userid'=>$USER->id)); + + if (count($sessions) > 1) { + // Add submit and cancel buttons. + $this->add_action_buttons(true, get_string('managesessionslogout')); + } else { + // It's assumed this is your own session. No need to submit, only cancel. + $mform = $this->_form; + $mform->addElement('cancel', 'cancel', get_string('cancel')); + } + } +} diff --git a/user/renderer.php b/user/renderer.php index b449971b260..6c152290a64 100644 --- a/user/renderer.php +++ b/user/renderer.php @@ -216,4 +216,29 @@ class core_user_renderer extends plugin_renderer_base { } return $filteroptions; } + + /** + * Display user sessions in a table format. + * @return string Html code. + */ + public function user_manage_sessions_table() { + global $DB, $USER; + + $table = new html_table(); + $table->head = array( + get_string('managesessionslastip'), + get_string('managesessionslastaccessed'), + get_string('managesessionscurrent')); + $table->align = array('left', 'left', 'right'); + $table->data = array(); + + $sessions = $DB->get_records('sessions', array('userid'=>$USER->id), 'timemodified ASC'); + + foreach ($sessions as $session) { + $isyou = (session_id() === $session->sid) ? 'Yes' : 'No'; + $table->data[] = array($session->lastip, userdate($session->timemodified), $isyou); + } + + return html_writer::table($table); + } } -- 2.37.0 (Apple Git-136) From ae81ad79ba978428587199557e3913af545e1fac Mon Sep 17 00:00:00 2001 From: David Woloszyn Date: Fri, 25 Nov 2022 13:07:34 +1100 Subject: [PATCH 2/2] MDL-58353 admin: Logout on password change default to yes --- admin/settings/security.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/settings/security.php b/admin/settings/security.php index 72fac4a77d9..ec34384f410 100644 --- a/admin/settings/security.php +++ b/admin/settings/security.php @@ -126,7 +126,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page $temp->add($adminsetting); $temp->add(new admin_setting_configcheckbox('passwordchangelogout', new lang_string('passwordchangelogout', 'admin'), - new lang_string('passwordchangelogout_desc', 'admin'), 0)); + new lang_string('passwordchangelogout_desc', 'admin'), 1)); $temp->add(new admin_setting_configcheckbox('passwordchangetokendeletion', new lang_string('passwordchangetokendeletion', 'admin'), -- 2.37.0 (Apple Git-136)