Enable history (#595)

This commit is contained in:
Xavier Guimard 2017-02-19 07:17:48 +00:00
parent 22c22af3c0
commit 2e680c2ff1
10 changed files with 151 additions and 47 deletions

View File

@ -2,16 +2,13 @@
* write REST method to create session with an id
* Test ForceAuth
* Calendar in notifications explorer
* login history
* Test for Zero
* replace SOAP by REST for notification creation
* "mail" in UserDB/*
* checkLogins in SAML
* verify activeTimer on/off on screen
* Don't display "login" when connected
* Add test for #173
* lwpSslOpt
# Combination

View File

@ -406,6 +406,7 @@ t/50-IssuerGet.t
t/60-status.t
t/61-grantSession.t
t/62-singleSession.t
t/63-History.t
t/90-translations.t
t/99-pod.t
t/lmConf-1.js

View File

@ -21,7 +21,7 @@ our @pList = (
u2fActivation => '::Plugins::U2F',
u2fSelfRegistration => '::Register::U2F',
notification => '::Plugins::Notifications',
checkLogins => '::Plugins::History',
portalCheckLogins => '::Plugins::History',
);
##@method list enabledPlugins

View File

@ -141,6 +141,7 @@ sub authLogout {
sub deleteSession {
my ( $self, $req ) = @_;
$req->userData( {} );
my $apacheSession = $self->getApacheSession( $req->id );
my $id = $req->id;
unless ($apacheSession) {
@ -267,7 +268,7 @@ sub getUser {
sub authenticate {
my ( $self, $req ) = @_;
return $self->_authentication->authenticate($req);
return $req->authResult( $self->_authentication->authenticate($req) );
}
# Third block: Session data providing

View File

@ -12,6 +12,9 @@ extends 'Lemonldap::NG::Common::PSGI::Request';
# List of methods to call
has steps => ( is => 'rw' );
# Authentication result
has authResult => ( is => 'rw' );
# Datas shared between methods
has datas => ( is => 'rw' );

View File

@ -152,12 +152,17 @@ sub do {
$req->steps($steps);
my $err = $req->error( $self->process($req) );
# TODO: updateStatus
# Update status
if ( my $p = $self->HANDLER->tsv->{statusPipe} ) {
print $p ( $req->user ? $req->user : $req->address ) . ' => '
. $req->uri
. " $err\n";
}
# Update history
if ( $self->conf->{loginHistoryEnabled} ) {
$self->registerLogin($req);
}
if ( $err == PE_SENDRESPONSE ) {
return $req->response;
}
@ -374,9 +379,6 @@ sub updatePersistentSession {
# Return if no infos to update
return () unless ( ref $infos eq 'HASH' and %$infos );
# Update current session
$self->updateSession( $req, $infos, $id );
$uid ||= $req->{sessionInfo}->{ $self->conf->{whatToTrace} }
|| $req->userData->{ $self->conf->{whatToTrace} };
unless ($uid) {
@ -385,6 +387,9 @@ sub updatePersistentSession {
}
$self->logger->debug("Update $uid persistent session");
# Update current session
$self->updateSession( $req, $infos, $id );
my $persistentSession = $self->getPersistentSession($uid);
$persistentSession->update($infos);
@ -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;

View File

@ -40,11 +40,11 @@ sub grantSession {
foreach ( sort sortByComment keys %{ $self->rules } ) {
$self->logger->debug("Grant session condition \"$_\"");
unless ( $self->rules->{$_}->( $req->sessionInfo ) ) {
$req->userData({});
$req->userData( {} );
$self->userLogger->error( 'User '
. $req->user
. " was not granted to open session (rule $_)" );
return PE_SESSIONNOTGRANTED;
return $req->authResult(PE_SESSIONNOTGRANTED);
}
}
return PE_OK;

View File

@ -2,32 +2,41 @@ package Lemonldap::NG::Portal::Plugins::History;
use strict;
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',
'Lemonldap::NG::Portal::Lib::OtherSessions';
sub afterDatas { 'run' }
sub init { 1 }
sub run {
my ( $self, $req ) = @_;
$req->info(
(
$req->sessionInfo->{loginHistory}->{successLogin}
? $self->mkSessionArray(
$req->sessionInfo->{loginHistory}->{successLogin},
'lastLogins', 0, 0 )
: ""
)
. (
$req->sessionInfo->{loginHistory}->{failedLogin}
? $self->mkSessionArray(
$req->sessionInfo->{loginHistory}->{failedLogin},
'lastFailedLogins', 0, 1 )
: ""
)
);
PE_OK;
if ( $req->param('checkLogins') ) {
$self->logger->debug('History asked');
$req->info(
(
$req->sessionInfo->{loginHistory}->{successLogin}
? $self->mkSessionArray(
$req->sessionInfo->{loginHistory}->{successLogin},
'lastLogins', 0, 0 )
: ""
)
. (
$req->sessionInfo->{loginHistory}->{failedLogin}
? $self->mkSessionArray(
$req->sessionInfo->{loginHistory}->{failedLogin},
'lastFailedLogins', 0, 1 )
: ""
)
);
unless($req->info) {
$req->info('<p trspan="noHistory"></p>');
}
return PE_INFO;
}
return PE_OK;
}
1;

View File

@ -35,11 +35,11 @@ sub run {
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 );
}
else {
push @$otherSessions, $self->_sumUpSession( $session->data );
push @$otherSessions, $self->p->_sumUpSession( $session->data );
}
}
if ( $self->conf->{singleUserByIP} ) {
@ -52,7 +52,7 @@ sub run {
unless ( $req->{sessionInfo}->{ $self->conf->{whatToTrace} } eq
$session->data->{ $self->conf->{whatToTrace} } )
{
push @$deleted, $self->_sumUpSession( $session->data );
push @$deleted, $self->p->_sumUpSession( $session->data );
$self->p->_deleteSession( $req, $session, 1 );
}
}
@ -66,21 +66,6 @@ sub run {
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
# Last part of URL is built trough javascript
# @return removeOther link in HTML code

View File

@ -0,0 +1,64 @@
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() );