Commit 297b6fa5 authored by Christophe Maudoux's avatar Christophe Maudoux 🐛
Browse files

Display logins history with CheckUser plugin

parent c14b5c62
......@@ -41,6 +41,7 @@ sub defaultValues {
'checkUserDisplayComputedSession' => 1,
'checkUserDisplayEmptyHeaders' => 0,
'checkUserDisplayEmptyValues' => 0,
'checkUserDisplayHistory' => 0,
'checkUserDisplayNormalizedHeaders' => 0,
'checkUserDisplayPersistentInfo' => 0,
'checkUserHiddenAttributes' => '_loginHistory _session_id hGroups',
......
......@@ -905,6 +905,10 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'default' => 0,
'type' => 'boolOrExpr'
},
'checkUserDisplayHistory' => {
'default' => 0,
'type' => 'boolOrExpr'
},
'checkUserDisplayNormalizedHeaders' => {
'default' => 0,
'type' => 'boolOrExpr'
......
......@@ -542,6 +542,12 @@ sub attributes {
documentation => 'Display empty headers rule',
flags => 'p',
},
checkUserDisplayHistory => {
default => 0,
type => 'boolOrExpr',
documentation => 'Display history rule',
flags => 'p',
},
checkUserHiddenHeaders => {
type => 'keyTextContainer',
keyTest => qr/^\S+$/,
......
......@@ -808,6 +808,7 @@ sub tree {
'checkUserDisplayNormalizedHeaders',
'checkUserDisplayEmptyHeaders',
'checkUserDisplayEmptyValues',
'checkUserDisplayHistory',
]
},
]
......
......@@ -191,8 +191,10 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserDisplayHistory":"History",
"checkUserHiddenAttributes":"السمات المخفية",
"checkUserHiddenHeaders":"Hidden headers",
"checkUserIdRule":"Identities use rule",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserHiddenAttributes":"Hidden attributes",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserHiddenAttributes":"Hidden attributes",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserHiddenAttributes":"Atributos ocultos",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Sessions évaluées",
"checkUserDisplayEmptyHeaders":"Entêtes nuls",
"checkUserDisplayEmptyValues":"Valeurs nulles",
"checkUserDisplayHistory":"Historique",
"checkUserDisplayNormalizedHeaders":"Entêtes normalisés",
"checkUserDisplayPersistentInfo":"Données de session persistante",
"checkUserHiddenAttributes":"Attributs masqués",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserHiddenAttributes":"Attributi nascosti",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Sesje obliczane",
"checkUserDisplayEmptyHeaders":"Puste nagłówki",
"checkUserDisplayEmptyValues":"Puste wartości",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Znormalizowane nagłówki",
"checkUserDisplayPersistentInfo":"Trwałe dane sesji",
"checkUserHiddenAttributes":"Ukryte atrybuty",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Hesaplanan oturumlar",
"checkUserDisplayEmptyHeaders":"Boş başlıklar",
"checkUserDisplayEmptyValues":"Boş değerler",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalleştirilmiş başlıklar",
"checkUserDisplayPersistentInfo":"Kalıcı oturum verisi",
"checkUserHiddenAttributes":"Gizli nitelikler",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserHiddenAttributes":"Thuộc tính ẩn",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserHiddenAttributes":"Hidden attributes",
......
......@@ -191,6 +191,7 @@
"checkUserDisplayComputedSession":"Computed sessions",
"checkUserDisplayEmptyHeaders":"Empty headers",
"checkUserDisplayEmptyValues":"Empty values",
"checkUserDisplayHistory":"History",
"checkUserDisplayNormalizedHeaders":"Normalized headers",
"checkUserDisplayPersistentInfo":"Persistent session data",
"checkUserHiddenAttributes":"隱藏屬性",
......
......@@ -9,7 +9,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_BADCREDENTIALS
);
our $VERSION = '2.0.12';
our $VERSION = '2.0.14';
extends qw(
Lemonldap::NG::Portal::Main::Plugin
......@@ -28,6 +28,8 @@ has ott => (
return $ott;
}
);
has displayHistoryRule => ( is => 'rw', default => sub { 0 } );
has unrestrictedUsersRule => ( is => 'rw', default => sub { 0 } );
has displayEmptyValuesRule => ( is => 'rw', default => sub { 0 } );
has displayEmptyHeadersRule => ( is => 'rw', default => sub { 0 } );
......@@ -104,6 +106,13 @@ sub init {
)
);
return 0 unless $self->displayNormalizedHeadersRule;
$self->displayHistoryRule(
$self->p->buildRule(
$self->conf->{checkUserDisplayHistory},
'checkUserDisplayHistory'
)
);
return 0 unless $self->displayHistoryRule;
# Init. other options
$self->sorted( $self->conf->{impersonationRule}
......@@ -116,13 +125,18 @@ sub init {
# RUNNING METHODS
sub display {
my ( $self, $req ) = @_;
my ( $self, $req ) = @_;
my $history = [ [], [] ];
my ( $attrs, $array_attrs ) = ( $req->userData, [] );
$self->logger->debug("Display current session data...");
$self->userLogger->info("Using spoofed SSO groups if exist")
if ( $self->conf->{impersonationRule} );
$history = $self->_concatHistory( $attrs->{_loginHistory} )
if $self->displayHistoryRule->( $req, $req->userData )
&& $self->conf->{loginHistoryEnabled};
$attrs =
$self->_removeKeys( $attrs, $self->persistentAttrs,
'Remove persistent session attributes...' )
......@@ -141,6 +155,9 @@ sub display {
MSG => 'checkUser' . $self->merged,
ALERTE => ( $self->merged ? 'alert-warning' : 'alert-info' ),
LOGIN => $req->{userData}->{ $self->conf->{whatToTrace} },
HISTORY => ( @{ $history->[0] } || @{ $history->[1] } ) ? 1 : 0,
SUCCESS => $history->[0],
FAILED => $history->[1],
ATTRIBUTES => $array_attrs->[2],
MACROS => $array_attrs->[1],
GROUPS => $array_attrs->[0],
......@@ -161,7 +178,8 @@ sub check {
my ( $attrs, $array_attrs, $array_hdrs ) = ( {}, [], [] );
my $msg = my $auth = my $computed = '';
my $savedUserData = $req->userData;
my $unUser = $self->unrestrictedUsersRule->( $req, $savedUserData ) || 0;
my $unUser = $self->unrestrictedUsersRule->( $req, $savedUserData ) || 0;
my $history = [ [], [] ];
# Check token
if ( $self->ottRule->( $req, {} ) ) {
......@@ -294,7 +312,11 @@ sub check {
$attrs = {};
}
else {
$msg = 'checkUser' . $self->merged;
$msg = 'checkUser' . $self->merged;
$history = $self->_concatHistory( $attrs->{_loginHistory} )
if $self->displayHistoryRule->( $req, $savedUserData )
&& $self->conf->{loginHistoryEnabled};
$attrs =
$self->_removeKeys( $attrs, $self->persistentAttrs,
'Remove persistent session attributes...' )
......@@ -387,6 +409,9 @@ sub check {
ALLOWED => $auth,
ALERTE_AUTH => $alert_auth,
HEADERS => $array_hdrs,
HISTORY => ( @{ $history->[0] } || @{ $history->[1] } ) ? 1 : 0,
SUCCESS => $history->[0],
FAILED => $history->[1],
ATTRIBUTES => $array_attrs->[2],
MACROS => $array_attrs->[1],
GROUPS => $array_attrs->[0],
......@@ -651,4 +676,32 @@ sub _removeKeys {
return $attrs;
}
sub _concatHistory {
my ( $self, $history ) = @_;
my ( $success, $failed ) = ( [], [] );
$self->logger->debug('Concatenate history...');
@$success = map {
my $element = $_;
my $utime = delete $element->{_utime};
{
utime => $utime,
values => join $self->{conf}->{multiValuesSeparator},
map { "$_=$element->{$_}" } sort keys %$element
}
} @{ $history->{successLogin} };
@$failed = map {
my $element = $_;
my $utime = delete $element->{_utime};
{
utime => $utime,
values => join $self->{conf}->{multiValuesSeparator},
map { "$_=$element->{$_}" } sort keys %$element
}
} @{ $history->{failedLogin} };
return [ $success, $failed ];
}
1;
......@@ -43,13 +43,56 @@
</div>
</TMPL_IF>
<div class="row">
<TMPL_IF NAME="HISTORY">
<div class="card col border-secondary">
<div class="text-center bg-light text-dark"><b><span trspan="loginHistory">HISTORY</span></b></div>
<TMPL_IF NAME="SUCCESS">
<table class="table table-sm table-hover">
<thead>
<div class="text-center bg-light text-dark"><span trspan="lastLogins">Success</span></div>
<tr>
<th scope="col"><span trspan="date">Date</span></th>
<th scope="col"><span trspan="value">Value</span></th>
</tr>
</thead>
<tbody>
<TMPL_LOOP NAME="SUCCESS">
<tr>
<td class="localeDate" scope="row" val="<TMPL_VAR NAME="utime">"></td>
<td scope="row"><TMPL_VAR NAME="values"></td>
</tr>
</TMPL_LOOP>
</tbody>
</table>
</TMPL_IF>
<TMPL_IF NAME="FAILED">
<table class="table table-sm table-hover">
<thead>
<div class="text-center bg-light text-dark"><span trspan="lastFailedLogins">Failed</span></div>
<tr>
<th scope="col"><span trspan="date">Date</span></th>
<th scope="col"><span trspan="value">Value</span></th>
</tr>
</thead>
<tbody>
<TMPL_LOOP NAME="FAILED">
<tr>
<td class="localeDate" scope="row" val="<TMPL_VAR NAME="utime">"></td>
<td scope="row"><TMPL_VAR NAME="values"></td>
</tr>
</TMPL_LOOP>
</tbody>
</table>
</TMPL_IF>
</div>
</TMPL_IF>
<TMPL_IF NAME="GROUPS">
<div class="card col border-secondary">
<div class="text-center bg-light text-dark"><b><span trspan="groups_sso">SSO GROUPS</span></b></div>
<div class="row">
<TMPL_LOOP NAME="GROUPS">
<div class="w-100"></div>
<div class="col"><TMPL_VAR NAME="value"></div>
<div class="w-100"></div>
<div class="col"><TMPL_VAR NAME="value"></div>
</TMPL_LOOP>
</div>
</div>
......
......@@ -10,7 +10,7 @@ BEGIN {
my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
logLevel => 'debug',
authentication => 'Demo',
userDB => 'Same',
loginHistoryEnabled => 1,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment