Commit 2e680c2f authored by Yadd's avatar Yadd

Enable history (#595)

parent 22c22af3
...@@ -2,16 +2,13 @@ ...@@ -2,16 +2,13 @@
* write REST method to create session with an id * write REST method to create session with an id
* Test ForceAuth * Test ForceAuth
* Calendar in notifications explorer * Calendar in notifications explorer
* login history
* Test for Zero * Test for Zero
* replace SOAP by REST for notification creation * replace SOAP by REST for notification creation
* "mail" in UserDB/* * "mail" in UserDB/*
* checkLogins in SAML * checkLogins in SAML
* verify activeTimer on/off on screen * verify activeTimer on/off on screen
* Don't display "login" when connected
* Add test for #173 * Add test for #173
* lwpSslOpt
# Combination # Combination
......
...@@ -406,6 +406,7 @@ t/50-IssuerGet.t ...@@ -406,6 +406,7 @@ t/50-IssuerGet.t
t/60-status.t t/60-status.t
t/61-grantSession.t t/61-grantSession.t
t/62-singleSession.t t/62-singleSession.t
t/63-History.t
t/90-translations.t t/90-translations.t
t/99-pod.t t/99-pod.t
t/lmConf-1.js t/lmConf-1.js
......
...@@ -21,7 +21,7 @@ our @pList = ( ...@@ -21,7 +21,7 @@ our @pList = (
u2fActivation => '::Plugins::U2F', u2fActivation => '::Plugins::U2F',
u2fSelfRegistration => '::Register::U2F', u2fSelfRegistration => '::Register::U2F',
notification => '::Plugins::Notifications', notification => '::Plugins::Notifications',
checkLogins => '::Plugins::History', portalCheckLogins => '::Plugins::History',
); );
##@method list enabledPlugins ##@method list enabledPlugins
......
...@@ -141,6 +141,7 @@ sub authLogout { ...@@ -141,6 +141,7 @@ sub authLogout {
sub deleteSession { sub deleteSession {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$req->userData( {} );
my $apacheSession = $self->getApacheSession( $req->id ); my $apacheSession = $self->getApacheSession( $req->id );
my $id = $req->id; my $id = $req->id;
unless ($apacheSession) { unless ($apacheSession) {
...@@ -267,7 +268,7 @@ sub getUser { ...@@ -267,7 +268,7 @@ sub getUser {
sub authenticate { sub authenticate {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
return $self->_authentication->authenticate($req); return $req->authResult( $self->_authentication->authenticate($req) );
} }
# Third block: Session data providing # Third block: Session data providing
......
...@@ -12,6 +12,9 @@ extends 'Lemonldap::NG::Common::PSGI::Request'; ...@@ -12,6 +12,9 @@ extends 'Lemonldap::NG::Common::PSGI::Request';
# List of methods to call # List of methods to call
has steps => ( is => 'rw' ); has steps => ( is => 'rw' );
# Authentication result
has authResult => ( is => 'rw' );
# Datas shared between methods # Datas shared between methods
has datas => ( is => 'rw' ); has datas => ( is => 'rw' );
......
...@@ -152,12 +152,17 @@ sub do { ...@@ -152,12 +152,17 @@ sub do {
$req->steps($steps); $req->steps($steps);
my $err = $req->error( $self->process($req) ); my $err = $req->error( $self->process($req) );
# TODO: updateStatus # Update status
if ( my $p = $self->HANDLER->tsv->{statusPipe} ) { if ( my $p = $self->HANDLER->tsv->{statusPipe} ) {
print $p ( $req->user ? $req->user : $req->address ) . ' => ' print $p ( $req->user ? $req->user : $req->address ) . ' => '
. $req->uri . $req->uri
. " $err\n"; . " $err\n";
} }
# Update history
if ( $self->conf->{loginHistoryEnabled} ) {
$self->registerLogin($req);
}
if ( $err == PE_SENDRESPONSE ) { if ( $err == PE_SENDRESPONSE ) {
return $req->response; return $req->response;
} }
...@@ -374,9 +379,6 @@ sub updatePersistentSession { ...@@ -374,9 +379,6 @@ sub updatePersistentSession {
# Return if no infos to update # Return if no infos to update
return () unless ( ref $infos eq 'HASH' and %$infos ); return () unless ( ref $infos eq 'HASH' and %$infos );
# Update current session
$self->updateSession( $req, $infos, $id );
$uid ||= $req->{sessionInfo}->{ $self->conf->{whatToTrace} } $uid ||= $req->{sessionInfo}->{ $self->conf->{whatToTrace} }
|| $req->userData->{ $self->conf->{whatToTrace} }; || $req->userData->{ $self->conf->{whatToTrace} };
unless ($uid) { unless ($uid) {
...@@ -385,6 +387,9 @@ sub updatePersistentSession { ...@@ -385,6 +387,9 @@ sub updatePersistentSession {
} }
$self->logger->debug("Update $uid persistent session"); $self->logger->debug("Update $uid persistent session");
# Update current session
$self->updateSession( $req, $infos, $id );
my $persistentSession = $self->getPersistentSession($uid); my $persistentSession = $self->getPersistentSession($uid);
$persistentSession->update($infos); $persistentSession->update($infos);
...@@ -719,4 +724,43 @@ sub tplParams { ...@@ -719,4 +724,43 @@ sub tplParams {
); );
} }
sub registerLogin {
my ( $self, $req ) = @_;
return unless ( defined $req->authResult );
my $history = $req->sessionInfo->{loginHistory} ||= {};
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
$history->{$type} ||= [];
$self->logger->debug("Current login saved into $type");
# Gather current login's parameters
my $login = $self->_sumUpSession( $req->{sessionInfo}, 1 );
$login->{error} = $self->error( $req->authResult )
if ( $req->authResult );
# Add current login into history
unshift @{ $history->{$type} }, $login;
# Forget oldest logins
splice @{ $history->{$type} }, $self->conf->{ $type . "Number" }
if ( scalar @{ $history->{$type} } > $self->conf->{ $type . "Number" } );
# Save into persistent session
$self->updatePersistentSession( $req, { loginHistory => $history, } );
}
# put main session data into a hash ref
# @param hashref $session The session to sum up
# @return hashref
sub _sumUpSession {
my ( $self, $session, $withoutUser ) = @_;
my $res =
$withoutUser
? {}
: { user => $session->{ $self->conf->{whatToTrace} } };
$res->{$_} = $session->{$_}
foreach ( "_utime", "ipAddr",
keys %{ $self->conf->{sessionDataToRemember} } );
return $res;
}
1; 1;
...@@ -40,11 +40,11 @@ sub grantSession { ...@@ -40,11 +40,11 @@ sub grantSession {
foreach ( sort sortByComment keys %{ $self->rules } ) { foreach ( sort sortByComment keys %{ $self->rules } ) {
$self->logger->debug("Grant session condition \"$_\""); $self->logger->debug("Grant session condition \"$_\"");
unless ( $self->rules->{$_}->( $req->sessionInfo ) ) { unless ( $self->rules->{$_}->( $req->sessionInfo ) ) {
$req->userData({}); $req->userData( {} );
$self->userLogger->error( 'User ' $self->userLogger->error( 'User '
. $req->user . $req->user
. " was not granted to open session (rule $_)" ); . " was not granted to open session (rule $_)" );
return PE_SESSIONNOTGRANTED; return $req->authResult(PE_SESSIONNOTGRANTED);
} }
} }
return PE_OK; return PE_OK;
......
...@@ -2,32 +2,41 @@ package Lemonldap::NG::Portal::Plugins::History; ...@@ -2,32 +2,41 @@ package Lemonldap::NG::Portal::Plugins::History;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK); use Lemonldap::NG::Portal::Main::Constants qw(PE_INFO PE_OK);
extends 'Lemonldap::NG::Portal::Main::Plugin', extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::OtherSessions'; 'Lemonldap::NG::Portal::Lib::OtherSessions';
sub afterDatas { 'run' } sub afterDatas { 'run' }
sub init { 1 }
sub run { sub run {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$req->info( if ( $req->param('checkLogins') ) {
( $self->logger->debug('History asked');
$req->sessionInfo->{loginHistory}->{successLogin} $req->info(
? $self->mkSessionArray( (
$req->sessionInfo->{loginHistory}->{successLogin}, $req->sessionInfo->{loginHistory}->{successLogin}
'lastLogins', 0, 0 ) ? $self->mkSessionArray(
: "" $req->sessionInfo->{loginHistory}->{successLogin},
) 'lastLogins', 0, 0 )
. ( : ""
$req->sessionInfo->{loginHistory}->{failedLogin} )
? $self->mkSessionArray( . (
$req->sessionInfo->{loginHistory}->{failedLogin}, $req->sessionInfo->{loginHistory}->{failedLogin}
'lastFailedLogins', 0, 1 ) ? $self->mkSessionArray(
: "" $req->sessionInfo->{loginHistory}->{failedLogin},
) 'lastFailedLogins', 0, 1 )
); : ""
PE_OK; )
);
unless($req->info) {
$req->info('<p trspan="noHistory"></p>');
}
return PE_INFO;
}
return PE_OK;
} }
1; 1;
...@@ -35,11 +35,11 @@ sub run { ...@@ -35,11 +35,11 @@ sub run {
and $req->{sessionInfo}->{ipAddr} ne $session->data->{ipAddr} ) and $req->{sessionInfo}->{ipAddr} ne $session->data->{ipAddr} )
) )
{ {
push @$deleted, $self->_sumUpSession( $session->data ); push @$deleted, $self->p->_sumUpSession( $session->data );
$self->p->_deleteSession( $req, $session, 1 ); $self->p->_deleteSession( $req, $session, 1 );
} }
else { else {
push @$otherSessions, $self->_sumUpSession( $session->data ); push @$otherSessions, $self->p->_sumUpSession( $session->data );
} }
} }
if ( $self->conf->{singleUserByIP} ) { if ( $self->conf->{singleUserByIP} ) {
...@@ -52,7 +52,7 @@ sub run { ...@@ -52,7 +52,7 @@ sub run {
unless ( $req->{sessionInfo}->{ $self->conf->{whatToTrace} } eq unless ( $req->{sessionInfo}->{ $self->conf->{whatToTrace} } eq
$session->data->{ $self->conf->{whatToTrace} } ) $session->data->{ $self->conf->{whatToTrace} } )
{ {
push @$deleted, $self->_sumUpSession( $session->data ); push @$deleted, $self->p->_sumUpSession( $session->data );
$self->p->_deleteSession( $req, $session, 1 ); $self->p->_deleteSession( $req, $session, 1 );
} }
} }
...@@ -66,21 +66,6 @@ sub run { ...@@ -66,21 +66,6 @@ sub run {
PE_OK; PE_OK;
} }
# put main session data into a hash ref
# @param hashref $session The session to sum up
# @return hashref
sub _sumUpSession {
my ( $self, $session, $withoutUser ) = @_;
my $res =
$withoutUser
? {}
: { user => $session->{ $self->conf->{whatToTrace} } };
$res->{$_} = $session->{$_}
foreach ( "_utime", "ipAddr",
keys %{ $self->conf->{sessionDataToRemember} } );
return $res;
}
# Build the removeOther link # Build the removeOther link
# Last part of URL is built trough javascript # Last part of URL is built trough javascript
# @return removeOther link in HTML code # @return removeOther link in HTML code
......
use Test::More;
use strict;
use IO::String;
BEGIN {
require 't/test-lib.pm';
}
my $res;
my $client = LLNG::Manager::Test->new(
{
ini => {
logLevel => 'error',
authentication => 'Demo',
userDB => 'Same',
loginHistoryEnabled => 1,
}
}
);
# Case "no history"
ok(
$res = $client->_post(
'/',
IO::String->new('user=dwho&password=dwho&checkLogins=1'),
length => 37,
accept => 'text/html',
),
'Auth query'
);
count(1);
expectOK($res);
my $id1 = expectCookie($res);
ok( $res->[2]->[0] =~ /trspan="noHistory"/, 'No history found' );
count(1);
ok( $res = $client->_get( '/', cookie => "lemonldap=$id1" ),
'Verify connection' );
count(1);
expectOK($res);
$client->logout($id1);
# History with 1 success
ok(
$res = $client->_post(
'/',
IO::String->new('user=dwho&password=dwho&checkLogins=1'),
length => 37,
accept => 'text/html',
),
'Auth query'
);
count(1);
expectOK($res);
$id1 = expectCookie($res);
ok( $res->[2]->[0] =~ /trspan="lastLogins"/, 'History found' );
count(1);
clean_sessions();
done_testing( count() );
Markdown is supported
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