Merge branch 'pdata-1785' into 'v2.0'

New keepPdata behavior

See merge request lemonldap-ng/lemonldap-ng!96
This commit is contained in:
Xavier Guimard 2019-09-30 15:08:15 +02:00
commit 37b09f39cb
6 changed files with 76 additions and 31 deletions

View File

@ -85,7 +85,11 @@ sub storeEnvAndCheckGateway {
$self->logger->debug(
"Gateway mode requested, redirect without authentication");
$req->response( [ 302, [ Location => $service ], [] ] );
$req->pdata( {} );
for my $s ( $self->ipath, $self->ipath . 'Path' ) {
$self->logger->debug("Removing $s from pdata")
if delete $req->pdata->{$s};
}
return PE_SENDRESPONSE;
}

View File

@ -140,24 +140,24 @@ sub init {
# psgi.js
->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] )
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
# portal.css
->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] )
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
# lmerror
->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
# Core REST API
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
->addAuthRoute( ping => 'authenticated', ['GET'] )
# Refresh session
->addAuthRoute( refresh => 'refresh', ['GET'] )
->addAuthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
->addAuthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
->addUnauthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
# Logout
@ -356,11 +356,18 @@ sub reloadConf {
# Clean $req->pdata after authentication
push @{ $self->endAuth }, sub {
unless ( $_[0]->pdata->{keepPdata} ) {
$self->logger->debug('Cleaning pdata');
$_[0]->pdata( {} );
$self->userLogger->notice( $_[0]->user . ' connected' )
if $_[0]->user;
my $tmp = $_[0]->pdata->{keepPdata} //= [];
foreach my $k ( keys %{ $_[0]->pdata } ) {
unless ( grep { $_ eq $k } @$tmp ) {
$self->logger->debug("Removing $k from pdata");
delete $_[0]->pdata->{$k};
}
}
$self->userLogger->notice( $_[0]->user . ' connected' ) if $_[0]->user;
if (@$tmp) {
$self->logger->debug(
'Add ' . join( ',', @$tmp ) . ' in keepPdata' );
$_[0]->pdata->{keepPdata} = $tmp;
}
return PE_OK;
};

View File

@ -34,9 +34,10 @@ has _ott => (
is => 'rw',
lazy => 1,
default => sub {
my $ott = $_[0]->{p}->loadModule('::Lib::OneTimeToken');
my $timeout = $_[0]->{conf}->{issuersTimeout} // $_[0]->{conf}->{formTimeout};
$ott->timeout( $timeout );
my $ott = $_[0]->{p}->loadModule('::Lib::OneTimeToken');
my $timeout = $_[0]->{conf}->{issuersTimeout}
// $_[0]->{conf}->{formTimeout};
$ott->timeout($timeout);
return $ott;
}
);
@ -86,7 +87,9 @@ sub _redirect {
$self->logger->debug('Processing _redirect');
$ir = $req->pdata->{ $self->ipath } ||= $self->storeRequest($req);
$req->pdata->{ $self->ipath . 'Path' } = \@path;
$req->pdata->{keepPdata} = 1;
$self->logger->debug(
'Add ' . $self->ipath . ', ' . $self->ipath . 'Path in keepPdata' );
push @{ $req->pdata->{keepPdata} }, $self->ipath, $self->ipath . 'Path';
$req->{urldc} = $self->conf->{portal} . '/' . $self->path;
}
else {
@ -111,8 +114,7 @@ sub _redirect {
# Restore urldc if auth doesn't need to dial with browser
$self->restoreRequest( $req, $ir );
delete $req->pdata->{ $self->ipath };
delete $req->pdata->{ $self->ipath . 'Path' };
$self->cleanPdata($req);
return $self->run( @_, @path );
}
: ()
@ -135,8 +137,9 @@ sub _forAuthUser {
# Clean pdata: keepPdata has been set, so pdata must be cleaned here
$self->logger->debug('Cleaning pdata');
$req->pdata( {} );
$req->urlNotBase64(1) if ( ref($self) =~ /::CAS$/ );
$self->cleanPdata($req);
$req->maybeNotBase64(1) if ( ref($self) =~ /::CAS$/ );
$req->mustRedirect(1);
return $self->p->do(
$req,
@ -151,6 +154,27 @@ sub _forAuthUser {
);
}
sub cleanPdata {
my ( $self, $req ) = @_;
for my $s ( $self->ipath, $self->ipath . 'Path' ) {
if ( $req->pdata->{$s} ) {
$self->logger->debug("Removing $s key from pdata");
delete $req->pdata->{$s};
}
}
if ( $req->pdata->{keepPdata} and ref $req->pdata->{keepPdata} ) {
@{ $req->pdata->{keepPdata} } =
grep {
$_ ne $self->ipath
and $_ ne $self->ipath . 'Path'
? 1
: ( $self->logger->debug("Removing $_ from keepPdata") and 0 )
} @{ $req->pdata->{keepPdata} };
delete $req->pdata->{keepPdata}
unless ( @{ $req->pdata->{keepPdata} } );
}
}
sub storeRequest {
my ( $self, $req ) = @_;
$self->logger->debug('Store issuer request');
@ -191,7 +215,7 @@ qq'<script type="text/javascript" src="$self->{p}->{staticPrefix}/common/js/auto
$req->data->{_url} =
encode_base64( $self->conf->{portal} . $req->path_info, '' );
$req->pdata->{ $self->ipath } = $self->storeRequest($req);
$req->pdata->{keepPdata} = 1;
push @{ $req->pdata->{keepPdata} }, $self->ipath, $self->ipath . 'Path';
return PE_RENEWSESSION;
}

View File

@ -95,12 +95,18 @@ sub controlUrl {
}
else {
if ( $url =~ m#[^A-Za-z0-9\+/=]# ) {
$self->userLogger->error(
"Value must be BASE64 encoded (param: url | value: $url)");
return PE_BADURL;
unless ( $req->maybeNotBase64 ) {
$self->userLogger->error(
"Value must be BASE64 encoded (param: url | value: $url)"
);
return PE_BADURL;
}
$req->{urldc} = $url;
}
else {
$req->{urldc} = decode_base64($url);
$req->{urldc} =~ s/[\r\n]//sg;
}
$req->{urldc} = decode_base64($url);
$req->{urldc} =~ s/[\r\n]//sg;
}
# For logout request, test if Referer comes from an authorized site
@ -153,10 +159,12 @@ sub checkLogout {
sub authLogout {
my ( $self, $req ) = @_;
my $res = $self->_authentication->authLogout($req);
unless ( $res or $req->pdata->{keepPdata} ) {
$self->logger->debug('Cleaning pdata');
$req->pdata( {} );
$self->logger->debug('Cleaning pdata');
my $tmp = $req->pdata->{keepPdata} //= [];
foreach my $k ( keys %{ $req->pdata } ) {
delete $req->pdata->{$k} unless ( grep { $_ eq $k } @$tmp );
}
$req->pdata->{keepPdata} = $tmp if @$tmp;
return $res;
}
@ -309,7 +317,7 @@ sub authenticate {
$req->steps( [
'setSessionInfo', 'setMacros',
'setPersistentSessionInfo', 'storeHistory',
@{ $self->afterData }, sub { PE_BADCREDENTIALS }
@{ $self->afterData }, sub { PE_BADCREDENTIALS }
]
);

View File

@ -57,7 +57,8 @@ has continue => ( is => 'rw' );
has checkLogins => ( is => 'rw' );
# Boolean to indicate that url isn't Base64 encoded
has urlNotBase64 => ( is => 'rw' );
has urlNotBase64 => ( is => 'rw' );
has maybeNotBase64 => ( is => 'rw' );
# Menu error
has menuError => ( is => 'rw' );

View File

@ -134,7 +134,8 @@ SKIP: {
# Expect pdata to be cleared
$pdata = expectCookie( $res, 'lemonldappdata' );
ok( $pdata !~ 'issuerRequestsaml', 'SAML request cleared from pdata' );
ok( $pdata !~ 'issuerRequestsaml', 'SAML request cleared from pdata' )
or explain( $pdata, 'not issuerRequestsaml' );
( $host, $url, $s ) =
expectAutoPost( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost',