Merge branch 'v2.0'

This commit is contained in:
Xavier Guimard 2019-08-28 11:35:43 +02:00
commit 4193f4fb51
32 changed files with 208 additions and 124 deletions

View File

@ -248,7 +248,7 @@ sub _FileGKFAS {
closedir DIR;
my %res;
for my $f (@t) {
open F, "$args->{Directory}/$f";
open F, '<', "$args->{Directory}/$f";
my $row = join '', <F>;
if ( ref($data) eq 'CODE' ) {
eval { $res{$f} = &$data( $args->{unserialize}->($row), $f ); };
@ -288,7 +288,7 @@ sub _PHPGKFAS {
closedir DIR;
my %res;
for my $f (@t) {
open F, "$args->{SavePath}/$f";
open F, '<', "$args->{SavePath}/$f";
my $row = join '', <F>;
if ( ref($data) eq 'CODE' ) {
$res{$f} =

View File

@ -40,7 +40,7 @@ sub available {
closedir D;
@conf =
sort { $a <=> $b }
map { /lmConf-(\d+)(?:\.js(?:on))?/ ? ( $1 + 0 ) : () } @conf;
map { /lmConf-(\d+)(?:\.js(?:on))?/ ? ( $1 + 0 ) : () } @conf;
return @conf;
}
@ -106,7 +106,7 @@ sub load {
if ($filename) {
local $/ = '';
my $ret;
unless ( open FILE, $filename ) {
unless ( open FILE, '<', $filename ) {
$Lemonldap::NG::Common::Conf::msg .= "Read error: $!$@";
return undef;
}
@ -124,9 +124,9 @@ sub load {
# Old format
elsif ( -e "$self->{dirName}/lmConf-$cfgNum" ) {
open FILE, "$self->{dirName}/lmConf-$cfgNum" or die "$!$@";
open FILE, '<', "$self->{dirName}/lmConf-$cfgNum" or die "$!$@";
local $/ = "";
unless ( open FILE, $self->{dirName} . "/lmConf-$cfgNum" ) {
unless ( open FILE, '<', $self->{dirName} . "/lmConf-$cfgNum" ) {
$Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n";
return undef;
}

View File

@ -101,7 +101,7 @@ sub load {
$filename = $self->_yamlFile($cfgNum);
local $/ = '';
my $ret;
unless ( open FILE, $filename ) {
unless ( open FILE, '<', $filename ) {
$Lemonldap::NG::Common::Conf::msg .= "Read error: $!$@";
return undef;
}

View File

@ -47,7 +47,7 @@ sub get {
my $files;
foreach my $file (@notif) {
unless ( open F, $self->{dirName} . "/$file" ) {
unless ( open F, '<', $self->{dirName} . "/$file" ) {
$self->logger->error(
"Unable to read notification $self->{dirName}/$file");
next;
@ -116,7 +116,8 @@ sub newNotif {
return ( 0, 'This notification still exists' ) if ( -e $filename );
my $old = ( $filename =~ /(.*?)(?:\.$ext)$/ )[0] . '.done';
return ( 0, 'This notification has been done' ) if ( -e $old );
open my $F, ">$filename" or return ( 0, "Unable to create $filename ($!)" );
open my $F, '>', $filename
or return ( 0, "Unable to create $filename ($!)" );
binmode($F);
print $F $content;
return ( 0, "Unable to close $filename ($!)" ) unless ( close $F );

View File

@ -122,7 +122,7 @@ sub userError {
sub sendJSONresponse {
my ( $self, $req, $j, %args ) = @_;
$args{code} ||= 200;
$args{headers} ||= $req->respHeaders || [];
$args{headers} ||= [ $req->spliceHdrs ];
my $type = 'application/json; charset=utf-8';
if ( ref $j ) {
eval { $j = $_json->encode($j); };
@ -152,9 +152,9 @@ sub sendError {
return [
$code,
[
'Content-Type' => 'application/xml; charset=utf-8',
@{ $req->respHeaders || [] },
'Content-Length' => length($s)
'Content-Type' => 'application/xml; charset=utf-8',
'Content-Length' => length($s),
$req->spliceHdrs,
],
[$s]
];
@ -189,8 +189,9 @@ body{background:#000;color:#fff;padding:10px 50px;font-family:sans-serif;}a{text
return [
$code,
[
'Content-Type' => 'text/html; charset=utf-8',
@{ $req->respHeaders || [] }, 'Content-Length' => length($s)
'Content-Type' => 'text/html; charset=utf-8',
'Content-Length' => length($s),
$req->spliceHdrs,
],
[$s]
];
@ -248,7 +249,7 @@ sub sendHtml {
$sc = '.' unless ($sc);
$sc =~ s#/*$#/#;
$args{code} ||= 200;
$args{headers} ||= $req->respHeaders || [];
$args{headers} ||= [ $req->spliceHdrs ];
my $htpl;
unless ( ref $template ) {

View File

@ -58,6 +58,11 @@ sub respHeaders {
return $self->{respHeaders};
}
sub spliceHdrs {
my ($self) = @_;
return splice @{ $self->{respHeaders} };
}
sub accept { $_[0]->env->{HTTP_ACCEPT} }
sub encodings { $_[0]->env->{HTTP_ACCEPT_ENCODING} }
sub languages { $_[0]->env->{HTTP_ACCEPT_LANGUAGE} }
@ -192,6 +197,10 @@ Example:
# Add header
$req->respHeaders->{"X-Key"} = "Value";
=head2 spliceHdrs
Returns headers array and flush it.
=head2 set_param( $key, $value )
L<Plack::Request> param() method is read-only. This method can be used to

View File

@ -69,7 +69,7 @@ sub _run {
return sub {
my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] );
my $res = $self->handler($req);
push @{ $res->[1] }, @{ $req->{respHeaders} };
push @{ $res->[1] }, $req->spliceHdrs;
return $res;
};
}
@ -89,7 +89,7 @@ sub status {
return sub {
my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] );
$self->api->status($req);
return [ 200, [ @{ $req->{respHeaders} } ], [ $req->{respBody} ] ];
return [ 200, [ $req->spliceHdrs ], [ $req->{respBody} ] ];
};
}
@ -107,7 +107,7 @@ sub reload {
return sub {
my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] );
$self->api->reload($req);
return [ 200, [ @{ $req->{respHeaders} } ], [ $req->{respBody} ] ];
return [ 200, [ $req->spliceHdrs ], [ $req->{respBody} ] ];
};
}
@ -132,28 +132,19 @@ sub _authAndTrace {
if ( $res < 300 ) {
if ($noCall) {
return [ $res, $req->{respHeaders}, [] ];
return [ $res, [ $req->spliceHdrs ], [] ];
}
else {
$self->logger->debug('User authenticated, calling handler()');
$res = $self->handler($req);
# Insert respHeaders in response only if not already set
my %hdr1 = @{ $res->[1] };
my %hdr2 = @{ $req->{respHeaders} };
foreach ( keys %hdr2 ) {
unless ( $hdr1{$_} and $hdr2{$_} eq $hdr1{$_} ) {
push @{ $res->[1] }, ( $_ => $hdr2{$_} );
}
}
push @{ $res->[1] }, $req->spliceHdrs;
return $res;
}
return $res;
}
elsif ( $res < 400 ) {
return [ $res, $req->{respHeaders}, [] ];
return [ $res, [ $req->spliceHdrs ], [] ];
}
else {
my %h = $req->{respHeaders} ? @{ $req->{respHeaders} } : ();
my $s = $type->tsv->{portal}->() . "/lmerror/$res";
$s =
'<html><head><title>Redirection</title></head><body>'
@ -161,9 +152,15 @@ sub _authAndTrace {
. '<h1>Please wait</h1>'
. qq{<p>An error occurs, you're going to be redirected to <a href="$s">$s</a>.</p>}
. '</body></html>';
$h{'Content-Type'} = 'text/html';
$h{'Content-Length'} = length $s;
return [ $res, [%h], [$s] ];
return [
$res,
[
$req->spliceHdrs,
'Content-Type' => 'text/html',
'Content-Length' => length $s
],
[$s]
];
}
}

View File

@ -33,7 +33,7 @@ BEGIN {
sub run {
my $class = shift;
my $r = $_[0];
my $ret = $class->Lemonldap::NG::Handler::Main::run($r);
my ( $ret, $session ) = $class->Lemonldap::NG::Handler::Main::run($r);
# Continue only if user is authorized
return $ret unless ( $ret == $class->OK );
@ -107,7 +107,7 @@ sub run {
eval 'use Apache2::Filter' unless ( $INC{"Apache2/Filter.pm"} );
if ( $INC{"Apache2/Filter.pm"} ) {
$r->add_output_filter(
$r->{env}->{'psgi.r'}->add_output_filter(
sub {
my $f = shift;
while ( $f->read( my $buffer, 1024 ) ) {
@ -158,7 +158,7 @@ sub _setToken {
$secureTokenExpiration );
unless ($res) {
$class->( "Unable to store secure token $key", 'error' );
$class->logger->error("Unable to store secure token $key");
return;
}
@ -177,7 +177,7 @@ sub _deleteToken {
my $res = $secureTokenMemcachedConnection->delete($key);
unless ($res) {
$class->( "Unable to delete secure token $key", 'error' );
$class->logger->error("Unable to delete secure token $key");
}
else {
$class->logger->info("Token $key deleted");
@ -201,15 +201,14 @@ sub _isAlive {
my $total_c = $stats->{'total'}->{'connection_structures'};
my $total_i = $stats->{'total'}->{'total_items'};
$class->(
"Memcached connection is alive ($total_c connections / $total_i items)",
'debug'
$class->logger->debug->(
"Memcached connection is alive ($total_c connections / $total_i items)"
);
return 1;
}
$class->( "Memcached connection is not alive", 'error' );
$class->logger->error("Memcached connection is not alive");
return 0;
}
@ -222,7 +221,7 @@ sub _returnError {
my ( $class, $r, $secureTokenAllowOnError ) = @_;
if ($secureTokenAllowOnError) {
$class->( "Allow request without secure token", 'debug' );
$class->logger->debug("Allow request without secure token");
return $class->OK;
}

View File

@ -348,16 +348,18 @@ sub sessionStorageInit {
if ( $conf->{status} ) {
my $params = "";
if ( $class->tsv->{sessionCacheModule} ) {
require Data::Dumper;
$params = ' '
. $class->tsv->{sessionCacheModule} . ','
. Data::Dumper->new( [ $class->tsv->{sessionCacheOptions} ] )
->Terse(1)->Indent(0)->Dump; # To send params on one line
$params = ' ' . join(
',',
$class->tsv->{sessionCacheModule} . map {
"$_ => "
. $class->tsv->{sessionCacheOptions}->{$_}
} keys %{ $class->tsv->{sessionCacheOptions} // {} }
);
}
$class->tsv->{statusPipe}->print("RELOADCACHE $params\n");
}
}
return 1;
return 1;
}
## @imethod void headersInit(hashRef args)

View File

@ -147,7 +147,9 @@ sub run {
# ACCOUNTING (1. Inform web server)
$class->set_user( $req, $session->{ $class->tsv->{whatToTrace} } );
$class->set_custom( $req, $session->{ $class->tsv->{customToTrace} } );
$class->set_custom( $req, $session->{ $class->tsv->{customToTrace} } )
if $class->tsv->{customToTrace}
and $session->{ $class->tsv->{customToTrace} };
# AUTHORIZATION
return ( $class->forbidden( $req, $session ), $session )
@ -409,7 +411,7 @@ sub fetchId {
my $value =
$lookForHttpCookie
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
if ( $value && $lookForHttpCookie && $class->tsv->{securedCookie} == 3 ) {
$value = $class->tsv->{cipher}->decryptHex( $value, "http" );

View File

@ -47,7 +47,7 @@ sub addAuthRouteWithRedirect {
sub _auth_and_redirect {
my ( $self, $req ) = @_;
$self->api->goToPortal( $req, $req->{env}->{REQUEST_URI} );
return [ 302, $req->respHeaders, [] ];
return [ 302, [$req->spliceHdrs], [] ];
}
sub defaultAuthRoute {
@ -71,6 +71,7 @@ sub _run {
if ( $res->[0] < 300 ) {
$self->routes( $self->authRoutes );
$req->userData( $self->api->data );
$req->respHeaders($res->[1]);
}
elsif ( $res->[0] != 403 and not $req->data->{noTry} ) {
@ -85,15 +86,7 @@ sub _run {
return $res;
}
$res = $self->handler($req);
# Insert respHeaders in response only if not already set
my %hdr1 = @{ $res->[1] };
my %hdr2 = @{ $req->{respHeaders} };
foreach ( keys %hdr2 ) {
unless ( $hdr1{$_} and $hdr2{$_} eq $hdr1{$_} ) {
push @{ $res->[1] }, ( $_ => $hdr2{$_} );
}
}
push @{ $res->[1] }, $req->spliceHdrs;
return $res;
};
}

View File

@ -26,7 +26,7 @@ sub _run {
return sub {
my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] );
my $res = $self->_authAndTrace($req);
push @{ $res->[1] }, @{ $req->respHeaders },
push @{ $res->[1] }, $req->spliceHdrs,
Cookie => ( $req->{Cookie} // '' );
return $res;
};

View File

@ -65,13 +65,10 @@ sub _run {
#@param $req Lemonldap::NG::Common::PSGI::Request
sub handler {
my ( $self, $req ) = @_;
my $hdrs = $req->{respHeaders};
$req->{respHeaders} = [];
my @convertedHdrs =
( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) );
my $i = 0;
while ( my $k = shift @$hdrs ) {
my $v = shift @$hdrs;
while ( my ( $k, $v ) = splice( @{ $req->{respHeaders} }, 0, 2 ) ) {
if ( $k =~ /^(?:Lm-Remote-(?:User|Custom)|Cookie)$/ ) {
push @convertedHdrs, $k, $v;
}

View File

@ -53,9 +53,9 @@ count(2);
my @headers = grep { /service|^XFromVH$/ } @{ $res->[1] };
my @values = grep { /\.example\.com|^$sessionId$/ } @{ $res->[1] };
ok( @headers == 4, 'Found 4 service headers' )
ok( @headers == 2, 'Found 2 service headers' )
or print STDERR Data::Dumper::Dumper( $res->[1] );
ok( @values == 4, 'Found 4 service header values' )
ok( @values == 2, 'Found 2 service header values' )
or print STDERR Data::Dumper::Dumper( $res->[1] );
count(2);
@ -75,9 +75,9 @@ count(2);
@headers = grep { /service|^XFromVH$/ } @{ $res->[1] };
@values = grep { /\.example\.com|^$sessionId$/ } @{ $res->[1] };
ok( @headers == 4, 'Found 4 service headers' )
ok( @headers == 2, 'Found 2 service headers' )
or print STDERR Data::Dumper::Dumper( $res->[1] );
ok( @values == 4, 'Found 4 service header values' )
ok( @values == 2, 'Found 2 service header values' )
or print STDERR Data::Dumper::Dumper( $res->[1] );
count(2);
@ -116,9 +116,9 @@ count(2);
@headers = grep { /service|^XFromVH$/ } @{ $res->[1] };
@values = grep { /\.example\.com|^$sessionId$/ } @{ $res->[1] };
ok( @headers == 4, 'Found 4 service headers' )
ok( @headers == 2, 'Found 2 service headers' )
or print STDERR Data::Dumper::Dumper( $res->[1] );
ok( @values == 4, 'Found 4 service header values' )
ok( @values == 2, 'Found 2 service header values' )
or print STDERR Data::Dumper::Dumper( $res->[1] );
count(2);

View File

@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="shortcut icon" type="image/vnd.microsoft.icon" sizes="16x16 32x32 48x48 64x64 128x128" href="<TMPL_VAR NAME="STATIC_PREFIX">logos/favicon.ico" />
<link rel="icon" type="image/vnd.microsoft.icon" sizes="16x16 32x32 48x48 64x64 128x128" href="<TMPL_VAR NAME="STATIC_PREFIX">logos/favicon.ico" />
<!-- //if:usedebianlibs

View File

@ -506,7 +506,7 @@ t/32-Auth-and-issuer-OIDC-implicit.t
t/32-Auth-and-issuer-OIDC-sorted.t
t/32-CAS-10.t
t/32-OIDC-RP-rule.t
t/32-OIDC-Token-Spoof.t
t/32-OIDC-Token-Security.t
t/33-Auth-and-issuer-OpenID2.t
t/34-Auth-Proxy-and-REST-Server.t
t/34-Auth-Proxy-and-SOAP-Server.t
@ -577,7 +577,7 @@ t/66-CDA-with-REST.t
t/66-CDA-with-SOAP.t
t/66-CDA.t
t/67-CheckUser-with-Global-token.t
t/67-Checkuser-with-Impersonation-and-whatToTrace.t
t/67-CheckUser-with-Impersonation-and-whatToTrace.t
t/67-CheckUser-with-issuer-SAML-POST.t
t/67-CheckUser-with-token.t
t/67-CheckUser.t
@ -615,6 +615,7 @@ t/77-2F-Mail-with-global-storage.t
t/77-2F-Mail.t
t/78-2F-Upgrade.t
t/90-Translations.t
t/99-Dont-load-Dumper.t
t/99-pod.t
t/gpghome/key.asc
t/gpghome/openpgp-revocs.d/9482CEFB055809CBAFE6D71AAB2D5542891D1677.rev

View File

@ -85,7 +85,7 @@ sub run {
else {
# Use HTML template
$body = $self->loadTemplate(
$body = $self->loadMailTemplate(
$req,
'mail_2fcode',
filter => $tr,

View File

@ -163,7 +163,7 @@ sub handler {
);
# Redirect
return [ 302, [ Location => $urldc, @{ $req->respHeaders } ], [] ];
return [ 302, [ Location => $urldc, $req->spliceHdrs ], [] ];
}
@ -180,7 +180,7 @@ sub handler {
[
'Content-Type' => 'text/plain',
'Content-Length' => 2,
@{ $req->respHeaders }
$req->spliceHdrs,
],
['OK']
];

View File

@ -3,7 +3,6 @@ package Lemonldap::NG::Portal::Lib::Notifications::JSON;
use strict;
use Mouse;
use JSON qw(from_json);
use Data::Dumper;
our $VERSION = '2.1.0';
@ -260,7 +259,8 @@ sub notificationServer {
return $self->p->sendError( $req, "Unable to decode JSON file: $@",
400 )
if ($@);
$self->p->logger->debug( "Notification $notif: " . Dumper($json) );
$self->p->logger->debug(
"Notification $notif: " . $notifs->{$notif} );
if ($ref) {
push( @$res,
map { "$_" => $json->{$_} },

View File

@ -81,6 +81,21 @@ has transport => (
},
);
sub loadMailTemplate {
my ( $self, $req, $name, %prm ) = @_;
# HTML::Template cache interferes with email translation (#1897)
$prm{cache} = 0 unless defined $prm{cache};
$prm{params}->{STATIC_PREFIX} = $self->p->staticPrefix;
my %extra =
$self->p->can('tplParams')
? $self->p->tplParams($req)
: ();
$prm{params}->{$_} = $extra{$_} for keys %extra;
return $self->loadTemplate( $req, $name, %prm );
}
sub translate {
my ( $self, $req ) = @_;
@ -89,7 +104,7 @@ sub translate {
my $json = $self->conf->{templateDir} . "/common/mail/$lang_code.json";
$json = $self->conf->{templateDir} . '/common/mail/en.json'
unless ( -f $json );
open F, $json
open F, '<', $json
or die 'Installation error: '
. $!
. " ($self->{conf}->{templateDir}/$lang_code.json or $self->{conf}->{templateDir}/common/mail/en.json)";

View File

@ -8,7 +8,6 @@ package Lemonldap::NG::Portal::Main;
use strict;
use Mouse;
use JSON;
use Data::Dumper;
use constant CommonPrms => {
MAIN_LOGO => 'portalMainLogo',
@ -139,8 +138,9 @@ sub display {
# 1.3 There is a message to display
elsif ( my $info = $req->info ) {
$self->logger->debug('Display: info detected');
$self->logger->debug(
'Hidden values -> ' . Dumper( $req->{portalHiddenFormValues} ) );
$self->logger->debug('Hidden values :');
$self->logger->debug( " $_: " . $req->{portalHiddenFormValues}->{$_} )
for keys %{ $req->{portalHiddenFormValues} // {} };
$skinfile = 'info';
%templateParams = (
AUTH_ERROR => $self->error,

View File

@ -342,8 +342,7 @@ sub autoRedirect {
$req->data->{redirectFormMethod} = "get";
}
else {
return [ 302,
[ Location => $req->{urldc}, @{ $req->respHeaders } ], [] ];
return [ 302, [ Location => $req->{urldc}, $req->spliceHdrs ], [] ];
}
}
return $self->display($req);
@ -759,10 +758,12 @@ sub cookie {
sub _dump {
my ( $self, $variable ) = @_;
require Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Useperl = 1;
$self->logger->debug( "Dump: " . Data::Dumper::Dumper($variable) );
if ( $self->conf->{logLevel} eq 'debug' ) {
require Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Useperl = 1;
$self->logger->debug( "Dump: " . Data::Dumper::Dumper($variable) );
}
return;
}
@ -816,11 +817,11 @@ sub sendHtml {
'Pragma' => 'no-cache', # HTTP 1.0
'Expires' => '0'; # Proxies
my @cors = split /;/, $self->cors;
if ( $self->conf->{corsEnabled} ) {
my @cors = split /;/, $self->cors;
push @{ $res->[1] }, @cors;
$self->logger->debug(
"Apply following CORS policy : " . Data::Dumper::Dumper( \@cors ) );
$self->logger->debug('Apply following CORS policy :');
$self->logger->debug(" $_") for @cors;
}
# Set authorized URL for POST
@ -1005,7 +1006,7 @@ sub registerLogin {
}
my $history = $req->sessionInfo->{_loginHistory} ||= {};
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
$history->{$type} ||= [];
$self->logger->debug("Current login saved into $type");
@ -1059,7 +1060,7 @@ sub loadTemplate {
search_path_on_include => 1,
die_on_bad_params => 0,
die_on_missing_include => 1,
cache => 1,
cache => ( defined $prm{cache} ? $prm{cache} : 1 ),
global_vars => 0,
( $prm{filter} ? ( filter => $prm{filter} ) : () ),
);

View File

@ -39,7 +39,7 @@ sub hAttr {
sub init {
my ($self) = @_;
my $hd = $self->p->HANDLER;
$self->addAuthRoute( checkuser => 'check', ['POST'] );
$self->addAuthRoute( checkuser => 'check', ['POST'] );
$self->addAuthRouteWithRedirect( checkuser => 'display', ['GET'] );
# Parse identity rule
@ -173,10 +173,10 @@ sub check {
? 'checkUserMerged'
: 'checkUser';
if ($compute) {
$msg = 'checkUserComputeSession';
$msg = 'checkUserComputeSession';
$attrs->{authenticationLevel} = $authLevel;
$attrs->{_auth} = $authMode;
if ( $self->conf->{impersonationRule} ) {
$self->logger->debug("Map real attributes...");
my %realAttrs = map {
@ -270,7 +270,7 @@ sub check {
}
sub display {
my ( $self, $req ) = @_;
my ( $self, $req ) = @_;
my ( $attrs, $array_attrs ) = ( {}, [] );
$self->logger->debug("Display current session data...");
@ -420,8 +420,8 @@ sub _splitAttributes {
$self->logger->debug("Dispatching attributes...");
while (@$attrs) {
my $element = shift @$attrs;
$self->logger->debug(
'Processing element: ' . Data::Dumper::Dumper($element) );
$self->logger->debug( "Processing element: $element->{key} => "
. ( $element->{value} // '' ) );
my $ok = 0;
if ( $element->{key} eq 'groups' ) {
$self->logger->debug('Key "groups" found');
@ -450,14 +450,15 @@ sub _splitAttributes {
my $prefix = "$self->{conf}->{impersonationPrefix}";
while (@$others) {
my $element = shift @$others;
$self->logger->debug(
'Processing attribute: ' . Data::Dumper::Dumper($element) );
$self->logger->debug( "Processing attribute $element->{key} => "
. ( $element->{value} // '' ) );
if ( $element->{key} =~ /^$prefix.+$/ ) {
push @$realAttrs, $element;
$self->logger->debug(' -> Real attribute');
}
else {
push @$spoofedAttrs, $element;
#$self->logger->debug(' -> Spoofed attribute');
}
}

View File

@ -19,7 +19,7 @@ has rules => ( is => 'rw', default => sub { {} } );
sub init {
my ($self) = @_;
my $hd = $self->p->HANDLER;
foreach ( keys %{ $self->conf->{grantSessionRules} } ) {
foreach ( keys %{ $self->conf->{grantSessionRules} // {} } ) {
$self->logger->debug("GrantRule key -> $_");
$self->logger->debug(
"GrantRule value -> " . $self->conf->{grantSessionRules}->{$_} );

View File

@ -334,7 +334,7 @@ sub _reset {
else {
# Use HTML template
$body = $self->loadTemplate(
$body = $self->loadMailTemplate(
$req,
'mail_confirm',
filter => $tr,
@ -473,7 +473,7 @@ sub changePwd {
else {
# Use HTML template
$body = $self->loadTemplate(
$body = $self->loadMailTemplate(
$req,
'mail_password',
filter => $tr,

View File

@ -309,7 +309,7 @@ sub _register {
my $html = 1;
# Use HTML template
$body = $self->loadTemplate(
$body = $self->loadMailTemplate(
$req,
'mail_register_confirm',
filter => $tr,
@ -369,7 +369,7 @@ sub _register {
my $html = 1;
# Use HTML template
$body = $self->loadTemplate(
$body = $self->loadMailTemplate(
$req,
'mail_register_done',
filter => $tr,

View File

@ -8,6 +8,7 @@
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- //if:usedebianlibs
<link rel="stylesheet" type="text/css" href="/javascript/bootstrap4/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="/javascript/font-awesome/css/font-awesome.min.css" />

View File

@ -10,10 +10,7 @@ BEGIN {
}
my ( $res, $user, $pwd );
my $maintests = 9;
my $mailSend = 0;
my $mail2 = 0;
my $maintests = 12;
SKIP: {
eval
@ -50,7 +47,20 @@ SKIP: {
$res = $client->_post(
'/resetpwd', IO::String->new($query),
length => length($query),
accept => 'text/html'
accept => 'text/html',
cookie => 'llnglanguage=fr',
),
'Post mail'
);
like( mail(), qr#<span>Bonjour</span>#, "Found french greeting" );
# Test another language (#1897)
ok(
$res = $client->_post(
'/resetpwd', IO::String->new($query),
length => length($query),
accept => 'text/html',
cookie => 'llnglanguage=en',
),
'Post mail'
);
@ -62,6 +72,8 @@ SKIP: {
ok( mail() =~ m%Content-Type: image/png; name="logo_llng_old.png"%,
'Found custom Main logo in mail' )
or print STDERR Dumper( mail() );
like( mail(), qr#<span>Hello</span>#, "Found english greeting" );
ok( mail() =~ m#a href="http://auth.example.com/resetpwd\?(.*?)"#,
'Found link in mail' );
$query = $1;
@ -89,8 +101,6 @@ SKIP: {
);
ok( mail() =~ /Your password was changed/, 'Password was changed' );
#print STDERR Dumper($query);
}
count($maintests);

View File

@ -166,7 +166,6 @@ SKIP: {
expectAuthenticatedAs( $res, 'davros@badguy.org@idp' );
# Simple SP access
my $res;
ok(
$res = $sp->_get(
'/', accept => 'text/html',
@ -179,7 +178,7 @@ SKIP: {
$res->[1],
'Set-Cookie => lemonldapidp=http://auth.idp.com/saml/metadata; domain=.sp.com; path=/'
);
my ( $host, $url, $s ) =
( $host, $url, $s ) =
expectAutoPost( $res, 'auth.idp.com', '/saml/singleSignOn',
'SAMLRequest' );
@ -195,7 +194,7 @@ SKIP: {
'Post SAML request to IdP'
);
expectOK($res);
my $pdata = 'lemonldappdata=' . expectCookie( $res, 'lemonldappdata' );
$pdata = 'lemonldappdata=' . expectCookie( $res, 'lemonldappdata' );
# Try to authenticate with an authorized user to IdP
$s = "user=french&password=french&$s";
@ -254,7 +253,8 @@ SKIP: {
),
'CheckUser form',
);
my ( $host, $url, $query ) =
my $query;
( $host, $url, $query ) =
expectForm( $res, undef, '/checkuser', 'user', 'url' );
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%,
'Found trspan="checkUser"' )
@ -263,10 +263,14 @@ SKIP: {
or explain( $res->[2]->[0], 'Attribute uid' );
ok( $res->[2]->[0] =~ m%<td scope="row">french</td>%, 'Found value french' )
or explain( $res->[2]->[0], 'Value french' );
ok( $res->[2]->[0] =~ m%<td scope="row">_lassoSessionDump</td>%, 'Found attribute _lassoSessionDump' )
ok( $res->[2]->[0] =~ m%<td scope="row">_lassoSessionDump</td>%,
'Found attribute _lassoSessionDump' )
or explain( $res->[2]->[0], 'Attribute _lassoSessionDump' );
ok( $res->[2]->[0] =~ m%ProviderID="http://auth.idp.com/saml/metadata" AssertionID=%, 'Found ProviderID & AssertionID values' )
or explain( $res->[2]->[0], 'Provider & Assertion Ids' );
ok(
$res->[2]->[0] =~
m%ProviderID="http://auth.idp.com/saml/metadata" AssertionID=%,
'Found ProviderID & AssertionID values'
) or explain( $res->[2]->[0], 'Provider & Assertion Ids' );
count(6);
# CheckUser request with an unknown user
@ -301,7 +305,7 @@ m%<div class="message message-positive alert"><span trspan="PE5"></span></div>%,
'POST checkuser'
);
my ( $host, $url, $query ) =
( $host, $url, $query ) =
expectForm( $res, undef, '/checkuser', 'user', 'url' );
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%,
'Found trspan="checkUser"' )

View File

@ -197,7 +197,7 @@ ok(
);
count(3);
my ( $host, $url, $query ) =
( $host, $url, $query ) =
expectForm( $res, undef, '/checkuser', 'user', 'url' );
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
or explain( $res->[2]->[0], 'trspan="checkUser"' );

View File

@ -0,0 +1,49 @@
use Test::More tests => 5;
use_ok('Lemonldap::NG::Portal::Main');
my ( $p, $app );
my $ini = {
configStorage => {
type => 'File',
dirName => 't',
},
localSessionStorage => 'Cache::FileCache',
localSessionStorageOptions => {
namespace => 'lemonldap-ng-session',
cache_root => 't/',
cache_depth => 0,
},
logLevel => 'error',
cookieName => 'lemonldap',
domain => 'example.com',
templateDir => 'site/templates',
staticPrefix => '/static',
loginHistoryEnabled => 1,
securedCookie => 0,
https => 0,
portalDisplayResetPassword => 1,
portalStatus => 1,
cda => 1,
notification => 1,
portalCheckLogins => 1,
stayConnected => 1,
bruteForceProtection => 1,
grantSessionRules => 1,
upgradeSession => 1,
autoSigninRules => { a => 1 },
checkState => 1,
portalForceAuthn => 1,
checkUser => 1,
impersonationRule => 1,
contextSwitchingRule => 1,
grantSessionRules => { a => 1 },
checkStateSecret => 'x',
};
ok( $p = Lemonldap::NG::Portal::Main->new, 'Portal object' );
ok( $p->init($ini), 'Init' );
ok( $app = $p->run, 'App' );
eval { Data::Dumper::Dumper( {} ) };
ok( $@, "Portal doesn't depend on Data::Dumper" );