Merge branch 'v2.0'

This commit is contained in:
Xavier Guimard 2019-06-27 07:59:37 +02:00
commit 72439d341f
46 changed files with 308 additions and 48 deletions

View File

@ -10,7 +10,7 @@ our $VERSION = '2.1.0';
has parser => (
is => 'rw',
builder => sub {
return XML::LibXML->new();
return XML::LibXML->new( load_ext_dtd => 0, expand_entities => 0 );
}
);

View File

@ -60,7 +60,7 @@ ok( @values == 2, 'Found 2 service header values' )
count(2);
diag 'Waiting';
sleep 2;
sleep 1;
ok(
$res = $client->_get(
@ -82,7 +82,7 @@ ok( @values == 2, 'Found 2 service header values' )
count(2);
diag 'Waiting';
sleep 1;
sleep 2;
ok(
$res = $client->_get(

View File

@ -734,7 +734,7 @@
"sfaTitle":"Second Factors Authentication",
"sfRequired":"Require 2FA",
"sfRemovedNotification":"Display a message if an expired SF is removed",
"sfRemovedMsgRule":"Activation",
"sfRemovedMsgRule":"激活",
"sfRemovedUseNotif":"Use Notifications plugin",
"sfRemovedNotifMsg":"Notification message",
"sfRemovedNotifRef":"Notification reference",

View File

@ -17,7 +17,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
has parser => (
is => 'rw',
builder => sub {
return XML::LibXML->new();
return XML::LibXML->new( load_ext_dtd => 0, expand_entities => 0 );
}
);
@ -32,7 +32,7 @@ has stylesheet => (
( $self->conf->{notificationXSLTfile}
and -e $self->conf->{notificationXSLTfile} )
? $self->conf->{notificationXSLTfile}
: $self->conf->{templatesDir} . '/common/notification.xsl';
: $self->conf->{templateDir} . '/common/notification.xsl';
unless ( -e $styleFile ) {
$self->{logger}->error("$styleFile not found, aborting");
die "$styleFile not found";

View File

@ -55,8 +55,8 @@ sub displayInit {
sub display {
my ( $self, $req ) = @_;
my $skin_dir = $self->conf->{templatesDir};
my ( $skinfile, %templateParams, $filter );
my $skin_dir = $self->conf->{templateDir};
my ( $skinfile, %templateParams );
# 1. Authentication not complete
@ -343,9 +343,9 @@ sub staticFile {
require Plack::Util;
require Cwd;
require HTTP::Date;
open my $fh, '<:raw', $self->conf->{templatesDir} . "/$file"
open my $fh, '<:raw', $self->conf->{templateDir} . "/$file"
or return $self->sendError( $req,
$self->conf->{templatesDir} . "/$file: $!", 403 );
$self->conf->{templateDir} . "/$file: $!", 403 );
my @stat = stat $file;
Plack::Util::set_io_path( $fh, Cwd::realpath($file) );
return [

View File

@ -160,7 +160,7 @@ sub authLogout {
sub deleteSession {
my ( $self, $req ) = @_;
if ( my $id = $req->id || $req->userData->{_session_id} ) {
my $apacheSession = $self->getApacheSession( $req->id );
my $apacheSession = $self->getApacheSession( $id );
unless ($apacheSession) {
$self->logger->debug("Session $id already deleted");
return PE_OK;

View File

@ -37,6 +37,14 @@ sub init {
my ($self) = @_;
unless ( $self->noRoute ) {
$self->logger->debug( 'Adding ' . $self->prefix . '2fcheck routes' );
$self->addAuthRoute(
$self->prefix . '2fcheck' => '_verify',
['POST']
);
$self->addAuthRoute(
$self->prefix . '2fcheck' => '_redirect',
['GET']
);
$self->addUnauthRoute(
$self->prefix . '2fcheck' => '_verify',
['POST']

View File

@ -58,7 +58,9 @@ sub ask {
sub confirm {
my ( $self, $req ) = @_;
$req->pdata->{keepPdata} = 1;
# Disabled due to #1821
#$req->pdata->{keepPdata} = 1;
my $upg;
if ( my $t = $req->param('upgrading') ) {
if ( $self->ott->getToken($t) ) {

View File

@ -215,7 +215,7 @@
"serviceProvidedBy":"Ce service est fourni par",
"sessionsDeleted":"Les sessions suivantes ont été fermées",
"sfaManager":"Gestionnaire 2ndFA",
"spoofId":"Identifiant usurpé",
"spoofId":"Identifiant simulé",
"SSOSessionInactive":"Session SSO inactive",
"stayConnected": "Rester connecté sur cet appareil",
"submit":"Envoyer",

View File

@ -173,7 +173,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -204,7 +204,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -186,7 +186,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -190,7 +190,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -185,7 +185,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -204,7 +204,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -258,7 +258,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -258,7 +258,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -110,7 +110,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -229,7 +229,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -118,7 +118,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -221,7 +221,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -159,7 +159,6 @@ sub issuer {
skipRenewConfirmation => 1,
logLevel => $debug,
#templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -313,7 +313,6 @@ sub issuer {
ini => {
skipRenewConfirmation => 1,
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Choice',

View File

@ -93,7 +93,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -193,7 +193,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -308,7 +308,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -145,7 +145,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -168,7 +168,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -127,7 +127,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -97,7 +97,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -163,7 +163,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -137,7 +137,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -128,7 +128,6 @@ sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -228,7 +228,6 @@ sub issuer {
ini => {
skipRenewConfirmation => 1,
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -213,7 +213,6 @@ sub issuer {
ini => {
skipRenewConfirmation => 1,
logLevel => $debug,
templatesDir => 'site/htdocs/static',
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',

View File

@ -39,7 +39,6 @@ q{INSERT INTO notifications VALUES ('dwho','testref','2016-05-30 00:00:00',?,nul
logLevel => 'error',
useSafeJail => 1,
notification => 1,
templatesDir => 'site/templates/',
notificationStorage => 'DBI',
notificationStorageOptions => {
dbiChain => "dbi:SQLite:dbname=$file",

View File

@ -26,7 +26,6 @@ my $client = LLNG::Manager::Test->new( {
logLevel => 'error',
useSafeJail => 1,
notification => 1,
templatesDir => 'site/templates/',
notificationStorage => 'File',
notificationStorageOptions => {
dirName => 't'

View File

@ -26,7 +26,6 @@ my $client = LLNG::Manager::Test->new( {
logLevel => 'error',
useSafeJail => 1,
notification => 1,
templatesDir => 'site/templates/',
notificationStorage => 'File',
notificationStorageOptions => { dirName => 't' },
oldNotifFormat => 0,

View File

@ -22,7 +22,6 @@ my $client = LLNG::Manager::Test->new( {
useSafeJail => 1,
notification => 1,
notificationServer => 1,
templatesDir => 'site/templates/',
notificationStorage => 'File',
notificationStorageOptions => {
dirName => 't'

View File

@ -38,7 +38,6 @@ qq{INSERT INTO notifications VALUES ('dwho','testref','2016-05-30 00:00:00','<?x
logLevel => 'error',
useSafeJail => 1,
notification => 1,
templatesDir => 'site/templates/',
notificationStorage => 'DBI',
notificationStorageOptions => {
dbiChain => "dbi:SQLite:dbname=$file",

View File

@ -30,7 +30,6 @@ SKIP: {
logLevel => 'error',
useSafeJail => 1,
notification => 1,
templatesDir => 'site/templates/',
notificationStorage => 'File',
notificationStorageOptions => { dirName => 't' },
oldNotifFormat => 1,

View File

@ -64,7 +64,6 @@ SKIP: {
useSafeJail => 1,
notification => 1,
notificationServer => 1,
templatesDir => 'site/templates/',
notificationStorage => 'File',
notificationStorageOptions => {
dirName => 't'

View File

@ -0,0 +1,126 @@
use Test::More;
use strict;
use IO::String;
use Data::Dumper;
require 't/test-lib.pm';
require 't/smtp.pm';
use_ok('Lemonldap::NG::Common::FormEncode');
count(1);
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
upgradeSession => 1,
authentication => 'Choice',
apacheAuthnLevel => 5,
userDB => 'Same',
'authChoiceModules' => {
'strong' => 'Apache;Demo;Null;;;{}',
'weak' => 'Demo;Demo;Null;;;{}'
},
'vhostOptions' => {
'test1.example.com' => {
'vhostAuthnLevel' => 3
},
},
}
}
);
# Try to authenticate
# -------------------
ok(
my $res = $client->_post(
'/',
IO::String->new('user=dwho&password=dwho&lmAuth=weak'),
length => 35,
accept => 'text/html',
),
'Auth query'
);
count(1);
my $id = expectCookie($res);
# After attempting to access test1,
# the handler sends up back to /upgradesession
# --------------------------------------------
ok(
my $res = $client->_get(
'/upgradesession',
query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29t',
accept => 'text/html',
cookie => "lemonldap=$id",
),
'Upgrade session query'
);
count(1);
my ( $host, $url, $query ) =
expectForm( $res, undef, '/upgradesession', 'confirm', 'url' );
# Accept session upgrade
# ----------------------
ok(
my $res = $client->_post(
'/upgradesession',
IO::String->new($query),
length => length($query),
accept => 'text/html',
cookie => "lemonldap=$id",
),
'Accept session upgrade query'
);
count(1);
my $pdata = expectCookie( $res, 'lemonldappdata' );
my ( $host, $url, $query ) = expectForm( $res, '#', undef, 'upgrading', 'url' );
$query = $query . "&lmAuth=strong";
# Attempt login with the "strong" auth choice
# this should trigger 2FA
# -------------------------------------------
ok(
my $res = $client->_post(
'/upgradesession',
IO::String->new($query),
length => length($query),
accept => 'text/html',
cookie => "lemonldap=$id;lemonldappdata=$pdata",
custom => {
REMOTE_USER => 'dwho',
},
),
'Post login'
);
count(1);
$pdata = expectCookie( $res, 'lemonldappdata' );
$id = expectCookie($res);
expectRedirection( $res, 'http://test1.example.com' );
# Make pdata was cleared and we aren't being redirected
ok(
my $res = $client->_get(
'/',
accept => 'text/html',
cookie => "lemonldap=$id;lemonldappdata=$pdata",
),
'Post login'
);
count(1);
expectOK($res);
clean_sessions();
done_testing( count() );

View File

@ -23,7 +23,6 @@ SKIP: {
sfRemovedUseNotif => 1,
portalMainLogo => 'common/logos/logo_llng_old.png',
notification => 1,
templatesDir => 'site/templates/',
notificationStorage => 'File',
notificationStorageOptions => { dirName => 't' },
oldNotifFormat => 0,

View File

@ -23,7 +23,6 @@ SKIP: {
sfRemovedUseNotif => 1,
portalMainLogo => 'common/logos/logo_llng_old.png',
notification => 1,
templatesDir => 'site/templates/',
notificationStorage => 'File',
notificationStorageOptions => { dirName => 't' },
oldNotifFormat => 1,

View File

@ -0,0 +1,159 @@
use Test::More;
use strict;
use IO::String;
use Data::Dumper;
require 't/test-lib.pm';
require 't/smtp.pm';
use_ok('Lemonldap::NG::Common::FormEncode');
count(1);
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
upgradeSession => 1,
mail2fActivation => '$_choice eq "strong"',
mail2fCodeRegex => '\d{4}',
mail2fAuthnLevel => 5,
authentication => 'Choice',
userDB => 'Same',
'authChoiceModules' => {
'strong' => 'Demo;Demo;Null;;;{}',
'weak' => 'Demo;Demo;Null;;;{}'
},
'vhostOptions' => {
'test1.example.com' => {
'vhostAuthnLevel' => 3
},
},
}
}
);
# Try to authenticate
# -------------------
ok(
my $res = $client->_post(
'/',
IO::String->new('user=dwho&password=dwho&lmAuth=weak'),
length => 35,
accept => 'text/html',
),
'Auth query'
);
count(1);
my $id = expectCookie($res);
# After attempting to access test1,
# the handler sends up back to /upgradesession
# --------------------------------------------
ok(
my $res = $client->_get(
'/upgradesession',
query => 'url=aHR0cDovL3Rlc3QxLmV4YW1wbGUuY29t',
accept => 'text/html',
cookie => "lemonldap=$id",
),
'Upgrade session query'
);
count(1);
my ( $host, $url, $query ) =
expectForm( $res, undef, '/upgradesession', 'confirm', 'url' );
# Accept session upgrade
# ----------------------
ok(
my $res = $client->_post(
'/upgradesession',
IO::String->new($query),
length => length($query),
accept => 'text/html',
cookie => "lemonldap=$id",
),
'Accept session upgrade query'
);
count(1);
my $pdata = expectCookie( $res, 'lemonldappdata' );
my ( $host, $url, $query ) = expectForm( $res, '#', undef, 'upgrading', 'url' );
$query = $query . "&user=dwho&password=dwho&lmAuth=strong";
# Attempt login with the "strong" auth choice
# this should trigger 2FA
# -------------------------------------------
ok(
my $res = $client->_post(
'/upgradesession',
IO::String->new($query),
length => length($query),
accept => 'text/html',
cookie => "lemonldap=$id;lemonldappdata=$pdata",
),
'Post login'
);
count(1);
my $pdata = expectCookie( $res, 'lemonldappdata' );
( $host, $url, $query ) =
expectForm( $res, undef, '/mail2fcheck', 'token', 'code' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);
ok( mail() =~ m%<b>(\d{4})</b>%, 'Found 2F code in mail' )
or print STDERR Dumper( mail() );
count(1);
my $code = $1;
# Post 2F code
# ------------
$query =~ s/code=/code=${code}/;
ok(
$res = $client->_post(
'/mail2fcheck',
IO::String->new($query),
length => length($query),
accept => 'text/html',
cookie => "lemonldap=$id;lemonldappdata=$pdata",
),
'Post code'
);
count(1);
$pdata = expectCookie( $res, 'lemonldappdata' );
$id = expectCookie($res);
expectRedirection( $res, 'http://test1.example.com' );
# Make pdata was cleared and we aren't being redirected
ok(
my $res = $client->_get(
'/',
accept => 'text/html',
cookie => "lemonldap=$id;lemonldappdata=$pdata",
),
'Post login'
);
count(1);
expectOK($res);
clean_sessions();
done_testing( count() );