forked from extern/egroupware
* Admin: session-list is generated now from egw_access_log table independent of readablity of sessions files in filesystem
- session_(dla|action) is stored in egw_access_log table - notifications refresh via ajax set notification_heartbeat timestamp in egw_access_log - if notification_heartbeat is set (happens only for browser sessions with popup notification) sessions get removed from session list one minute after browser is closed - new static method egw_session::notifications_active($account_id) to check if given user has an open browser with notifications popup checking, to ensure popup notifications can fall back to email --> REQUIRES DATABASE UPDATE / SETUP
This commit is contained in:
parent
aecfe9d768
commit
5495491e78
@ -1,17 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* eGgroupWare admin - accesslog
|
||||
* EGgroupware admin - access- and session-log
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @package admin
|
||||
* @copyright (c) 2009 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2009-11 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Show eGroupware access log
|
||||
* Show EGroupware access- and session-log
|
||||
*/
|
||||
class admin_accesslog
|
||||
{
|
||||
@ -22,6 +22,7 @@ class admin_accesslog
|
||||
*/
|
||||
public $public_functions = array(
|
||||
'index' => true,
|
||||
'sessions' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
@ -46,10 +47,6 @@ class admin_accesslog
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
if ($GLOBALS['egw']->acl->check('access_log_access',1,'admin'))
|
||||
{
|
||||
$GLOBALS['egw']->redirect_link('/index.php');
|
||||
}
|
||||
$this->so = new so_sql(self::APP,self::TABLE,null,'',true);
|
||||
}
|
||||
|
||||
@ -63,34 +60,81 @@ class admin_accesslog
|
||||
*/
|
||||
function get_rows($query,&$rows,&$readonlys)
|
||||
{
|
||||
$heartbeat_limit = egw_session::heartbeat_limit();
|
||||
|
||||
if ($query['session_list']) // filter active sessions
|
||||
{
|
||||
$query['col_filter']['lo'] = null; // not logged out
|
||||
$query['col_filter'][0] = 'session_dla > '.(int)(time() - $GLOBALS['egw_info']['server']['sessions_timeout']);
|
||||
$query['col_filter'][1] = "(notification_heartbeat IS NULL OR notification_heartbeat > $heartbeat_limit)";
|
||||
}
|
||||
$total = $this->so->get_rows($query,$rows,$readonlys);
|
||||
|
||||
$no_kill = !$GLOBALS['egw']->acl->check('current_sessions_access',8,'admin') && !$query['session_list'];
|
||||
|
||||
foreach($rows as &$row)
|
||||
{
|
||||
$row['sessionstatus'] = lang('success');
|
||||
if (stripos($row['sessionid'],'blocked') !== False || stripos($row['sessionid'],'bad login') !== False)
|
||||
if ($row['notification_heartbeat'] > $heartbeat_limit)
|
||||
{
|
||||
$row['sessionstatus'] = $row['sessionid'];
|
||||
$row['sessionstatus'] = lang('active');
|
||||
}
|
||||
if (stripos($row['session_php'],'blocked') !== false ||
|
||||
stripos($row['session_php'],'bad login') !== false ||
|
||||
strpos($row['sessioin_php'],' ') !== false)
|
||||
{
|
||||
$row['sessionstatus'] = $row['session_php'];
|
||||
}
|
||||
if ($row['lo']) {
|
||||
$row['total'] = ($row['lo'] - $row['li']) / 60;
|
||||
$row['sessionstatus'] = lang('logged out');
|
||||
}
|
||||
// eg. for bad login or password
|
||||
if (!$row['account_id']) $row['alt_loginid'] = $row['loginid'];
|
||||
|
||||
$readonlys['kill['.$row['sessionid'].']'] = $no_kill;
|
||||
$readonlys['delete['.$row['sessionid'].']'] = $query['session_list'];
|
||||
|
||||
// do not allow to kill or select own session
|
||||
if ($GLOBALS['egw']->session->sessionid_access_log == $row['sessionid'] && $query['session_list'])
|
||||
{
|
||||
$readonlys['kill['.$row['sessionid'].']'] = $readonlys['selected['.$row['sessionid'].']'] = true;
|
||||
}
|
||||
// do not allow to delete access log off active sessions
|
||||
if (!$row['lo'] && $row['session_dla'] > time()-$GLOBALS['egw_info']['server']['sessions_timeout'] && !$query['session_list'])
|
||||
{
|
||||
$readonlys['delete['.$row['sessionid'].']'] = $readonlys['selected['.$row['sessionid'].']'] = true;
|
||||
}
|
||||
unset($row['session_php']); // for security reasons, do NOT give real PHP sessionid to UI
|
||||
}
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('Admin').' - '.lang('View Access Log').
|
||||
if ($query['session_list'])
|
||||
{
|
||||
$rows['no_total'] = $rows['no_lo'] = true;
|
||||
}
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('Admin').' - '.
|
||||
($query['session_list'] ? lang('View sessions') : lang('View Access Log')).
|
||||
($query['col_filter']['account_id'] ? ': '.common::grab_owner_name($query['col_filter']['account_id']) : '');
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the accesslog
|
||||
* Display the access log or session list
|
||||
*
|
||||
* @param array $content
|
||||
* @param array $content=null
|
||||
* @param string $msg=''
|
||||
* @param boolean $sessions_list=false
|
||||
*/
|
||||
function index(array $content=null)
|
||||
function index(array $content=null, $msg='', $sessions_list=false)
|
||||
{
|
||||
//_debug_array($content);
|
||||
if (is_array($content)) $sessions_list = $content['nm']['session_list'];
|
||||
|
||||
// check if user has access to requested functionality
|
||||
if ($GLOBALS['egw']->acl->check($sessions_list ? 'current_sessions_access' : 'access_log_access',1,'admin'))
|
||||
{
|
||||
$GLOBALS['egw']->redirect_link('/index.php');
|
||||
}
|
||||
|
||||
if(!isset($content))
|
||||
{
|
||||
@ -114,32 +158,71 @@ class admin_accesslog
|
||||
{
|
||||
$content['nm']['col_filter']['account_id'] = (int)$_GET['account_id'];
|
||||
}
|
||||
if ($sessions_list)
|
||||
{
|
||||
$content['nm']['order'] = 'session_dla';
|
||||
$content['nm']['options-selectcols'] = array(
|
||||
'lo' => false,
|
||||
'total' => false,
|
||||
);
|
||||
}
|
||||
$content['nm']['session_list'] = $sessions_list;
|
||||
}
|
||||
elseif(isset($content['nm']['rows']['delete']))
|
||||
elseif(isset($content['nm']['rows']['delete']) || isset($content['delete']))
|
||||
{
|
||||
list($sessionid) = each($content['nm']['rows']['delete']);
|
||||
unset($content['nm']['rows']['delete']);
|
||||
if (isset($content['nm']['rows']['delete']))
|
||||
{
|
||||
list($sessionid) = each($content['nm']['rows']['delete']);
|
||||
unset($content['nm']['rows']['delete']);
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($content['delete']);
|
||||
$sessionid = $content['nm']['rows']['selected'];
|
||||
}
|
||||
if ($sessionid && $this->so->delete(array('sessionid' => $sessionid)))
|
||||
{
|
||||
$content['msg'] = lang('%1 log entries deleted.',1);
|
||||
$msg = lang('%1 log entries deleted.',1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$content['msg'] = lang('Error deleting log entry!');
|
||||
$msg = lang('Error deleting log entry!');
|
||||
}
|
||||
}
|
||||
elseif(isset($content['delete']))
|
||||
elseif(isset($content['nm']['rows']['kill']) || isset($content['kill']))
|
||||
{
|
||||
unset($content['delete']);
|
||||
if (($deleted = $this->so->delete(array('sessionid' => $content['nm']['rows']['selected']))))
|
||||
if (isset($content['nm']['rows']['kill']))
|
||||
{
|
||||
$content['msg'] = lang('%1 log entries deleted.',$deleted);
|
||||
list($sessionid) = each($content['nm']['rows']['kill']);
|
||||
$sessionid = array($sessionid);
|
||||
unset($content['nm']['rows']['kill']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$content['msg'] = lang('Error deleting log entry!');
|
||||
unset($content['kill']);
|
||||
$sessionid = $content['nm']['rows']['selected'];
|
||||
}
|
||||
if (($key = array_search($GLOBALS['egw']->session->sessionid_access_log, $sessionid)))
|
||||
{
|
||||
unset($sessionid[$key]); // dont allow to kill own sessions
|
||||
}
|
||||
if ($GLOBALS['egw']->acl->check('current_sessions_access',8,'admin'))
|
||||
{
|
||||
$msg = lang('Permission denied!');
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach((array)$sessionid as $id)
|
||||
{
|
||||
$GLOBALS['egw']->session->destroy($id);
|
||||
}
|
||||
$msg = lang('%1 sessions killed',count($sessionid));
|
||||
}
|
||||
}
|
||||
$readonlys['kill'] = !$sessions_list;
|
||||
$readonlys['delete'] = $sessions_list;
|
||||
|
||||
$content['msg'] = $msg;
|
||||
$content['percent'] = 100.0 * $GLOBALS['egw']->db->query(
|
||||
'SELECT ((SELECT COUNT(*) FROM '.self::TABLE.' WHERE lo != 0) / COUNT(*)) FROM '.self::TABLE,
|
||||
__LINE__,__FILE__)->fetchColumn();
|
||||
@ -149,4 +232,15 @@ class admin_accesslog
|
||||
'nm' => $content['nm'],
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display session list
|
||||
*
|
||||
* @param array $content=null
|
||||
* @param string $msg=''
|
||||
*/
|
||||
function sessions(array $content=null, $msg='')
|
||||
{
|
||||
return $this->index(null,$msg,true);
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ class admin_prefs_sidebox_hooks
|
||||
|
||||
if (! $GLOBALS['egw']->acl->check('current_sessions_access',1,'admin'))
|
||||
{
|
||||
$file['View Sessions'] = egw::link('/index.php','menuaction=admin.uicurrentsessions.list_sessions');
|
||||
$file['View Sessions'] = egw::link('/index.php','menuaction=admin.admin_accesslog.sessions');
|
||||
}
|
||||
|
||||
if (! $GLOBALS['egw']->acl->check('access_log_access',1,'admin'))
|
||||
|
@ -1,71 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Administration *
|
||||
* http://www.egroupware.org *
|
||||
* This file written by Joseph Engo <jengo@phpgroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
class bocurrentsessions
|
||||
{
|
||||
var $ui;
|
||||
var $so;
|
||||
var $public_functions = array(
|
||||
'kill' => True
|
||||
);
|
||||
|
||||
function total()
|
||||
{
|
||||
return $GLOBALS['egw']->session->session_count();
|
||||
}
|
||||
|
||||
function list_sessions($start,$order,$sort)
|
||||
{
|
||||
$values = $GLOBALS['egw']->session->session_list($start,$sort,$order);
|
||||
|
||||
while (list(,$value) = @each($values))
|
||||
{
|
||||
if (strpos($value['session_lid'],'@') !== false)
|
||||
{
|
||||
$t = explode('@',$value['session_lid']);
|
||||
$session_lid = $t[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$session_lid = $value['session_lid'];
|
||||
}
|
||||
$tmp = time() - $value['session_dla'];
|
||||
$secs = $tmp % 60;
|
||||
$mins = (($tmp - $secs) % 3600) / 60;
|
||||
$hours = ($tmp - ($mins * 60) - $secs) / 3600;
|
||||
$_values[] = array(
|
||||
'session_id' => $value['session_id'],
|
||||
'session_lid' => $session_lid,
|
||||
'session_ip' => $value['session_ip'],
|
||||
'session_logintime' => $GLOBALS['egw']->common->show_date($value['session_logintime']),
|
||||
'session_action' => $value['session_action'],
|
||||
'session_dla' => $value['session_dla'],
|
||||
'session_idle' => str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' . str_pad($mins, 2, '0', STR_PAD_LEFT) . ':' . str_pad($secs, 2, '0', STR_PAD_LEFT)
|
||||
);
|
||||
}
|
||||
return $_values;
|
||||
}
|
||||
|
||||
function kill()
|
||||
{
|
||||
if ($_GET['ksession'] &&
|
||||
($GLOBALS['sessionid'] != $_GET['ksession']) &&
|
||||
! $GLOBALS['egw']->acl->check('current_sessions_access',8,'admin'))
|
||||
{
|
||||
$GLOBALS['egw']->session->destroy($_GET['ksession'],0);
|
||||
}
|
||||
$this->ui =& CreateObject('admin.uicurrentsessions');
|
||||
$this->ui->list_sessions();
|
||||
}
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Administration *
|
||||
* http://www.egroupware.org *
|
||||
* This file written by Joseph Engo <jengo@phpgroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
class uicurrentsessions
|
||||
{
|
||||
var $template;
|
||||
var $bo;
|
||||
var $public_functions = array(
|
||||
'list_sessions' => True,
|
||||
'kill' => True
|
||||
);
|
||||
|
||||
function uicurrentsessions()
|
||||
{
|
||||
if ($GLOBALS['egw']->acl->check('current_sessions_access',1,'admin'))
|
||||
{
|
||||
$GLOBALS['egw']->redirect_link('/index.php');
|
||||
}
|
||||
$this->template =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
|
||||
$this->bo =& CreateObject('admin.bocurrentsessions');
|
||||
$this->nextmatchs =& CreateObject('phpgwapi.nextmatchs');
|
||||
}
|
||||
|
||||
function header()
|
||||
{
|
||||
$GLOBALS['egw']->common->egw_header();
|
||||
echo parse_navbar();
|
||||
}
|
||||
|
||||
function store_location($info)
|
||||
{
|
||||
$GLOBALS['egw']->session->appsession('currentsessions_session_data','admin',$info);
|
||||
}
|
||||
|
||||
function list_sessions()
|
||||
{
|
||||
$info = $GLOBALS['egw']->session->appsession('currentsessions_session_data','admin');
|
||||
if (! is_array($info))
|
||||
{
|
||||
$info = array(
|
||||
'start' => 0,
|
||||
'sort' => 'DESC',
|
||||
'order' => 'session_dla'
|
||||
);
|
||||
$this->store_location($info);
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['start']) || $_REQUEST['sort'] || $_REQUEST['order'])
|
||||
{
|
||||
if ($_REQUEST['start'] == 0 || $_REQUEST['start'] && $_REQUEST['start'] != $info['start'])
|
||||
{
|
||||
$info['start'] = $_REQUEST['start'];
|
||||
}
|
||||
|
||||
if ($_REQUEST['sort'] && $_REQUEST['sort'] != $info['sort'])
|
||||
{
|
||||
$info['sort'] = $_REQUEST['sort'];
|
||||
}
|
||||
|
||||
if ($_REQUEST['order'] && $_REQUEST['order'] != $info['order'])
|
||||
{
|
||||
$info['order'] = $_REQUEST['order'];
|
||||
}
|
||||
|
||||
$this->store_location($info);
|
||||
}
|
||||
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('Admin').' - '.lang('List of current users');
|
||||
$this->header();
|
||||
|
||||
$this->template->set_file('current','currentusers.tpl');
|
||||
$this->template->set_block('current','list','list');
|
||||
$this->template->set_block('current','row','row');
|
||||
|
||||
$can_view_action = !$GLOBALS['egw']->acl->check('current_sessions_access',2,'admin');
|
||||
$can_view_ip = !$GLOBALS['egw']->acl->check('current_sessions_access',4,'admin');
|
||||
$can_kill = !$GLOBALS['egw']->acl->check('current_sessions_access',8,'admin');
|
||||
|
||||
$total = $this->bo->total();
|
||||
|
||||
$this->template->set_var('left_next_matchs',$this->nextmatchs->left('/admin/currentusers.php',$info['start'],$total));
|
||||
$this->template->set_var('right_next_matchs',$this->nextmatchs->right('/admin/currentusers.php',$info['start'],$total));
|
||||
$this->template->set_var('start_total',$this->nextmatchs->show_hits($total,$info['start']));
|
||||
|
||||
$this->template->set_var('sort_loginid',$this->nextmatchs->show_sort_order($info['sort'],'session_lid',$info['order'],
|
||||
'/admin/currentusers.php',lang('LoginID')));
|
||||
$this->template->set_var('sort_ip',$this->nextmatchs->show_sort_order($info['sort'],'session_ip',$info['order'],
|
||||
'/admin/currentusers.php',lang('IP')));
|
||||
$this->template->set_var('sort_login_time',$this->nextmatchs->show_sort_order($info['sort'],'session_logintime',$info['order'],
|
||||
'/admin/currentusers.php',lang('Login Time')));
|
||||
$this->template->set_var('sort_action',$this->nextmatchs->show_sort_order($info['sort'],'session_action',$info['order'],
|
||||
'/admin/currentusers.php',lang('Action')));
|
||||
$this->template->set_var('sort_idle',$this->nextmatchs->show_sort_order($info['sort'],'session_dla',$info['order'],
|
||||
'/admin/currentusers.php',lang('idle')));
|
||||
$this->template->set_var('lang_kill',lang('Kill'));
|
||||
|
||||
$values = $this->bo->list_sessions($info['start'],$info['order'],$info['sort']);
|
||||
|
||||
while (list(,$value) = @each($values))
|
||||
{
|
||||
$this->nextmatchs->template_alternate_row_color($this->template);
|
||||
|
||||
$this->template->set_var('row_loginid',$value['session_lid']);
|
||||
|
||||
$this->template->set_var('row_ip',$can_view_ip?$value['session_ip']:' ');
|
||||
|
||||
$this->template->set_var('row_logintime',$value['session_logintime']);
|
||||
$this->template->set_var('row_idle',$value['session_idle']);
|
||||
|
||||
if ($value['session_action'] && $can_view_action)
|
||||
{
|
||||
$this->template->set_var('row_action',$GLOBALS['egw']->strip_html($value['session_action']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->template->set_var('row_action',' ');
|
||||
}
|
||||
|
||||
if ($value['session_id'] != $GLOBALS['egw_info']['user']['sessionid'] && $can_kill)
|
||||
{
|
||||
$this->template->set_var('row_kill','<a href="' . $GLOBALS['egw']->link('/index.php','menuaction=admin.uicurrentsessions.kill&ksession='
|
||||
. $value['session_id'] . '&kill=true') . '">' . lang('Kill').'</a>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->template->set_var('row_kill',' ');
|
||||
}
|
||||
|
||||
$this->template->parse('rows','row',True);
|
||||
}
|
||||
|
||||
$this->template->pfp('out','list');
|
||||
}
|
||||
|
||||
function kill()
|
||||
{
|
||||
if ($GLOBALS['egw']->acl->check('current_sessions_access',8,'admin'))
|
||||
{
|
||||
$GLOBALS['egw']->redirect_link('/index.php');
|
||||
}
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('Admin').' - '.lang('Kill session');
|
||||
$this->header();
|
||||
$this->template->set_file('form','kill_session.tpl');
|
||||
|
||||
$this->template->set_var('lang_message',lang('Are you sure you want to kill this session ?'));
|
||||
$this->template->set_var('link_no','<a href="' . $GLOBALS['egw']->link('/index.php','menuaction=admin.uicurrentsessions.list_sessions') . '">' . lang('No') . '</a>');
|
||||
$this->template->set_var('link_yes','<a href="' . $GLOBALS['egw']->link('/index.php','menuaction=admin.bocurrentsessions.kill&ksession=' . $_GET['ksession']) . '">' . lang('Yes') . '</a>');
|
||||
|
||||
$this->template->pfp('out','form');
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
%1 log entries deleted. admin de %1 Protokolleinträge gelöscht.
|
||||
%1 not found or not executable !!! admin de %1 nicht gefunden oder nicht ausführbar !!!
|
||||
%1 rights for %2 and applications %3 admin de %1 Rechte für %2 und Anwendung(en) %3
|
||||
%1 sessions killed admin de %1 Sitzungen beendet
|
||||
%1 user %2 admin de %1 Benutzer %2
|
||||
(default no, leave it off if you dont use it) admin de (Vorgabe Nein, ausgeschaltet lassen, wenn nicht benutzt)
|
||||
(stored password will not be shown here) admin de (Gespeichertes Passwort wird hier nicht angezeigt)
|
||||
@ -28,8 +29,8 @@ account preferences admin de Einstellungen der Benutzerkonten
|
||||
account-id's have to be integers! admin de Konten-ID`s müssen vom Typ Integer (Zahl) sein!
|
||||
acl manager admin de ACL-Manager
|
||||
acl rights common de ACL-Rechte
|
||||
action admin de Aktion
|
||||
actions admin de Aktionen
|
||||
action admin de Befehl
|
||||
actions admin de Befehle
|
||||
activate wysiwyg-editor admin de WYSIWYG Editor (formatierter Text) aktivieren
|
||||
add a category admin de Eine Kategorie hinzufügen
|
||||
add a group admin de Eine Gruppe hinzufügen
|
||||
@ -160,6 +161,7 @@ delete peer server admin de Server von Serververbund löschen
|
||||
delete selected entries admin de Ausgewählte Einträge löschen
|
||||
delete the category admin de Kategorie löschen
|
||||
delete the group admin de Gruppe löschen
|
||||
delete the selected entries admin de Die ausgewählten Einträge löschen
|
||||
delete this category admin de Kategorie löschen
|
||||
delete this group admin de Gruppe löschen
|
||||
delete this log entry admin de Diesen Protokolleintrag löschen
|
||||
@ -330,6 +332,7 @@ kill admin de Beenden
|
||||
kill session admin de Sitzung beenden
|
||||
last %1 logins admin de Letze %1 Logins
|
||||
last %1 logins for %2 admin de Letze %1 Logins für %2
|
||||
last action admin de Letzte Aktion
|
||||
last login admin de Letzter Login
|
||||
last login from admin de Letzer Login von
|
||||
last submission: admin de Letzte Absendung:
|
||||
|
@ -7,6 +7,7 @@
|
||||
%1 log entries deleted. admin en %1 log entries deleted.
|
||||
%1 not found or not executable !!! admin en %1 not found or not executable !!!
|
||||
%1 rights for %2 and applications %3 admin en %1 rights for %2 and applications %3
|
||||
%1 sessions killed admin en %1 sessions killed
|
||||
%1 user %2 admin en %1 user %2
|
||||
(default no, leave it off if you dont use it) admin en (default No, leave it off if you dont use it)
|
||||
(stored password will not be shown here) admin en (Stored password will not be shown here)
|
||||
@ -160,6 +161,7 @@ delete peer server admin en Delete peer server
|
||||
delete selected entries admin en Delete selected entries
|
||||
delete the category admin en delete the category
|
||||
delete the group admin en delete the group
|
||||
delete the selected entries admin en Delete the selected entries
|
||||
delete this category admin en delete this category
|
||||
delete this group admin en delete this group
|
||||
delete this log entry admin en Delete this log entry
|
||||
@ -330,6 +332,7 @@ kill admin en Kill
|
||||
kill session admin en Kill session
|
||||
last %1 logins admin en Last %1 logins
|
||||
last %1 logins for %2 admin en Last %1 logins for %2
|
||||
last action admin en Last action
|
||||
last login admin en last login
|
||||
last login from admin en last login from
|
||||
last submission: admin en Last submission:
|
||||
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* eGroupWare - eTemplates for Application admin
|
||||
* http://www.egroupware.org
|
||||
* generated by soetemplate::dump4setup() 2011-04-12 09:22
|
||||
* generated by soetemplate::dump4setup() 2011-04-13 15:34
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package admin
|
||||
@ -12,11 +12,11 @@
|
||||
|
||||
$templ_version=1;
|
||||
|
||||
$templ_data[] = array('name' => 'admin.accesslog','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:5:"align";s:6:"center";s:4:"name";s:3:"msg";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:4:{s:4:"type";s:9:"nextmatch";s:4:"size";s:4:"rows";s:4:"name";s:2:"nm";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"type";s:5:"label";s:5:"label";s:32:"Percent of users that logged out";s:8:"readonly";s:1:"1";}i:2;a:5:{s:4:"type";s:5:"float";s:4:"name";s:7:"percent";s:4:"size";s:4:",,,1";s:5:"label";s:6:": %s %";s:8:"readonly";s:1:"1";}}s:1:"B";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";s:5:"align";s:5:"right";i:1;a:6:{s:4:"type";s:6:"button";s:4:"name";s:6:"delete";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"help";s:23:"Delete selected entries";s:7:"onclick";s:46:"return confirm(\'Delete the selected entries\');";}i:2;a:4:{s:4:"type";s:10:"buttononly";s:4:"size";s:9:"arrow_ltr";s:7:"onclick";s:71:"toggle_all(this.form,form::name(\'nm[rows][selected][]\')); return false;";s:4:"span";s:15:",selectAllArrow";}}}}s:4:"rows";i:3;s:4:"cols";i:2;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '.selectAllArrow { padding-right: 12px; }','modified' => '1240661952',);
|
||||
$templ_data[] = array('name' => 'admin.accesslog','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:2:{s:1:"A";a:4:{s:4:"span";s:13:"all,redItalic";s:5:"align";s:6:"center";s:4:"name";s:3:"msg";s:4:"type";s:5:"label";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:4:{s:4:"span";s:3:"all";s:4:"name";s:2:"nm";s:4:"size";s:20:"admin.accesslog.rows";s:4:"type";s:9:"nextmatch";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:4:{s:4:"size";s:6:"2,,0,0";s:4:"type";s:4:"hbox";i:1;a:3:{s:8:"readonly";s:4:"true";s:4:"type";s:5:"label";s:5:"label";s:32:"Percent of users that logged out";}i:2;a:6:{s:4:"type";s:5:"float";s:9:"precision";s:1:"1";s:5:"label";s:6:": %s %";s:8:"readonly";s:4:"true";s:4:"name";s:7:"percent";s:4:"size";s:1:",";}}s:1:"B";a:6:{s:5:"align";s:5:"right";s:4:"type";s:4:"hbox";i:1;a:6:{s:5:"label";s:6:"Delete";s:7:"onclick";s:46:"return confirm(\'Delete the selected entries\');";s:4:"name";s:6:"delete";s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:4:"help";s:23:"Delete selected entries";}i:2;a:5:{s:4:"type";s:6:"button";s:4:"size";s:5:"close";s:5:"label";s:4:"Kill";s:4:"name";s:4:"kill";s:7:"onclick";s:63:"return confirm(\'Are you sure you want to kill this session ?\');";}s:4:"size";s:1:"3";i:3;a:4:{s:4:"type";s:10:"buttononly";s:4:"size";s:9:"arrow_ltr";s:5:"label";s:10:"Select all";s:7:"onclick";s:61:"toggle_all(this.form,form::name(\'selected[]\')); return false;";}}}}s:4:"cols";i:2;s:4:"rows";i:3;s:4:"size";s:4:"100%";}}','size' => '100%','style' => '.selectAllArrow { padding-right: 12px; }','modified' => '1302686599',);
|
||||
|
||||
$templ_data[] = array('name' => 'admin.accesslog.get_rows','template' => '','lang' => '','group' => '0','version' => '1.3.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:2:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";}i:1;a:4:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:7:"LoginID";s:4:"name";s:7:"loginid";}s:1:"B";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:2:"IP";s:4:"name";s:2:"ip";}s:1:"C";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:9:"Logintime";s:4:"name";s:2:"li";}s:1:"D";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:9:"Logoutime";s:4:"name";s:2:"lo";}}i:2;a:4:{s:1:"A";a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:15:"${row}[loginid]";s:8:"readonly";s:1:"1";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:4:"name";s:10:"${row}[ip]";s:7:"no_lang";s:1:"1";}s:1:"C";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[li]";s:8:"readonly";s:1:"1";}s:1:"D";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[lo]";s:8:"readonly";s:1:"1";}}}s:4:"rows";i:2;s:4:"cols";i:4;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1164479930',);
|
||||
|
||||
$templ_data[] = array('name' => 'admin.accesslog.rows','template' => '','lang' => '','group' => '0','version' => '1.7.002','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:3:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:1:"H";s:2:"1%";}i:1;a:8:{s:1:"A";a:3:{s:4:"type";s:23:"nextmatch-accountfilter";s:4:"size";s:7:"LoginID";s:4:"name";s:10:"account_id";}s:1:"B";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:12:"Login-Status";s:4:"name";s:13:"sessionstatus";}s:1:"C";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:7:"Loginid";s:4:"name";s:7:"loginid";}s:1:"D";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:2:"IP";s:4:"name";s:2:"ip";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Login";s:4:"name";s:2:"li";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:6:"Logout";s:4:"name";s:2:"lo";}s:1:"G";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:5:"Total";s:4:"name";s:5:"total";}s:1:"H";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:5:"label";s:5:"label";s:6:"Action";s:5:"align";s:6:"center";}i:2;a:4:{s:4:"type";s:10:"buttononly";s:4:"size";s:5:"check";s:5:"label";s:10:"Select all";s:7:"onclick";s:61:"toggle_all(this.form,form::name(\'selected[]\')); return false;";}}}i:2;a:8:{s:1:"A";a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:18:"${row}[account_id]";s:8:"readonly";s:1:"1";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:21:"${row}[sessionstatus]";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[loginid]";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:4:"name";s:10:"${row}[ip]";}s:1:"E";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[li]";s:8:"readonly";s:1:"1";}s:1:"F";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[lo]";s:8:"readonly";s:1:"1";}s:1:"G";a:4:{s:4:"type";s:13:"date-duration";s:4:"name";s:13:"${row}[total]";s:8:"readonly";s:1:"1";s:4:"size";s:6:",hm,24";}s:1:"H";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:6:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:28:"delete[$row_cont[sessionid]]";s:4:"help";s:21:"Delete this log entry";s:7:"onclick";s:40:"return confirm(\'Delete this log entry\');";}i:2;a:3:{s:4:"type";s:8:"checkbox";s:4:"size";s:20:"$row_cont[sessionid]";s:4:"name";s:10:"selected[]";}s:5:"align";s:6:"center";}}}s:4:"rows";i:2;s:4:"cols";i:8;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1254816462',);
|
||||
$templ_data[] = array('name' => 'admin.accesslog.rows','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:6:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:1:"G";s:10:",@no_total";s:1:"F";s:7:",@no_lo";s:1:"B";s:18:",@no_sessionstatus";s:1:"J";s:2:"1%";}i:1;a:10:{s:1:"A";a:3:{s:4:"type";s:23:"nextmatch-accountfilter";s:4:"size";s:7:"LoginID";s:4:"name";s:10:"account_id";}s:1:"B";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:12:"Login-Status";s:4:"name";s:13:"sessionstatus";}s:1:"C";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:7:"Loginid";s:4:"name";s:7:"loginid";}s:1:"D";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:2:"IP";s:4:"name";s:2:"ip";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Login";s:4:"name";s:2:"li";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:6:"Logout";s:4:"name";s:2:"lo";}s:1:"G";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:5:"Total";s:4:"name";s:5:"total";}s:1:"H";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Idle";s:4:"name";s:11:"session_dla";}s:1:"I";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:11:"Last action";s:4:"name";s:14:"session_action";}s:1:"J";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";s:5:"align";s:6:"center";}i:2;a:4:{s:4:"type";s:10:"buttononly";s:4:"size";s:5:"check";s:5:"label";s:10:"Select all";s:7:"onclick";s:61:"toggle_all(this.form,form::name(\'selected[]\')); return false;";}}}i:2;a:10:{s:1:"A";a:4:{s:4:"type";s:14:"select-account";s:4:"name";s:18:"${row}[account_id]";s:8:"readonly";s:1:"1";s:5:"label";s:22:"$row_cont[alt_loginid]";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:21:"${row}[sessionstatus]";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[loginid]";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:4:"name";s:10:"${row}[ip]";}s:1:"E";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[li]";s:8:"readonly";s:1:"1";}s:1:"F";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:10:"${row}[lo]";s:8:"readonly";s:1:"1";}s:1:"G";a:4:{s:4:"type";s:13:"date-duration";s:4:"name";s:13:"${row}[total]";s:8:"readonly";s:1:"1";s:4:"size";s:6:",hm,24";}s:1:"H";a:3:{s:4:"type";s:10:"date-since";s:4:"name";s:19:"${row}[session_dla]";s:8:"readonly";s:1:"1";}s:1:"I";a:2:{s:4:"type";s:5:"label";s:4:"name";s:22:"${row}[session_action]";}s:1:"J";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"3,,0,0";i:1;a:6:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:28:"delete[$row_cont[sessionid]]";s:4:"help";s:21:"Delete this log entry";s:7:"onclick";s:40:"return confirm(\'Delete this log entry\');";}i:2;a:5:{s:4:"type";s:6:"button";s:4:"size";s:5:"close";s:5:"label";s:4:"Kill";s:4:"name";s:26:"kill[$row_cont[sessionid]]";s:7:"onclick";s:63:"return confirm(\'Are you sure you want to kill this session ?\');";}s:5:"align";s:6:"center";i:3;a:4:{s:4:"type";s:8:"checkbox";s:4:"size";s:20:"$row_cont[sessionid]";s:4:"name";s:10:"selected[]";s:5:"align";s:5:"right";}}}}s:4:"rows";i:2;s:4:"cols";i:10;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1254816462',);
|
||||
|
||||
$templ_data[] = array('name' => 'admin.applications','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:4:{s:4:"type";s:9:"nextmatch";s:4:"size";s:4:"rows";s:4:"span";s:3:"all";s:4:"name";s:2:"nm";}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:6:"button";s:5:"label";s:28:"Number applications serially";s:4:"name";s:6:"number";}i:2;a:2:{s:4:"type";s:5:"label";s:5:"label";s:157:"Number the applications serially. If they are not numbered serially, sorting the applications could work wrong. This will not change the application\'s order.";}}}}s:4:"rows";i:2;s:4:"cols";i:1;s:4:"size";s:7:"100%,,0";s:7:"options";a:2:{i:0;s:4:"100%";i:2;s:1:"0";}}}','size' => '100%,,0','style' => '','modified' => '1276610727',);
|
||||
|
||||
|
@ -1,45 +1,58 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="admin.accesslog.rows" template="" lang="" group="0" version="1.7.001">
|
||||
<template id="admin.accesslog.rows" template="" lang="" group="0" version="1.9.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
<column disabled="@no_sessionstatus"/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column disabled="@no_lo"/>
|
||||
<column disabled="@no_total"/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column width="1%"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<nextmatch-accountfilter options="LoginID" id="account_id"/>
|
||||
<nextmatch-header label="Login-Status" id="sessionstatus"/>
|
||||
<nextmatch-header label="Loginid" id="loginid"/>
|
||||
<nextmatch-header label="IP" id="ip"/>
|
||||
<nextmatch-sortheader label="Login" id="li"/>
|
||||
<nextmatch-sortheader label="Logout" id="lo"/>
|
||||
<nextmatch-header label="Total" id="total"/>
|
||||
<nextmatch-sortheader label="Idle" id="session_dla"/>
|
||||
<nextmatch-header label="Last action" id="session_action"/>
|
||||
<hbox>
|
||||
<description value="Action" align="center"/>
|
||||
<description value="Actions" align="center"/>
|
||||
<buttononly options="check" label="Select all" onclick="toggle_all(this.form,form::name('selected[]')); return false;"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row class="row">
|
||||
<menulist>
|
||||
<menupopup type="select-account" id="${row}[account_id]" readonly="true"/>
|
||||
<menupopup type="select-account" id="${row}[account_id]" readonly="true" label="$row_cont[alt_loginid]"/>
|
||||
</menulist>
|
||||
<description id="${row}[sessionstatus]"/>
|
||||
<description id="${row}[loginid]"/>
|
||||
<description id="${row}[ip]"/>
|
||||
<date-time id="${row}[li]" readonly="true"/>
|
||||
<date-time id="${row}[lo]" readonly="true"/>
|
||||
<date-duration id="${row}[total]" readonly="true" options=",hm,24"/>
|
||||
<date-since id="${row}[session_dla]" readonly="true"/>
|
||||
<description id="${row}[session_action]"/>
|
||||
<hbox options="0,0" align="center">
|
||||
<button image="delete" label="Delete" id="delete[$row_cont[sessionid]]" statustext="Delete this log entry" onclick="return confirm('Delete this log entry');"/>
|
||||
<checkbox options="$row_cont[sessionid]" id="selected[]"/>
|
||||
<button image="close" label="Kill" id="kill[$row_cont[sessionid]]" onclick="return confirm('Are you sure you want to kill this session ?');"/>
|
||||
<checkbox options="$row_cont[sessionid]" id="selected[]" align="right"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="admin.accesslog" template="" lang="" group="0" version="1.7.001">
|
||||
<template id="admin.accesslog" template="" lang="" group="0" version="1.9.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
@ -51,16 +64,17 @@
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<nextmatch options="admin.accesslog.rows" id="nm" span="all"/>
|
||||
<nextmatch span="all" id="nm" options="admin.accesslog.rows"/>
|
||||
</row>
|
||||
<row>
|
||||
<hbox options="0,0">
|
||||
<description value="Percent of users that logged out" readonly="true"/>
|
||||
<textbox type="float" id="percent" precision="1" label=": %s %" readonly="true"/>
|
||||
<description readonly="true" value="Percent of users that logged out"/>
|
||||
<textbox type="float" precision="1" label=": %s %" readonly="true" id="percent"/>
|
||||
</hbox>
|
||||
<hbox align="right">
|
||||
<button id="delete" image="delete" label="Delete" statustext="Delete selected entries" onclick="return confirm('Delete the selected entries');"/>
|
||||
<buttononly options="arrow_ltr" onclick="toggle_all(this.form,form::name('nm[rows][selected][]')); return false;" class="selectAllArrow"/>
|
||||
<button label="Delete" onclick="return confirm('Delete the selected entries');" id="delete" image="delete" statustext="Delete selected entries"/>
|
||||
<button image="close" label="Kill" id="kill" onclick="return confirm('Are you sure you want to kill this session ?');"/>
|
||||
<buttononly options="arrow_ltr" label="Select all" onclick="toggle_all(this.form,form::name('selected[]')); return false;"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
|
@ -1,38 +0,0 @@
|
||||
<!-- BEGIN list -->
|
||||
<br>
|
||||
<table border="0" width="95%" align="center">
|
||||
<tr>
|
||||
{left_next_matchs}
|
||||
<td align="center">{start_total}</td>
|
||||
{right_next_matchs}
|
||||
</tr>
|
||||
</td>
|
||||
|
||||
<table border="0" width="95%" align="center" class="egwGridView_grid">
|
||||
<tr class="th">
|
||||
<td>{sort_loginid}</td>
|
||||
<td>{sort_ip}</td>
|
||||
<td>{sort_login_time}</td>
|
||||
<td>{sort_action}</td>
|
||||
<td>{sort_idle}</td>
|
||||
<td>{lang_kill}</td>
|
||||
</tr>
|
||||
|
||||
{rows}
|
||||
|
||||
</table>
|
||||
<br>
|
||||
<!-- END list -->
|
||||
|
||||
<!-- BEGIN row -->
|
||||
<tr bgcolor="{tr_color}">
|
||||
<td>{row_loginid}</td>
|
||||
<td>{row_ip}</td>
|
||||
<td>{row_logintime}</td>
|
||||
<td>{row_action}</td>
|
||||
<td>{row_idle}</td>
|
||||
<td>{row_kill}</td>
|
||||
</tr>
|
||||
<!-- END row -->
|
||||
|
||||
|
@ -439,7 +439,7 @@ abstract class egw_framework
|
||||
{
|
||||
if( $GLOBALS['egw_info']['user']['apps']['admin'] && $GLOBALS['egw_info']['user']['preferences']['common']['show_currentusers'])
|
||||
{
|
||||
$current_users = '<a href="' . egw::link('/index.php','menuaction=admin.uicurrentsessions.list_sessions') . '">' .
|
||||
$current_users = '<a href="' . egw::link('/index.php','menuaction=admin.admin_accesslog.sessions') . '">' .
|
||||
lang('Current users') . ': ' . $GLOBALS['egw']->session->session_count() . '</a>';
|
||||
return $current_users;
|
||||
}
|
||||
|
@ -132,6 +132,13 @@ class egw_session
|
||||
*/
|
||||
var $kp3;
|
||||
|
||||
/**
|
||||
* Primary key of egw_access_log row for updates
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
var $sessionid_access_log;
|
||||
|
||||
/**
|
||||
* name of XML-RPC/SOAP method called
|
||||
*
|
||||
@ -579,7 +586,7 @@ class egw_session
|
||||
$this->register_session($this->login,$user_ip,$now,$this->session_flags);
|
||||
if ($this->session_flags != 'A') // dont log anonymous sessions
|
||||
{
|
||||
$this->log_access($this->sessionid,$login,$user_ip,$this->account_id);
|
||||
$this->sessionid_access_log = $this->log_access($this->sessionid,$login,$user_ip,$this->account_id);
|
||||
}
|
||||
self::appsession('account_previous_login','phpgwapi',$GLOBALS['egw']->auth->previous_login);
|
||||
$GLOBALS['egw']->accounts->update_lastlogin($this->account_id,$user_ip);
|
||||
@ -640,10 +647,11 @@ class egw_session
|
||||
/**
|
||||
* Write or update (for logout) the access_log
|
||||
*
|
||||
* @param string $sessionid id of session or 0 for unsuccessful logins
|
||||
* @param string|int $sessionid PHP sessionid or 0 for unsuccessful logins
|
||||
* @param string $login account_lid (evtl. with domain) or '' for settion the logout-time
|
||||
* @param string $user_ip ip to log
|
||||
* @param int $account_id numerical account_id
|
||||
* @return int $sessionid primary key of egw_access_log for login, null otherwise
|
||||
*/
|
||||
private function log_access($sessionid,$login='',$user_ip='',$account_id='')
|
||||
{
|
||||
@ -652,17 +660,24 @@ class egw_session
|
||||
if ($login)
|
||||
{
|
||||
$GLOBALS['egw']->db->insert(self::ACCESS_LOG_TABLE,array(
|
||||
'sessionid' => $sessionid,
|
||||
'session_php' => $sessionid,
|
||||
'loginid' => $login,
|
||||
'ip' => $user_ip,
|
||||
'li' => $now,
|
||||
'lo' => 0,
|
||||
'account_id'=> $account_id,
|
||||
),false,__LINE__,__FILE__);
|
||||
|
||||
$ret = $GLOBALS['egw']->db->get_last_insert_id(self::ACCESS_LOG_TABLE,'sessionid');
|
||||
}
|
||||
else
|
||||
{
|
||||
$GLOBALS['egw']->db->update(self::ACCESS_LOG_TABLE,array('lo' => $now),array('sessionid' => $sessionid),__LINE__,__FILE__);
|
||||
$GLOBALS['egw']->db->update(self::ACCESS_LOG_TABLE,array(
|
||||
'lo' => $now
|
||||
),is_numeric($sessionid) ? array(
|
||||
'sessionid' => $sessionid,
|
||||
) : array(
|
||||
'session_php' => $sessionid,
|
||||
),__LINE__,__FILE__);
|
||||
}
|
||||
if ($GLOBALS['egw_info']['server']['max_access_log_age'])
|
||||
{
|
||||
@ -670,6 +685,8 @@ class egw_session
|
||||
|
||||
$GLOBALS['egw']->db->delete(self::ACCESS_LOG_TABLE,"li < $max_age",__LINE__,__FILE__);
|
||||
}
|
||||
//error_log(__METHOD__."('$sessionid', '$login', '$user_ip', $account_id) returning ".array2string($ret));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -861,6 +878,10 @@ class egw_session
|
||||
{
|
||||
$this->update_dla();
|
||||
}
|
||||
elseif ($GLOBALS['egw_info']['flags']['currentapp'] == 'notifications')
|
||||
{
|
||||
$this->update_notification_heartbeat();
|
||||
}
|
||||
$this->account_id = $GLOBALS['egw']->accounts->name2id($this->account_lid,'account_lid','u');
|
||||
if (!$this->account_id)
|
||||
{
|
||||
@ -959,6 +980,15 @@ class egw_session
|
||||
//echo 'DEBUG: Sessions: account_id is empty!<br>'."\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// query accesslog-id, if not set in session (session is made persistent after login!)
|
||||
if (!$this->sessionid_access_log)
|
||||
{
|
||||
$this->sessionid_access_log = $GLOBALS['egw']->db->select(self::ACCESS_LOG_TABLE,'sessionid',array(
|
||||
'session_php' => $this->sessionid,
|
||||
),__LINE__,__FILE__)->fetchColumn();
|
||||
//error_log(__METHOD__."() sessionid=$this->sessionid --> sessionid_access_log=$this->sessionid_access_log");
|
||||
}
|
||||
if (self::ERROR_LOG_DEBUG) error_log("--> session::verify($sessionid) SUCCESS");
|
||||
|
||||
return true;
|
||||
@ -971,16 +1001,23 @@ class egw_session
|
||||
* @param string $kp3
|
||||
* @return boolean true on success, false on error
|
||||
*/
|
||||
function destroy($sessionid, $kp3)
|
||||
function destroy($sessionid, $kp3='')
|
||||
{
|
||||
if (!$sessionid && $kp3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$this->log_access($this->sessionid); // log logout-time
|
||||
$this->log_access($sessionid); // log logout-time
|
||||
|
||||
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__."($sessionid,$kp3) parent::destroy()=$ret");
|
||||
|
||||
if (is_numeric($sessionid)) // do we have a access-log-id --> get PHP session id
|
||||
{
|
||||
$sessionid = $GLOBALS['egw']->db->select(self::ACCESS_LOG_TABLE,'session_php',array(
|
||||
'sessionid' => $sessionid,
|
||||
),__LINE__,__FILE__)->fetchColumn();
|
||||
}
|
||||
|
||||
$GLOBALS['egw']->hooks->process(array(
|
||||
'location' => 'session_destroyed',
|
||||
'sessionid' => $sessionid,
|
||||
@ -1006,12 +1043,12 @@ class egw_session
|
||||
}
|
||||
else
|
||||
{
|
||||
$sessions = self::session_list(0,'','',true);
|
||||
$this->commit_session(); // close our own session
|
||||
|
||||
if (isset($sessions[$sessionid]) && session_module_name() == 'files')
|
||||
session_id($sessionid);
|
||||
if (session_start())
|
||||
{
|
||||
//echo '<p>'.__METHOD__."($session_id): unlink('".$sessions[$sessionid]['php_session_file']."')</p>\n";
|
||||
@unlink($sessions[$sessionid]['php_session_file']);
|
||||
session_destroy();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -1318,24 +1355,41 @@ class egw_session
|
||||
}
|
||||
|
||||
/**
|
||||
* Update session_action and session_dla (session last used time),
|
||||
* Update session_action and session_dla (session last used time)
|
||||
*/
|
||||
private function update_dla()
|
||||
{
|
||||
if (isset($_GET['menuaction']))
|
||||
// This way XML-RPC users aren't always listed as xmlrpc.php
|
||||
if ($this->xmlrpc_method_called)
|
||||
{
|
||||
$action = $this->xmlrpc_method_called;
|
||||
}
|
||||
elseif (isset($_GET['menuaction']))
|
||||
{
|
||||
$action = $_GET['menuaction'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$action = $_SERVER['PHP_SELF'];
|
||||
// remove EGroupware path, if not installed in webroot
|
||||
$egw_path = $GLOBALS['egw_info']['server']['webserver_url'];
|
||||
if ($egw_path[0] != '/') $egw_path = parse_url($egw_path,PHP_URL_PATH);
|
||||
if ($egw_path)
|
||||
{
|
||||
list(,$action) = explode($egw_path,$action,2);
|
||||
}
|
||||
}
|
||||
|
||||
// This way XML-RPC users aren't always listed as
|
||||
// xmlrpc.php
|
||||
if ($this->xmlrpc_method_called)
|
||||
// update dla in access-log table, if we have an access-log row (non-anonymous session)
|
||||
if ($this->sessionid_access_log)
|
||||
{
|
||||
$action = $this->xmlrpc_method_called;
|
||||
$GLOBALS['egw']->db->update(self::ACCESS_LOG_TABLE,array(
|
||||
'session_dla' => time(),
|
||||
'session_action' => $action,
|
||||
'lo' => null, // just in case it was (automatic) timed out before
|
||||
),array(
|
||||
'sessionid' => $this->sessionid_access_log,
|
||||
),__LINE__,__FILE__);
|
||||
}
|
||||
|
||||
$_SESSION[self::EGW_SESSION_VAR]['session_dla'] = time();
|
||||
@ -1343,6 +1397,23 @@ class egw_session
|
||||
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__.'() _SESSION['.self::EGW_SESSION_VAR.']='.array2string($_SESSION[self::EGW_SESSION_VAR]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification_heartbeat time of session
|
||||
*/
|
||||
private function update_notification_heartbeat()
|
||||
{
|
||||
// update dla in access-log table, if we have an access-log row (non-anonymous session)
|
||||
if ($this->sessionid_access_log)
|
||||
{
|
||||
$GLOBALS['egw']->db->update(self::ACCESS_LOG_TABLE,array(
|
||||
'notification_heartbeat' => time(),
|
||||
),array(
|
||||
'sessionid' => $this->sessionid_access_log,
|
||||
'lo IS NULL',
|
||||
),__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the diverse repositories / init classes with data from the just loged in user
|
||||
*
|
||||
@ -1471,32 +1542,80 @@ class egw_session
|
||||
* Get a session list (of the current instance)
|
||||
*
|
||||
* @param int $start
|
||||
* @param string $sort='session_dla' session_lid, session_id, session_started, session_logintime, session_action, or (default) session_dla
|
||||
* @param string $order='DESC' ASC or DESC
|
||||
* @param string $sort='DESC' ASC or DESC
|
||||
* @param string $order='session_dla' session_lid, session_id, session_started, session_logintime, session_action, or (default) session_dla
|
||||
* @param boolean $all_no_sort=False skip sorting and limiting to maxmatchs if set to true
|
||||
* @return array with sessions (values for keys as in $sort) or array() if not supported by session-handler
|
||||
* @return array with sessions (values for keys as in $sort)
|
||||
*/
|
||||
public static function session_list($start,$sort='DESC',$order='session_dla',$all_no_sort=False)
|
||||
{
|
||||
if (method_exists(self::$session_handler,'session_list'))
|
||||
$sessions = array();
|
||||
if (!preg_match('/^[a-z0-9_ ,]+$/i',$order_by=$order.' '.$sort))
|
||||
{
|
||||
return call_user_func(array(self::$session_handler,'session_list'),$start,$sort,$order,$all_no_sort);
|
||||
$order_by = 'session_dla DESC';
|
||||
}
|
||||
return array();
|
||||
foreach($GLOBALS['egw']->db->select(self::ACCESS_LOG_TABLE, '*', array(
|
||||
'lo' => null,
|
||||
'session_dla > '.(int)(time() - $GLOBALS['egw_info']['server']['sessions_timeout']),
|
||||
'(notification_heartbeat IS NULL OR notification_heartbeat > '.self::heartbeat_limit().')',
|
||||
), __LINE__, __FILE__, $all_no_sort ? false : $start, 'ORDER BY '.$order_by) as $row)
|
||||
{
|
||||
$sessions[$row['sessionid']] = $row;
|
||||
}
|
||||
return $sessions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query number of sessions (not more then once every N secs)
|
||||
*
|
||||
* @return int|boolean integer number of sessions or false if not supported by session-handler
|
||||
* @return int number of active sessions
|
||||
*/
|
||||
public static function session_count()
|
||||
{
|
||||
if (method_exists(self::$session_handler,'session_count'))
|
||||
return $GLOBALS['egw']->db->select(self::ACCESS_LOG_TABLE, 'COUNT(*)', array(
|
||||
'lo' => null,
|
||||
'session_dla > '.(int)(time() - $GLOBALS['egw_info']['server']['sessions_timeout']),
|
||||
'(notification_heartbeat IS NULL OR notification_heartbeat > '.self::heartbeat_limit().')',
|
||||
), __LINE__, __FILE__)->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get limit / latest time of heartbeat for session to be active
|
||||
*
|
||||
* @return int TS in server-time
|
||||
*/
|
||||
public static function heartbeat_limit()
|
||||
{
|
||||
static $limit;
|
||||
|
||||
if (is_null($limit))
|
||||
{
|
||||
return call_user_func(array(self::$session_handler,'session_count'));
|
||||
$config = config::read('notifications');
|
||||
if (!($popup_poll_interval = $config['popup_poll_interval']))
|
||||
{
|
||||
$popup_poll_interval = 60;
|
||||
}
|
||||
$limit = (int)(time() - $popup_poll_interval-10); // 10s grace periode
|
||||
}
|
||||
return false;
|
||||
return $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given user can be reached via notifications
|
||||
*
|
||||
* Checks if notifications callback checked in not more then heartbeat_limit() seconds ago
|
||||
*
|
||||
* @param int $account_id
|
||||
* @param int number of active sessions of given user with notifications running
|
||||
*/
|
||||
public static function notifications_active($account_id)
|
||||
{
|
||||
return $GLOBALS['egw']->db->select(self::ACCESS_LOG_TABLE, 'COUNT(*)', array(
|
||||
'lo' => null,
|
||||
'session_dla > '.(int)(time() - $GLOBALS['egw_info']['server']['sessions_timeout']),
|
||||
'account_id' => $account_id,
|
||||
'notifications_heartbeat > '.self::heartbeat_limit(),
|
||||
), __LINE__, __FILE__)->fetchColumn();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -616,7 +616,23 @@ class schema_proc
|
||||
$blob_column_included = $auto_column_included = False;
|
||||
foreach($aTableDef['fd'] as $name => $data)
|
||||
{
|
||||
if ($aDefaults && isset($aDefaults[$name])) // use given default
|
||||
// new auto column with no default or explicit NULL as default (can be an existing column too!)
|
||||
if ($data['type'] == 'auto' &&
|
||||
(!isset($old_table_def['fd'][$name]) && (!$aDefaults || !isset($aDefaults[$name])) ||
|
||||
$aDefaults && strtoupper($aDefaults[$name]) == 'NULL'))
|
||||
{
|
||||
$sequence_name = $sTableName.'_'.$name.'_seq';
|
||||
switch($GLOBALS['egw_setup']->db->Type)
|
||||
{
|
||||
case 'mysql':
|
||||
$value = 'NULL'; break;
|
||||
case 'pgsql':
|
||||
$value = "nextval('$sequence_name'::regclass)"; break;
|
||||
default:
|
||||
$value = "nextval('$sequence_name')"; break;
|
||||
}
|
||||
}
|
||||
elseif ($aDefaults && isset($aDefaults[$name])) // use given default
|
||||
{
|
||||
$value = $aDefaults[$name];
|
||||
}
|
||||
@ -690,10 +706,11 @@ class schema_proc
|
||||
$Ok = $this->RenameTable($sTableName,$tmp_name);
|
||||
}
|
||||
$Ok = $Ok && $this->CreateTable($sTableName,$aTableDef) &&
|
||||
$this->m_odb->query("$extra INSERT INTO $sTableName (".
|
||||
$this->m_odb->query($sql_copy_data="$extra INSERT INTO $sTableName (".
|
||||
implode(',',array_keys($aTableDef['fd'])).
|
||||
") SELEcT $distinct $select FROM $tmp_name",__LINE__,__FILE__) &&
|
||||
$this->DropTable($tmp_name);
|
||||
//error_log($sql_copy_data);
|
||||
|
||||
if (!$Ok)
|
||||
{
|
||||
|
@ -12,7 +12,7 @@
|
||||
/* Basic information about this app */
|
||||
$setup_info['phpgwapi']['name'] = 'phpgwapi';
|
||||
$setup_info['phpgwapi']['title'] = 'eGroupWare API';
|
||||
$setup_info['phpgwapi']['version'] = '1.9.007';
|
||||
$setup_info['phpgwapi']['version'] = '1.9.008';
|
||||
$setup_info['phpgwapi']['versions']['current_header'] = '1.29';
|
||||
$setup_info['phpgwapi']['enable'] = 3;
|
||||
$setup_info['phpgwapi']['app_order'] = 1;
|
||||
@ -74,3 +74,4 @@ $setup_info['groupdav']['author'] = $setup_info['groupdav']['maintainer'] = arra
|
||||
$setup_info['groupdav']['license'] = 'GPL';
|
||||
$setup_info['groupdav']['hooks']['preferences'] = 'groupdav_hooks::menus';
|
||||
$setup_info['groupdav']['hooks']['settings'] = 'groupdav_hooks::settings';
|
||||
|
||||
|
@ -83,16 +83,20 @@ $phpgw_baseline = array(
|
||||
),
|
||||
'egw_access_log' => array(
|
||||
'fd' => array(
|
||||
'sessionid' => array('type' => 'char','precision' => '128','nullable' => False),
|
||||
'loginid' => array('type' => 'varchar','precision' => '64','nullable' => False),
|
||||
'ip' => array('type' => 'varchar','precision' => '40','nullable' => False),
|
||||
'li' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'lo' => array('type' => 'int','precision' => '4','default' => '0'),
|
||||
'account_id' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0')
|
||||
'sessionid' => array('type' => 'auto','nullable' => False,'comment' => 'primary key'),
|
||||
'loginid' => array('type' => 'varchar','precision' => '64','nullable' => False,'comment' => 'username used to login'),
|
||||
'ip' => array('type' => 'varchar','precision' => '40','nullable' => False,'comment' => 'ip of user'),
|
||||
'li' => array('type' => 'int','precision' => '8','nullable' => False,'comment' => 'TS if login'),
|
||||
'lo' => array('type' => 'int','precision' => '8','comment' => 'TD of logout'),
|
||||
'account_id' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'numerical account id'),
|
||||
'session_dla' => array('type' => 'int','precision' => '8','comment' => 'TS of last user action'),
|
||||
'session_action' => array('type' => 'varchar','precision' => '64','comment' => 'menuaction or path of last user action'),
|
||||
'session_php' => array('type' => 'varchar','precision' => '64','nullable' => False,'comment' => 'php session-id or error-message'),
|
||||
'notification_heartbeat' => array('type' => 'int','precision' => '8','comment' => 'TS of last notification request')
|
||||
),
|
||||
'pk' => array(),
|
||||
'pk' => array('sessionid'),
|
||||
'fk' => array(),
|
||||
'ix' => array('li'),
|
||||
'ix' => array('li','lo','session_dla','notification_heartbeat'),
|
||||
'uc' => array()
|
||||
),
|
||||
'egw_hooks' => array(
|
||||
|
@ -173,3 +173,33 @@ function phpgwapi_upgrade1_9_006()
|
||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '1.9.007';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns for session list (dla, action), make sessionid primary key and TS 64bit
|
||||
*/
|
||||
function phpgwapi_upgrade1_9_007()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->RefreshTable('egw_access_log',array(
|
||||
'fd' => array(
|
||||
'sessionid' => array('type' => 'auto','nullable' => False,'comment' => 'primary key'),
|
||||
'loginid' => array('type' => 'varchar','precision' => '64','nullable' => False,'comment' => 'username used to login'),
|
||||
'ip' => array('type' => 'varchar','precision' => '40','nullable' => False,'comment' => 'ip of user'),
|
||||
'li' => array('type' => 'int','precision' => '8','nullable' => False,'comment' => 'TS if login'),
|
||||
'lo' => array('type' => 'int','precision' => '8','comment' => 'TD of logout'),
|
||||
'account_id' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'numerical account id'),
|
||||
'session_dla' => array('type' => 'int','precision' => '8','comment' => 'TS of last user action'),
|
||||
'session_action' => array('type' => 'varchar','precision' => '64','comment' => 'menuaction or path of last user action'),
|
||||
'session_php' => array('type' => 'char','precision' => '64','nullable' => False,'comment' => 'php session-id or error-message'),
|
||||
'notification_heartbeat' => array('type' => 'int','precision' => '8','comment' => 'TS of last notification request')
|
||||
),
|
||||
'pk' => array('sessionid'),
|
||||
'fk' => array(),
|
||||
'ix' => array('li','lo','session_dla','notification_heartbeat'),
|
||||
'uc' => array()
|
||||
),array(
|
||||
'session_php' => 'sessionid',
|
||||
'sessionid' => 'NULL', // to NOT copy old sessionid, but create a new sequence
|
||||
));
|
||||
|
||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '1.9.008';
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user