Merge branch 'v2.0' into 1783
This commit is contained in:
commit
8ad895c3b8
|
@ -133,7 +133,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "llng-fastcgi-server 1"
|
||||
.TH llng-fastcgi-server 1 "2019-06-13" "perl v5.28.1" "User Contributed Perl Documentation"
|
||||
.TH llng-fastcgi-server 1 "2019-06-27" "perl v5.28.1" "User Contributed Perl Documentation"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
|
@ -4,7 +4,7 @@ use strict;
|
|||
use Mouse;
|
||||
use Lemonldap::NG::Common::Conf;
|
||||
|
||||
our $VERSION = '2.0.0';
|
||||
our $VERSION = '2.0.5';
|
||||
|
||||
has confAccess => (
|
||||
is => 'rw',
|
||||
|
@ -31,6 +31,9 @@ sub info {
|
|||
my $conf =
|
||||
$self->confAccess->getConf( { cfgNum => $self->cfgNum, raw => 1 } )
|
||||
or die $Lemonldap::NG::Common::Conf::msg;
|
||||
$conf->{cfgAuthorIP} ||= "No IP provided";
|
||||
$conf->{cfgDate} ||= 0;
|
||||
$conf->{cfgLog} ||= "No log provided";
|
||||
print qq{
|
||||
Num : $conf->{cfgNum}
|
||||
Author : $conf->{cfgAuthor}
|
||||
|
|
|
@ -10,7 +10,7 @@ our $VERSION = '2.0.0';
|
|||
has parser => (
|
||||
is => 'rw',
|
||||
builder => sub {
|
||||
return XML::LibXML->new();
|
||||
return XML::LibXML->new( load_ext_dtd => 0, expand_entities => 0 );
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ sub perlExpr {
|
|||
[ '&encrypt', '&token' ] );
|
||||
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
|
||||
$Lemonldap::NG::Common::Safelib::functions );
|
||||
$cpt->reval("BEGIN { warnings->unimport; } $val");
|
||||
$cpt->reval("BEGIN { 'warnings'->unimport; } $val");
|
||||
my $err = join(
|
||||
'',
|
||||
grep( { $_ =~ /Undefined subroutine/ ? () : $_; } split( /\n/, $@, 0 ) )
|
||||
|
|
|
@ -18,7 +18,7 @@ sub perlExpr {
|
|||
[ '&encrypt', '&token' ] );
|
||||
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
|
||||
$Lemonldap::NG::Common::Safelib::functions );
|
||||
$cpt->reval("BEGIN { warnings->unimport; } $val");
|
||||
$cpt->reval("BEGIN { 'warnings'->unimport; } $val");
|
||||
my $err = join( '',
|
||||
grep { $_ =~ /Undefined subroutine/ ? () : $_ } split( /\n/, $@ ) );
|
||||
return $err ? ( 1, "__badExpression__: $err" ) : (1);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use Lemonldap::NG::Common::Conf;
|
||||
use Lemonldap::NG::Common::Conf::Constants;
|
||||
use Lemonldap::NG::Manager::Conf::Parser;
|
||||
use Lemonldap::NG::Handler::Main::Jail;
|
||||
use Data::Dumper;
|
||||
use English qw(-no_match_vars);
|
||||
use File::Temp;
|
||||
|
|
|
@ -303,7 +303,7 @@
|
|||
"hideTree":"Masquer l'arbre",
|
||||
"httpOnly":"Protection contre javascript",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Usurpation d'identité",
|
||||
"impersonation":"Simulation d'identité",
|
||||
"impersonationRule":"Règle d'utilisation",
|
||||
"impersonationIdRule":"Règle d'utilisation des identités",
|
||||
"impersonationHiddenAttributes":"Attributs masqués",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -10,6 +10,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_ERROR
|
||||
PE_LOGOUT_OK
|
||||
PE_OK
|
||||
PE_BADURL
|
||||
PE_SENDRESPONSE
|
||||
);
|
||||
|
||||
|
@ -55,6 +56,18 @@ sub init {
|
|||
},
|
||||
['GET']
|
||||
);
|
||||
|
||||
# Add CAS Services, so we can check service= parameter on logout
|
||||
foreach my $casSrv ( keys %{ $self->conf->{casAppMetaDataOptions} } ) {
|
||||
if ( my $serviceUrl =
|
||||
$self->conf->{casAppMetaDataOptions}->{$casSrv}
|
||||
->{casAppMetaDataOptionsService} )
|
||||
{
|
||||
push @{ $self->p->{additionalTrustedDomains} }, $serviceUrl;
|
||||
$self->logger->debug(
|
||||
"CAS Service $serviceUrl added in trusted domains");
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -265,6 +278,19 @@ sub run {
|
|||
$logout_service = ''
|
||||
if ( $self->p->checkXSSAttack( 'service', $logout_service ) );
|
||||
|
||||
# If we use access control, check that the service URL is trusted
|
||||
if ( $self->conf->{casAccessControlPolicy} =~ /^(error|faketicket)$/i )
|
||||
{
|
||||
if ( $logout_service
|
||||
and not $self->p->isTrustedUrl($logout_service) )
|
||||
{
|
||||
$self->userLogger->error(
|
||||
"Untrusted service URL $logout_service"
|
||||
. "specified for CAS Logout" );
|
||||
return PE_BADURL;
|
||||
}
|
||||
}
|
||||
|
||||
# Delete linked CAS sessions
|
||||
$self->deleteCasSecondarySessions($session_id);
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -36,7 +36,7 @@ sub displayInit {
|
|||
sub display {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $skin_dir = $self->conf->{templatesDir};
|
||||
my $skin_dir = $self->conf->{templateDir};
|
||||
my ( $skinfile, %templateParams );
|
||||
|
||||
# 1. Authentication not complete
|
||||
|
@ -438,9 +438,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 [
|
||||
|
|
|
@ -39,6 +39,7 @@ has _jsRedirect => ( is => 'rw' );
|
|||
|
||||
# TrustedDomain regexp
|
||||
has trustedDomainsRe => ( is => 'rw' );
|
||||
has additionalTrustedDomains => ( is => 'rw', default => sub { [] } );
|
||||
|
||||
# Lists to store plugins entry-points
|
||||
my @entryPoints;
|
||||
|
@ -269,53 +270,6 @@ sub reloadConf {
|
|||
unless $self->{_sfEngine} =
|
||||
$self->loadPlugin( $self->conf->{'sfEngine'} );
|
||||
|
||||
# Initialize trusted domain regexp
|
||||
if ( $self->conf->{trustedDomains}
|
||||
and $self->conf->{trustedDomains} =~ /^\s*\*\s*$/ )
|
||||
{
|
||||
$self->trustedDomainsRe(qr#^https?://#);
|
||||
}
|
||||
else {
|
||||
my $re = Regexp::Assemble->new();
|
||||
if ( my $td = $self->conf->{trustedDomains} ) {
|
||||
$td =~ s/^\s*(.*?)\s*/$1/;
|
||||
foreach ( split( /\s+/, $td ) ) {
|
||||
next unless ($td);
|
||||
s#^\.#([^/]+\.)?#;
|
||||
$self->logger->debug("Domain $_ added in trusted domains");
|
||||
s/\./\\./g;
|
||||
|
||||
# This regexp is valid for the followings hosts:
|
||||
# - $td
|
||||
# - $domainlabel.$td
|
||||
# $domainlabel is build looking RFC2396
|
||||
# (see Regexp::Common::URI::RFC2396)
|
||||
$_ =~
|
||||
s/\*\\\./(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9]\\.)*/g;
|
||||
$re->add("$_");
|
||||
}
|
||||
}
|
||||
my $p = $self->conf->{portal};
|
||||
$p =~ s#https?://([^/]*).*$#$1#;
|
||||
$re->add( quotemeta($p) );
|
||||
foreach my $vhost ( keys %{ $self->conf->{locationRules} } ) {
|
||||
$self->logger->debug("Vhost $vhost added in trusted domains");
|
||||
$re->add( quotemeta($vhost) );
|
||||
$self->conf->{vhostOptions} ||= {};
|
||||
if ( my $tmp =
|
||||
$self->conf->{vhostOptions}->{$vhost}->{vhostAliases} )
|
||||
{
|
||||
foreach my $alias ( split /\s+/, $tmp ) {
|
||||
$self->logger->debug(
|
||||
"Alias $alias added in trusted domains");
|
||||
$re->add( quotemeta($alias) );
|
||||
}
|
||||
}
|
||||
}
|
||||
my $tmp = 'https?://' . $re->as_string . '(?::\d+)?(?:/|$)';
|
||||
$self->trustedDomainsRe(qr/$tmp/);
|
||||
}
|
||||
|
||||
# Compile macros in _macros, groups in _groups
|
||||
foreach my $type (qw(macros groups)) {
|
||||
$self->{"_$type"} = {};
|
||||
|
@ -344,6 +298,59 @@ sub reloadConf {
|
|||
$self->loadPlugin($plugin) or return $self->fail;
|
||||
}
|
||||
|
||||
# Initialize trusted domain regexp
|
||||
if ( $self->conf->{trustedDomains}
|
||||
and $self->conf->{trustedDomains} =~ /^\s*\*\s*$/ )
|
||||
{
|
||||
$self->trustedDomainsRe(qr#^https?://#);
|
||||
}
|
||||
else {
|
||||
my $re = Regexp::Assemble->new();
|
||||
if ( my $td = $self->conf->{trustedDomains} ) {
|
||||
$td =~ s/^\s*(.*?)\s*/$1/;
|
||||
foreach ( split( /\s+/, $td ) ) {
|
||||
next unless ($td);
|
||||
s#^\.#([^/]+\.)?#;
|
||||
$self->logger->debug("Domain $_ added in trusted domains");
|
||||
s/\./\\./g;
|
||||
|
||||
# This regexp is valid for the followings hosts:
|
||||
# - $td
|
||||
# - $domainlabel.$td
|
||||
# $domainlabel is build looking RFC2396
|
||||
# (see Regexp::Common::URI::RFC2396)
|
||||
$_ =~
|
||||
s/\*\\\./(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9]\\.)*/g;
|
||||
$re->add("$_");
|
||||
}
|
||||
}
|
||||
foreach ( @{ $self->{additionalTrustedDomains} },
|
||||
$self->conf->{portal} )
|
||||
{
|
||||
my $p = $_;
|
||||
$p =~ s#https?://([^/]*).*$#$1#;
|
||||
$re->add( quotemeta($p) );
|
||||
}
|
||||
foreach my $vhost ( keys %{ $self->conf->{locationRules} } ) {
|
||||
$self->logger->debug("Vhost $vhost added in trusted domains");
|
||||
$re->add( quotemeta($vhost) );
|
||||
$self->conf->{vhostOptions} ||= {};
|
||||
if ( my $tmp =
|
||||
$self->conf->{vhostOptions}->{$vhost}->{vhostAliases} )
|
||||
{
|
||||
foreach my $alias ( split /\s+/, $tmp ) {
|
||||
$self->logger->debug(
|
||||
"Alias $alias added in trusted domains");
|
||||
$re->add( quotemeta($alias) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $tmp = 'https?://' . $re->as_string . '(?::\d+)?(?:/|$)';
|
||||
$self->trustedDomainsRe(qr/$tmp/);
|
||||
|
||||
}
|
||||
|
||||
# Clean $req->pdata after authentication
|
||||
push @{ $self->endAuth }, sub {
|
||||
unless ( $_[0]->pdata->{keepPdata} ) {
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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) ) {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -152,7 +152,7 @@ ok( $res->{cn} eq 'Frédéric Accents', 'UTF-8 values' )
|
|||
or explain( $res, 'cn => Frédéric Accents' );
|
||||
count(3);
|
||||
|
||||
# Logout initiated by CAS
|
||||
# Logout initiated by CAS, try with invalid service URL first
|
||||
switch ('issuer');
|
||||
ok(
|
||||
$res = $issuer->_get(
|
||||
|
@ -164,7 +164,22 @@ ok(
|
|||
'Query SP for logout'
|
||||
);
|
||||
count(1);
|
||||
expectRedirection( $res, 'http://url.test/' );
|
||||
ok( $res->[2]->[0] =~ m%<span trmsg="37"></span>%, ' PE37 found' );
|
||||
count(1);
|
||||
|
||||
# Logout initiated by CAS, try with valid service URL
|
||||
ok(
|
||||
$res = $issuer->_get(
|
||||
'/cas/logout',
|
||||
query => 'service=http://auth.sp.com/',
|
||||
cookie => "lemonldap=$idpId,llngcasserver=idp",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'Query SP for logout'
|
||||
);
|
||||
count(1);
|
||||
|
||||
expectRedirection( $res, 'http://auth.sp.com/' );
|
||||
|
||||
# Verify that user has been disconnected
|
||||
ok( $res = $issuer->_get( '/', cookie => "lemonldap=$idpId" ), 'Query IdP' );
|
||||
|
@ -185,7 +200,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',
|
||||
|
@ -193,8 +207,13 @@ sub issuer {
|
|||
issuerDBCASActivation => 1,
|
||||
casAttr => 'uid',
|
||||
casAttributes => { cn => 'cn', uid => 'uid', },
|
||||
casAccessControlPolicy => 'none',
|
||||
casAccessControlPolicy => 'error',
|
||||
multiValuesSeparator => ';',
|
||||
casAppMetaDataOptions => {
|
||||
sp => {
|
||||
casAppMetaDataOptionsService => 'http://auth.sp.com',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -159,7 +159,6 @@ sub issuer {
|
|||
skipRenewConfirmation => 1,
|
||||
logLevel => $debug,
|
||||
|
||||
#templatesDir => 'site/htdocs/static',
|
||||
domain => 'idp.com',
|
||||
portal => 'http://auth.idp.com',
|
||||
authentication => 'Demo',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -26,7 +26,6 @@ my $client = LLNG::Manager::Test->new( {
|
|||
logLevel => 'error',
|
||||
useSafeJail => 1,
|
||||
notification => 1,
|
||||
templatesDir => 'site/templates/',
|
||||
notificationStorage => 'File',
|
||||
notificationStorageOptions => {
|
||||
dirName => 't'
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -22,7 +22,6 @@ my $client = LLNG::Manager::Test->new( {
|
|||
useSafeJail => 1,
|
||||
notification => 1,
|
||||
notificationServer => 1,
|
||||
templatesDir => 'site/templates/',
|
||||
notificationStorage => 'File',
|
||||
notificationStorageOptions => {
|
||||
dirName => 't'
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -30,7 +30,6 @@ SKIP: {
|
|||
logLevel => 'error',
|
||||
useSafeJail => 1,
|
||||
notification => 1,
|
||||
templatesDir => 'site/templates/',
|
||||
notificationStorage => 'File',
|
||||
notificationStorageOptions => { dirName => 't' },
|
||||
oldNotifFormat => 1,
|
||||
|
|
|
@ -64,7 +64,6 @@ SKIP: {
|
|||
useSafeJail => 1,
|
||||
notification => 1,
|
||||
notificationServer => 1,
|
||||
templatesDir => 'site/templates/',
|
||||
notificationStorage => 'File',
|
||||
notificationStorageOptions => {
|
||||
dirName => 't'
|
||||
|
|
126
lemonldap-ng-portal/t/62-UpgradeSession.t
Normal file
126
lemonldap-ng-portal/t/62-UpgradeSession.t
Normal 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() );
|
||||
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
159
lemonldap-ng-portal/t/78-2F-Upgrade.t
Normal file
159
lemonldap-ng-portal/t/78-2F-Upgrade.t
Normal 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() );
|
||||
|
Loading…
Reference in New Issue
Block a user