session_limit.module in Session Limit 5
Same filename and directory in other branches
Established Sessions do NOT need to verify every page load. new Session must deal w/ determining which connection is cut.
File
session_limit.moduleView source
<?php
/**
* @file
* Established Sessions do NOT need to verify every page load.
* new Session must deal w/ determining which connection is cut.
*/
/**
* Implementation of hook_settings().
*/
function session_limit_settings() {
$form = array();
$form['session_limit_max'] = array(
'#type' => 'select',
'#title' => t('Maximum sessions per user'),
'#description' => t('Select the maximum # of active sessions a user can have. 0 implies unlimited sessions.'),
'#default_value' => variable_get('session_limit_max', 1),
'#options' => range(0, 10),
);
$form['session_limit_auto_drop'] = array(
'#type' => 'checkbox',
'#title' => t('Automatically drop the oldest session without prompting.'),
'#default_value' => variable_get('session_limit_auto_drop', 0),
);
if (module_exists('masquerade')) {
$form['session_limit_masquerade_ignore'] = array(
'#type' => 'checkbox',
'#title' => t('Ignore masqueraded sessions.'),
'#description' => t("When a user administrator uses the masquerade module to impersonate a different user, it won't count against the session limit counter"),
'#default_value' => variable_get('session_limit_masquerade_ignore', false),
);
}
return system_settings_form($form);
}
/**
* Implementation of hook_help().
*/
function session_limit_help($section) {
switch ($section) {
case 'session/limit':
return t('The maximum number of simultaneous sessions (@num) for your account has been reached. You did not log off from a previous session or someone else is logged on to your account. This may indicate that your account has been compromised or that account sharing is limited on this site. Please contact the site administrator if you suspect your account has been compromised.', array(
'@num' => variable_get('session_limit_max', 1),
));
}
}
/**
* Implementation of hook_init().
*
* Determine whether session has been verified.
*/
function session_limit_init() {
global $user;
if (variable_get('session_limit_max', 1) && $user->uid > 1 && !isset($_SESSION['session_limit'])) {
// Exclude from the redirect.
if (arg(0) == 'session' && arg(1) == 'limit' || arg(0) == 'logout') {
return;
}
if (module_exists('masquerade') && variable_get('session_limit_masquerade_ignore', false)) {
$result = db_query('SELECT COUNT(s.uid) FROM {sessions} AS s
LEFT JOIN {masquerade} AS m ON s.uid = m.uid_as AND s.sid = m.sid
WHERE s.uid = %d AND m.sid IS NULL', $user->uid);
}
else {
$result = db_query('SELECT COUNT(*) FROM {sessions} WHERE uid = %d', $user->uid);
}
if (db_result($result) > variable_get('session_limit_max', 1)) {
// redirect to session handler.
drupal_goto('session/limit');
}
else {
// mark session as verified to bypass this in future.
$_SESSION['session_limit'] = TRUE;
}
}
}
/**
* Implementation of hook_menu().
* Redirect user if over session limit.
*/
function session_limit_menu($may_cache) {
global $user;
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'session/limit',
'title' => t('Session Limit Exceeded'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'session_limit_page',
),
'access' => TRUE,
'type' => MENU_CALLBACK,
);
if ($user->uid) {
$items[] = array(
'path' => 'mysessions',
'title' => t('My sessions'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'session_limit_page',
),
'access' => TRUE,
'type' => MENU_SUGGESTED_ITEM,
);
}
$items[] = array(
'path' => 'admin/settings/session_limit',
'title' => t('Session Limit'),
'description' => t('Configure session limits.'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'session_limit_settings',
),
);
}
return $items;
}
/**
* Display/Delete sessions..
*/
function session_limit_page() {
global $user;
if (!$user->uid > 0) {
drupal_goto();
}
if (variable_get('session_limit_auto_drop', 0)) {
// Get the oldest session.
$sid = db_result(db_query_range("SELECT sid FROM {sessions} WHERE uid = %d ORDER BY timestamp", $user->uid, 0, 1));
if ($sid) {
_session_limit_disconnect($sid);
}
drupal_goto();
}
$result = db_query('SELECT * FROM {sessions} WHERE uid = %d', $user->uid);
while ($obj = db_fetch_object($result)) {
if ($user->sid == $obj->sid) {
$message = t('Your current session.');
}
else {
unset($message);
}
$sids[$obj->sid] = t('<strong>Host:</strong> %host (idle: %time) <b>@message</b>', array(
'%host' => $obj->hostname,
'@message' => $message,
'%time' => format_interval(time() - $obj->timestamp),
));
}
$form['sid'] = array(
'#type' => 'radios',
'#title' => t('Select a session to disconnect'),
'#options' => $sids,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Disconnect'),
);
return $form;
}
/**
* Handler for submissions from session_limit_page().
*/
function session_limit_page_submit($form_id, $form_values) {
global $user;
if ($user->sid == $form_values['sid']) {
// force a normal logout for ourself.
drupal_set_message(t('Your session has been disconnected.'));
drupal_goto('logout');
}
else {
_session_limit_disconnect($form_values['sid']);
drupal_set_message(t('Session has been disconnected.'));
// redirect to main page.
drupal_goto();
}
}
/**
* Logout a specific session id and leave them a message.
*/
function _session_limit_disconnect($sid) {
$logout_message = <<<EOM
You have been automatically logged out.
Someone else has logged in with your username and password and the maximum number of @num simultaneous sessions was exceeded.
This may indicate that your account has been compromised or that account sharing is not allowed on this site.
Please contact the site administrator if you suspect your account has been compromised.
EOM;
$logout_message = 'messages|' . serialize(array(
'error' => array(
t($logout_message, array(
'@num' => variable_get('session_limit_max', 1),
)),
),
));
db_query("UPDATE {sessions} SET uid = 0, session = '%s' WHERE sid = '%s'", $logout_message, $sid);
}
Functions
Name | Description |
---|---|
session_limit_help | Implementation of hook_help(). |
session_limit_init | Implementation of hook_init(). |
session_limit_menu | Implementation of hook_menu(). Redirect user if over session limit. |
session_limit_page | Display/Delete sessions.. |
session_limit_page_submit | Handler for submissions from session_limit_page(). |
session_limit_settings | Implementation of hook_settings(). |
_session_limit_disconnect | Logout a specific session id and leave them a message. |