## @file
# Session explorer
## @class
# Session explorer.
package Lemonldap::NG::Manager::Sessions;
use strict;
use Lemonldap::NG::Handler::CGI qw(:globalStorage :locationRules);
use Lemonldap::NG::Common::Apache::Session; #inherits
use Lemonldap::NG::Common::Conf; #link protected conf Configuration
use Lemonldap::NG::Common::Conf::Constants; #inherits
#inherits Apache::Session
our $whatToTrace;
*whatToTrace = \$Lemonldap::NG::Handler::_CGI::whatToTrace;
our $VERSION = '0.11';
use base qw(Lemonldap::NG::Handler::CGI);
## @cmethod Lemonldap::NG::Manager::Sessions new(hashRef args)
# Constructor.
# @param $args Arguments for Lemonldap::NG::Handler::CGI::new(). Must contains
# 3 keys for Lemonldap::NG::Manager::Sessions:
# - jqueryUri HTTP path to jquery.js
# - personnalCss Optional HTTP path to custom CSS file
# - imagePath HTTP path to the images directory
# @return New Lemonldap::NG::Manager::Sessions object
sub new {
my ( $class, $args ) = @_;
my $self = $class->SUPER::new($args)
or $class->abort( 'Unable to start ' . __PACKAGE__,
'See Apache logs for more' );
# Try to get configuration values from local configuration
my $config = Lemonldap::NG::Common::Conf->new( $self->{configStorage} );
unless ($config) {
$self->abort( "Unable to start",
"Configuration not loaded\n" . $Lemonldap::NG::Common::Conf::msg );
}
my $localconf = $config->getLocalConf(MANAGERSECTION);
if ($localconf) {
$self->{$_} = $args->{$_} || $localconf->{$_}
foreach ( keys %$localconf );
}
# Check some paramaters
foreach (qw(jqueryUri personnalCss imagePath)) {
$self->{$_}
or $self->lmLog( "$_ is not set, falling to default value", 'debug' );
}
eval "use $globalStorage";
$class->abort( "Unable to load $globalStorage", $@ ) if ($@);
$self->{managerSkin} = "default" unless defined $self->{managerSkin};
return $self;
}
## @method void process()
# Main method.
sub process {
my $self = shift;
if ( $ENV{PATH_INFO} eq "/css" ) {
print $self->header_public( $ENV{SCRIPT_FILENAME}, -type => 'text/css',
);
$self->css;
exit;
}
elsif ( $ENV{PATH_INFO} eq "/js" ) {
print $self->header_public( $ENV{SCRIPT_FILENAME},
-type => 'text/javascript', );
$self->js;
exit;
}
# Check if we use X-FORWARDED-FOR header for IP
my $ipField = $self->{useXForwardedForIP} ? "xForwardedForAddr" : "ipAddr";
# Beginning of the job
# User connected from more than 1 IP
if ( $self->param('doubleIp') ) {
my ( $byUid, $byIp );
$globalStorage->get_key_from_all_sessions(
$globalStorageOptions,
sub {
my $entry = shift;
my $id = shift;
next if ( $entry->{_httpSessionType} );
push @{ $byUid->{ $entry->{$whatToTrace} }
->{ $entry->{$ipField} } },
{ id => $id, _utime => $entry->{_utime} };
undef;
}
);
$self->start('Sessions multi-IP');
$self->window("Sessions multi-IP");
foreach my $uid (
sort { ( keys %{ $byUid->{$b} } ) <=> ( keys %{ $byUid->{$a} } ) }
keys %$byUid
)
{
last if ( ( keys %{ $byUid->{$uid} } ) == 1 );
print "
';
}
## @method protected void ajaxnode(string id, string text, string param)
# Display tree node with Ajax functions inside for opening the node.
# @param $id HTML id of the element.
# @param $text text to display
# @param $param Parameters for the Ajax query
sub ajaxNode {
my ( $self, $id, $text, $param ) = @_;
print
"
$text\n- {url:$ENV{SCRIPT_NAME}?$param}
\n";
}
## @method protected void window(string root)
# Design the main window
# @param $root Text to display in the root node of the tree
sub window {
my $self = shift;
my $root = shift;
print
'
- ' . $root
. '
';
}
## @method protected void end()
# Display the end of HTML page.
sub end {
my $self = shift;
print
'
| |
';
print '
';
print $self->end_html();
}
1;
## @method protected css()
# Display the main CSS file (called by http://manager.example.com/sessions.pl/css)
sub css {
my $self = shift;
print <<"EOF";
body
{
/*font: normal 12px arial, tahoma, helvetica, sans-serif;*/
font:normal 9pt sans-serif;
margin:0;
background-color:#000;
}
a
{
text-decoration:none;
}
#header
{
background-color:#000;
padding:14px;
height:36px;
width:auto;
}
#header img, #header p
{
float:left;
}
#header p
{
margin:5px 10px;
padding:5px;
}
#body
{
margin: 0 10px;
}
.simpleTree
{
overflow:auto;
margin:20px 0;
/*
* width: 250px;
* height:350px;
* overflow:auto;
* border: 1px solid #444444;
* */
}
.simpleTree li
{
list-style: none;
margin:0;
padding:0 0 0 34px;
line-height: 14px;
}
.simpleTree li span
{
display:inline;
clear: left;
white-space: nowrap;
}
.simpleTree ul
{
margin:0;
padding:0;
}
.simpleTree .root
{
margin-left:-16px;
background: url($self->{imagePath}root.gif) no-repeat 16px 0;
}
.simpleTree .line
{
margin:0 0 0 -16px;
padding:0;
line-height: 3px;
height:3px;
font-size:3px;
background: url($self->{imagePath}line_bg.gif) 0 0 no-repeat transparent;
}
.simpleTree .line-last
{
margin:0 0 0 -16px;
padding:0;
line-height: 3px;
height:3px;
font-size:3px;
background: url($self->{imagePath}spacer.gif) 0 0 no-repeat transparent;
}
.simpleTree .line-over
{
margin:0 0 0 -16px;
padding:0;
line-height: 3px;
height:3px;
font-size:3px;
background: url($self->{imagePath}line_bg_over.gif) 0 0 no-repeat transparent;
}
.simpleTree .line-over-last
{
margin:0 0 0 -16px;
padding:0;
line-height: 3px;
height:3px;
font-size:3px;
background: url($self->{imagePath}line_bg_over_last.gif) 0 0 no-repeat transparent;
}
.simpleTree .folder-open
{
margin-left:-16px;
background: url($self->{imagePath}collapsable.gif) 0 -2px no-repeat;
}
.simpleTree .folder-open-last
{
margin-left:-16px;
background: url($self->{imagePath}collapsable-last.gif) 0 -2px no-repeat;
}
.simpleTree .folder-close
{
margin-left:-16px;
background: url($self->{imagePath}expandable.gif) 0 -2px no-repeat;
}
.simpleTree .folder-close-last
{
margin-left:-16px;
background: url($self->{imagePath}expandable-last.gif) 0 -2px no-repeat;
}
.simpleTree .doc
{
margin-left:-16px;
background: url($self->{imagePath}leaf.gif) 0 -1px no-repeat;
}
.simpleTree .doc-last
{
margin-left:-16px;
background: url($self->{imagePath}leaf-last.gif) 0 -1px no-repeat;
}
.simpleTree .ajax
{
background: url($self->{imagePath}spinner.gif) no-repeat 0 0;
height: 16px;
display:none;
}
.simpleTree .ajax li
{
display:none;
margin:0;
padding:0;
}
.simpleTree .trigger
{
display:inline;
margin-left:-32px;
width: 28px;
height: 11px;
cursor:pointer;
}
.simpleTree .text
{
cursor: default;
}
.simpleTree .active
{
cursor: default;
background-color:#F7BE77;
padding:0px 2px;
border: 1px dashed #444;
}
#drag_container
{
color:#000;
font: normal 11px arial, tahoma, helvetica, sans-serif;
border: 1px dashed #767676;
}
#drag_container ul
{
list-style: none;
padding:0;
margin:0;
}
#drag_container li
{
list-style: none;
line-height:18px;
white-space: nowrap;
padding:1px 1px 0px 16px;
margin:0;
}
#drag_container li span
{
padding:0;
}
#drag_container li.doc, #drag_container li.doc-last
{
background: url($self->{imagePath}leaf.gif) no-repeat -17px 0;
}
#drag_container .folder-close, #drag_container .folder-close-last
{
background: url($self->{imagePath}expandable.gif) no-repeat -17px 0;
}
#drag_container .folder-open, #drag_container .folder-open-last
{
background: url($self->{imagePath}collapsable.gif) no-repeat -17px 0;
}
EOF
}
## @method protected js()
# Display the main javascript file (called by http://manager.example.com/sessions.pl/js)
sub js {
my $self = shift;
print <<"EOF";
/*
* jQuery SimpleTree Drag&Drop plugin
* Update on 22th May 2008
* Version 0.3
*
* Licensed under BSD