Skip to content

Commit

Permalink
MDL-58353 report_usersessions: Ability to logout all other sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
davewoloszyn committed Jul 9, 2024
1 parent b1df497 commit 2e0579c
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 14 deletions.
4 changes: 2 additions & 2 deletions lang/en/moodle.php
Original file line number Diff line number Diff line change
Expand Up @@ -2076,8 +2076,8 @@
$string['showthishelpinlanguage'] = 'Show this help in language: {$a}';
$string['schedule'] = 'Schedule';
$string['sidepanel'] = 'Side panel';
$string['signoutofotherservices'] = 'Sign out everywhere';
$string['signoutofotherservices_help'] = 'If ticked, the account will be signed out of all devices and systems which use web services, such as the mobile app.';
$string['signoutofotherservices'] = 'Log out of all web apps';
$string['signoutofotherservices_help'] = 'Log out of all devices and systems that use web services, such as the mobile app. Browser sessions will remain active.';
$string['since'] = 'Since';
$string['sincelast'] = 'since last login';
$string['site'] = 'Site';
Expand Down
3 changes: 2 additions & 1 deletion login/change_password.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@

user_add_password_history($USER->id, $data->newpassword1);

if (!empty($CFG->passwordchangelogout)) {
// Log out all other sessions if mandated by admin, or if set by the user.
if (!empty($CFG->passwordchangelogout) || !empty($data->logoutothersessions)) {
\core\session\manager::kill_user_sessions($USER->id, session_id());
}

Expand Down
12 changes: 11 additions & 1 deletion login/change_password_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,20 @@ function definition() {
$mform->addRule('newpassword2', get_string('required'), 'required', null, 'client');
$mform->setType('newpassword2', PARAM_RAW);

if (empty($CFG->passwordchangetokendeletion) and !empty(webservice::get_active_tokens($USER->id))) {
$mform->addElement('checkbox', 'logoutothersessions', get_string('logoutothersessions', 'report_usersessions'));
$mform->addHelpButton('logoutothersessions', 'logoutothersessions', 'report_usersessions');
$mform->setDefault('logoutothersessions', 1);
if (!empty($CFG->passwordchangelogout)) {
$mform->getElement('logoutothersessions')->freeze();
}

if (!empty(webservice::get_active_tokens($USER->id))) {
$mform->addElement('advcheckbox', 'signoutofotherservices', get_string('signoutofotherservices'));
$mform->addHelpButton('signoutofotherservices', 'signoutofotherservices');
$mform->setDefault('signoutofotherservices', 1);
if (!empty($CFG->passwordchangetokendeletion)) {
$mform->getElement('signoutofotherservices')->freeze();
}
}

// hidden optional params
Expand Down
2 changes: 1 addition & 1 deletion login/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ function core_login_process_password_set($token) {
throw new \moodle_exception('errorpasswordupdate', 'auth');
}
user_add_password_history($user->id, $data->password);
if (!empty($CFG->passwordchangelogout)) {
if (!empty($CFG->passwordchangelogout) || !empty($data->logoutothersessions)) {
\core\session\manager::kill_user_sessions($user->id, session_id());
}
// Reset login lockout (if present) before a new password is set.
Expand Down
7 changes: 7 additions & 0 deletions login/set_password_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ public function definition() {
$mform->addRule('password2', get_string('required'), 'required', null, 'client');
$mform->setType('password2', PARAM_RAW);

$mform->addElement('checkbox', 'logoutothersessions', get_string('logoutothersessions', 'report_usersessions'));
$mform->addHelpButton('logoutothersessions', 'logoutothersessions', 'report_usersessions');
$mform->setDefault('logoutothersessions', 1);
if (!empty($CFG->passwordchangelogout)) {
$mform->getElement('logoutothersessions')->freeze();
}

// Hook for plugins to extend form definition.
$user = $this->_customdata;
core_login_extend_set_password_form($mform, $user);
Expand Down
6 changes: 5 additions & 1 deletion report/usersessions/lang/en/report_usersessions.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
* @author Petr Skoda <petr.skoda@totaralms.com>
*/

$string['logoutothersessions'] = 'Log out all other browser sessions';
$string['logoutothersessions_help'] = 'Log out of all browser sessions, except for this one. This does not affect web apps.';
$string['logoutothersessionssuccess'] = 'You have been logged out of all your other sessions';
$string['logoutsinglesessionsuccess'] = 'You have been logged out of the session at {$a}';
$string['mysessions'] = 'My active browser sessions';
$string['navigationlink'] = 'Browser sessions';
$string['mysessions'] = 'My active sessions';
$string['pluginname'] = 'User sessions report';
$string['thissession'] = 'Current session';
$string['usersessions:manageownsessions'] = 'Manage own browser sessions';
Expand Down
30 changes: 26 additions & 4 deletions report/usersessions/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,33 @@
require_capability('report/usersessions:manageownsessions', $context);

$delete = optional_param('delete', 0, PARAM_INT);
$deleteall = optional_param('deleteall', false, PARAM_BOOL);
$lastip = cleanremoteaddr(optional_param('lastip', '', PARAM_TEXT));

$PAGE->set_url('/report/usersessions/user.php');
$PAGE->set_context($context);
$PAGE->set_title(get_string('navigationlink', 'report_usersessions'));
$PAGE->set_heading(fullname($USER));
$PAGE->set_pagelayout('admin');

if ($delete and confirm_sesskey()) {
// Delete a specific session.
if ($delete && confirm_sesskey()) {
report_usersessions_kill_session($delete);
redirect($PAGE->url);
redirect(
url: $PAGE->url,
message: get_string('logoutsinglesessionsuccess', 'report_usersessions', $lastip),
messagetype: \core\output\notification::NOTIFY_SUCCESS,
);
}

// Delete all sessions except current.
if ($deleteall && confirm_sesskey()) {
\core\session\manager::kill_user_sessions($USER->id, session_id());
redirect(
url: $PAGE->url,
message: get_string('logoutothersessionssuccess', 'report_usersessions'),
messagetype: \core\output\notification::NOTIFY_SUCCESS,
);
}

// Create the breadcrumb.
Expand All @@ -79,7 +96,7 @@

} else {
$lastaccess = report_usersessions_format_duration(time() - $session->timemodified);
$url = new moodle_url($PAGE->url, array('delete' => $session->id, 'sesskey' => sesskey()));
$url = new moodle_url($PAGE->url, ['delete' => $session->id, 'sesskey' => sesskey(), 'lastip' => $session->lastip]);
$deletelink = html_writer::link($url, get_string('logout'));
}
$data[] = array(userdate($session->timecreated), $lastaccess, report_usersessions_format_ip($session->lastip), $deletelink);
Expand All @@ -91,5 +108,10 @@
$table->data = $data;
echo html_writer::table($table);

echo $OUTPUT->footer();
// Provide button to log out all other sessions.
if (count($sessions) > 1) {
$url = new moodle_url($PAGE->url, ['deleteall' => true]);
echo $OUTPUT->single_button($url, get_string('logoutothersessions', 'report_usersessions'));
}

echo $OUTPUT->footer();
8 changes: 4 additions & 4 deletions user/tests/behat/edituserpassword.feature
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ Feature: Edit a users password
# We need to cancel/submit a form that has been modified.
And I press "Create user"

Scenario: Sign out everywhere field is not present if user doesn't have active token
Scenario: Log out web apps field is not present if user doesn't have active token
Given the following "users" exist:
| username | firstname | lastname | email |
| user01 | User | One | user01@example.com |
When I am on the "user01" "user > editing" page logged in as "admin"
Then "Sign out everywhere" "field" should not exist
Then "Log out of all web apps" "field" should not exist

Scenario Outline: Sign out everywhere field is present based on expiry of active token
Scenario Outline: Log out web apps field is present based on expiry of active token
Given the following "users" exist:
| username | firstname | lastname | email |
| user01 | User | One | user01@example.com |
Expand All @@ -34,7 +34,7 @@ Feature: Edit a users password
| user | service | validuntil |
| user01 | mytestservice | <validuntil> |
When I am on the "user01" "user > editing" page logged in as "admin"
Then "Sign out everywhere" "field" <shouldornot> exist
Then "Log out of all web apps" "field" <shouldornot> exist
Examples:
| validuntil | shouldornot |
| ## -1 month ## | should not |
Expand Down

0 comments on commit 2e0579c

Please sign in to comment.