Merge branch 'v2.0'
This commit is contained in:
commit
77301e70ca
|
@ -142,8 +142,9 @@
|
|||
},
|
||||
"locationRules": {
|
||||
"auth.example.com" : {
|
||||
"(?#checkUser)/checkuser" : "$uid eq \"dwho\"",
|
||||
"default" : "deny"
|
||||
"(?#checkUser)^/checkuser": "$uid eq \"dwho\"",
|
||||
"(?#errors)^/lmerror/": "accept",
|
||||
"default" : "accept"
|
||||
},
|
||||
"manager.example.com": {
|
||||
"(?#Configuration)^/(manager\\.html|conf/)": "$uid eq \"dwho\"",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35)
|
||||
.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
|
@ -54,16 +54,20 @@
|
|||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.if !\nF .nr F 0
|
||||
.if \nF>0 \{\
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{\
|
||||
. if \nF \{\
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{\
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. if !\nF==2 \{\
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\"
|
||||
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
||||
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
||||
|
@ -129,7 +133,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "llng-fastcgi-server 1"
|
||||
.TH llng-fastcgi-server 1 "2018-08-03" "perl v5.26.2" "User Contributed Perl Documentation"
|
||||
.TH llng-fastcgi-server 1 "2019-03-05" "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
|
||||
|
|
|
@ -64,30 +64,34 @@ sub defaultValues {
|
|||
'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
|
||||
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
|
||||
},
|
||||
'gpgDb' => '',
|
||||
'groups' => {},
|
||||
'handlerInternalCache' => 15,
|
||||
'hiddenAttributes' => '_password',
|
||||
'httpOnly' => 1,
|
||||
'https' => -1,
|
||||
'infoFormMethod' => 'get',
|
||||
'issuerDBCASPath' => '^/cas/',
|
||||
'issuerDBCASRule' => 1,
|
||||
'issuerDBGetParameters' => {},
|
||||
'issuerDBGetPath' => '^/get/',
|
||||
'issuerDBGetRule' => 1,
|
||||
'issuerDBOpenIDConnectPath' => '^/oauth2/',
|
||||
'issuerDBOpenIDConnectRule' => 1,
|
||||
'issuerDBOpenIDPath' => '^/openidserver/',
|
||||
'issuerDBOpenIDRule' => 1,
|
||||
'issuerDBSAMLPath' => '^/saml/',
|
||||
'issuerDBSAMLRule' => 1,
|
||||
'jsRedirect' => 0,
|
||||
'krbAuthnLevel' => 3,
|
||||
'krbRemoveDomain' => 1,
|
||||
'ldapAuthnLevel' => 2,
|
||||
'ldapBase' => 'dc=example,dc=com',
|
||||
'ldapExportedVars' => {
|
||||
'gpgDb' => '',
|
||||
'groups' => {},
|
||||
'handlerInternalCache' => 15,
|
||||
'hiddenAttributes' => '_password',
|
||||
'httpOnly' => 1,
|
||||
'https' => -1,
|
||||
'impersonationHiddenAttributes' => '_2fDevices _loginHistory',
|
||||
'impersonationPrefix' => 'real_',
|
||||
'impersonationRule' => 0,
|
||||
'impersonationSkipEmptyValues' => 1,
|
||||
'infoFormMethod' => 'get',
|
||||
'issuerDBCASPath' => '^/cas/',
|
||||
'issuerDBCASRule' => 1,
|
||||
'issuerDBGetParameters' => {},
|
||||
'issuerDBGetPath' => '^/get/',
|
||||
'issuerDBGetRule' => 1,
|
||||
'issuerDBOpenIDConnectPath' => '^/oauth2/',
|
||||
'issuerDBOpenIDConnectRule' => 1,
|
||||
'issuerDBOpenIDPath' => '^/openidserver/',
|
||||
'issuerDBOpenIDRule' => 1,
|
||||
'issuerDBSAMLPath' => '^/saml/',
|
||||
'issuerDBSAMLRule' => 1,
|
||||
'jsRedirect' => 0,
|
||||
'krbAuthnLevel' => 3,
|
||||
'krbRemoveDomain' => 1,
|
||||
'ldapAuthnLevel' => 2,
|
||||
'ldapBase' => 'dc=example,dc=com',
|
||||
'ldapExportedVars' => {
|
||||
'cn' => 'cn',
|
||||
'mail' => 'mail',
|
||||
'uid' => 'uid'
|
||||
|
|
|
@ -41,12 +41,12 @@ sub serviceToXML {
|
|||
samlOrganizationURL
|
||||
);
|
||||
|
||||
if ($type and $type eq 'idp') {
|
||||
$template->param( 'hideSPMetadata', 1);
|
||||
if ( $type and $type eq 'idp' ) {
|
||||
$template->param( 'hideSPMetadata', 1 );
|
||||
}
|
||||
|
||||
if ($type and $type eq 'sp') {
|
||||
$template->param( 'hideIDPMetadata', 1);
|
||||
if ( $type and $type eq 'sp' ) {
|
||||
$template->param( 'hideIDPMetadata', 1 );
|
||||
}
|
||||
|
||||
foreach (@param_auto) {
|
||||
|
|
|
@ -31,8 +31,8 @@ sub new {
|
|||
$self->env->{PATH_INFO} =~ s|^$tmp|/|;
|
||||
}
|
||||
$self->env->{PATH_INFO} ||= '/';
|
||||
$self->{uri} = uri_unescape( $self->env->{REQUEST_URI} );
|
||||
$self->{uri} =~ s|^//+|/|g;
|
||||
$self->env->{REQUEST_URI} =~ s|^//+|/|g;
|
||||
$self->{uri} = uri_unescape( $self->env->{REQUEST_URI} );
|
||||
$self->{data} = {};
|
||||
$self->{error} = 0;
|
||||
$self->{respHeaders} = [];
|
||||
|
|
|
@ -44,20 +44,20 @@ sub getStatus {
|
|||
if ( $ENV{LLNGSTATUSHOST} ) {
|
||||
require IO::Socket::INET;
|
||||
foreach ( 64322 .. 64331 ) {
|
||||
if ( $statusOut
|
||||
= IO::Socket::INET->new( Proto => 'udp', LocalPort => $_ ) )
|
||||
if ( $statusOut =
|
||||
IO::Socket::INET->new( Proto => 'udp', LocalPort => $_ ) )
|
||||
{
|
||||
$args = ' host='
|
||||
. ( $ENV{LLNGSTATUSCLIENT} || 'localhost' ) . ":$_";
|
||||
$args =
|
||||
' host=' . ( $ENV{LLNGSTATUSCLIENT} || 'localhost' ) . ":$_";
|
||||
last;
|
||||
}
|
||||
}
|
||||
return $class->abort( $req,
|
||||
"$class: status page can not be displayed, unable to open socket"
|
||||
) unless ($statusOut);
|
||||
"$class: status page can not be displayed, unable to open socket" )
|
||||
unless ($statusOut);
|
||||
}
|
||||
return $class->abort( $req, "$class: status page can not be displayed" )
|
||||
unless ( $statusPipe and $statusOut );
|
||||
unless ( $statusPipe and $statusOut );
|
||||
my $q = $req->{env}->{QUERY_STRING} || '';
|
||||
if ( $q =~ /\s/ ) {
|
||||
$class->logger->error("Bad characters in query");
|
||||
|
@ -84,12 +84,12 @@ sub checkType {
|
|||
|
||||
if ( time() - $class->lastCheck > $class->checkTime ) {
|
||||
die("$class: No configuration found")
|
||||
unless ( $class->checkConf );
|
||||
unless ( $class->checkConf );
|
||||
}
|
||||
my $vhost = $class->resolveAlias($req);
|
||||
return ( defined $class->tsv->{type}->{$vhost} )
|
||||
? $class->tsv->{type}->{$vhost}
|
||||
: 'Main';
|
||||
? $class->tsv->{type}->{$vhost}
|
||||
: 'Main';
|
||||
}
|
||||
|
||||
## @rmethod int run
|
||||
|
@ -125,7 +125,7 @@ sub run {
|
|||
my ($cond);
|
||||
( $cond, $protection ) = $class->conditionSub($rule) if ($rule);
|
||||
$protection = $class->isUnprotected( $req, $uri ) || 0
|
||||
unless ( defined $protection );
|
||||
unless ( defined $protection );
|
||||
|
||||
if ( $protection == $class->SKIP ) {
|
||||
$class->logger->debug("Access control skipped");
|
||||
|
@ -150,7 +150,7 @@ sub run {
|
|||
|
||||
# AUTHORIZATION
|
||||
return ( $class->forbidden( $req, $session ), $session )
|
||||
unless ( $class->grant( $req, $session, $uri, $cond ) );
|
||||
unless ( $class->grant( $req, $session, $uri, $cond ) );
|
||||
$class->updateStatus( $req, 'OK',
|
||||
$session->{ $class->tsv->{whatToTrace} } );
|
||||
|
||||
|
@ -168,8 +168,8 @@ sub run {
|
|||
|
||||
# Log access granted
|
||||
$class->logger->debug( "User "
|
||||
. $session->{ $class->tsv->{whatToTrace} }
|
||||
. " was granted to access to $uri" );
|
||||
. $session->{ $class->tsv->{whatToTrace} }
|
||||
. " was granted to access to $uri" );
|
||||
|
||||
# Catch POST rules
|
||||
$class->postOutputFilter( $req, $session, $uri );
|
||||
|
@ -192,7 +192,7 @@ sub run {
|
|||
|
||||
# Redirect user to the portal
|
||||
$class->logger->info("No cookie found")
|
||||
unless ($id);
|
||||
unless ($id);
|
||||
|
||||
# if the cookie was fetched, a log is sent by retrieveSession()
|
||||
$class->updateStatus( $req, $id ? 'EXPIRED' : 'REDIRECT' );
|
||||
|
@ -243,10 +243,10 @@ sub lmLog {
|
|||
sub checkMaintenanceMode {
|
||||
my ( $class, $req ) = @_;
|
||||
my $vhost = $class->resolveAlias($req);
|
||||
my $_maintenance
|
||||
= ( defined $class->tsv->{maintenance}->{$vhost} )
|
||||
? $class->tsv->{maintenance}->{$vhost}
|
||||
: $class->tsv->{maintenance}->{_};
|
||||
my $_maintenance =
|
||||
( defined $class->tsv->{maintenance}->{$vhost} )
|
||||
? $class->tsv->{maintenance}->{$vhost}
|
||||
: $class->tsv->{maintenance}->{_};
|
||||
|
||||
if ($_maintenance) {
|
||||
$class->logger->debug("Maintenance mode enabled");
|
||||
|
@ -272,17 +272,17 @@ sub grant {
|
|||
}
|
||||
}
|
||||
for (
|
||||
my $i = 0;
|
||||
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 );
|
||||
my $i = 0 ;
|
||||
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 ) ;
|
||||
$i++
|
||||
)
|
||||
)
|
||||
{
|
||||
if ( $uri =~ $class->tsv->{locationRegexp}->{$vhost}->[$i] ) {
|
||||
$class->logger->debug( 'Regexp "'
|
||||
. $class->tsv->{locationConditionText}->{$vhost}->[$i]
|
||||
. '" match' );
|
||||
. $class->tsv->{locationConditionText}->{$vhost}->[$i]
|
||||
. '" match' );
|
||||
return $class->tsv->{locationCondition}->{$vhost}->[$i]
|
||||
->( $req, $session );
|
||||
->( $req, $session );
|
||||
}
|
||||
}
|
||||
unless ( $class->tsv->{defaultCondition}->{$vhost} ) {
|
||||
|
@ -319,8 +319,8 @@ sub forbidden {
|
|||
|
||||
# Log forbidding
|
||||
$class->userLogger->notice( "User "
|
||||
. $session->{ $class->tsv->{whatToTrace} }
|
||||
. " was forbidden to access to $vhost$uri" );
|
||||
. $session->{ $class->tsv->{whatToTrace} }
|
||||
. " was forbidden to access to $vhost$uri" );
|
||||
$class->updateStatus( $req, 'REJECT',
|
||||
$session->{ $class->tsv->{whatToTrace} } );
|
||||
|
||||
|
@ -377,9 +377,9 @@ sub goToPortal {
|
|||
$class->logger->debug(
|
||||
"Redirect $req->{env}->{REMOTE_ADDR} to portal (url was $url)");
|
||||
$class->set_header_out( $req,
|
||||
'Location' => $class->tsv->{portal}->()
|
||||
. "$path?url=$urlc_init"
|
||||
. ( $arg ? "&$arg" : "" ) );
|
||||
'Location' => $class->tsv->{portal}->()
|
||||
. "$path?url=$urlc_init"
|
||||
. ( $arg ? "&$arg" : "" ) );
|
||||
return $class->REDIRECT;
|
||||
}
|
||||
|
||||
|
@ -389,9 +389,9 @@ sub goToError {
|
|||
$class->logger->debug(
|
||||
"Redirect $req->{env}->{REMOTE_ADDR} to lmError (url was $url)");
|
||||
$class->set_header_out( $req,
|
||||
'Location' => $class->tsv->{portal}->()
|
||||
. "/lmerror/$code"
|
||||
. "?url=$urlc_init" );
|
||||
'Location' => $class->tsv->{portal}->()
|
||||
. "/lmerror/$code"
|
||||
. "?url=$urlc_init" );
|
||||
return $class->REDIRECT;
|
||||
}
|
||||
|
||||
|
@ -403,12 +403,12 @@ sub fetchId {
|
|||
my $t = $req->{env}->{HTTP_COOKIE} or return 0;
|
||||
my $vhost = $class->resolveAlias($req);
|
||||
my $lookForHttpCookie = ( $class->tsv->{securedCookie} =~ /^(2|3)$/
|
||||
and not $class->_isHttps( $req, $vhost ) );
|
||||
and not $class->_isHttps( $req, $vhost ) );
|
||||
my $cn = $class->tsv->{cookieName};
|
||||
my $value
|
||||
= $lookForHttpCookie
|
||||
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
|
||||
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
|
||||
my $value =
|
||||
$lookForHttpCookie
|
||||
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
|
||||
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
|
||||
|
||||
if ( $value && $lookForHttpCookie && $class->tsv->{securedCookie} == 3 ) {
|
||||
$value = $class->tsv->{cipher}->decryptHex( $value, "http" );
|
||||
|
@ -446,8 +446,8 @@ sub retrieveSession {
|
|||
|
||||
# 2. Get the session from cache or backend
|
||||
my $session = $req->data->{session} = (
|
||||
Lemonldap::NG::Common::Session->new(
|
||||
{ storageModule => $class->tsv->{sessionStorageModule},
|
||||
Lemonldap::NG::Common::Session->new( {
|
||||
storageModule => $class->tsv->{sessionStorageModule},
|
||||
storageModuleOptions => $class->tsv->{sessionStorageOptions},
|
||||
cacheModule => $class->tsv->{sessionCacheModule},
|
||||
cacheModuleOptions => $class->tsv->{sessionCacheOptions},
|
||||
|
@ -464,36 +464,36 @@ sub retrieveSession {
|
|||
|
||||
# Verify that session is valid
|
||||
$class->logger->error(
|
||||
"_utime is not defined. This should not happen. Check if it is well transmitted to handler"
|
||||
"_utime is not defined. This should not happen. Check if it is well transmitted to handler"
|
||||
) unless $session->data->{_utime};
|
||||
|
||||
$class->logger->debug("Check session validity from Handler");
|
||||
$class->logger->debug(
|
||||
"Session timeout -> " . $class->tsv->{timeout} );
|
||||
$class->logger->debug( "Session timeout -> " . $class->tsv->{timeout} );
|
||||
$class->logger->debug( "Session timeoutActivity -> "
|
||||
. $class->tsv->{timeoutActivity}
|
||||
. "s" )
|
||||
if ( $class->tsv->{timeoutActivity} );
|
||||
. $class->tsv->{timeoutActivity}
|
||||
. "s" )
|
||||
if ( $class->tsv->{timeoutActivity} );
|
||||
$class->logger->debug(
|
||||
"Session _utime -> " . $session->data->{_utime} );
|
||||
$class->logger->debug( "now -> " . $now );
|
||||
$class->logger->debug( "_lastSeen -> " . $session->data->{_lastSeen} )
|
||||
if ( $session->data->{_lastSeen} );
|
||||
if ( $session->data->{_lastSeen} );
|
||||
my $delta = $now - $session->data->{_lastSeen}
|
||||
if ( $session->data->{_lastSeen} );
|
||||
if ( $session->data->{_lastSeen} );
|
||||
$class->logger->debug( "now - _lastSeen = " . $delta )
|
||||
if ( $session->data->{_lastSeen} );
|
||||
if ( $session->data->{_lastSeen} );
|
||||
$class->logger->debug( "Session timeoutActivityInterval -> "
|
||||
. $class->tsv->{timeoutActivityInterval} )
|
||||
if ( $class->tsv->{timeoutActivityInterval} );
|
||||
. $class->tsv->{timeoutActivityInterval} )
|
||||
if ( $class->tsv->{timeoutActivityInterval} );
|
||||
my $ttl = $class->tsv->{timeout} - $now + $session->data->{_utime};
|
||||
$class->logger->debug( "Session TTL = " . $ttl );
|
||||
|
||||
if ($now - $session->data->{_utime} > $class->tsv->{timeout}
|
||||
if (
|
||||
$now - $session->data->{_utime} > $class->tsv->{timeout}
|
||||
or ( $class->tsv->{timeoutActivity}
|
||||
and $session->data->{_lastSeen}
|
||||
and $delta > $class->tsv->{timeoutActivity} )
|
||||
)
|
||||
)
|
||||
{
|
||||
$class->logger->info("Session $id expired");
|
||||
|
||||
|
@ -503,10 +503,11 @@ sub retrieveSession {
|
|||
}
|
||||
|
||||
# Update the session to notify activity, if necessary
|
||||
if ($class->tsv->{timeoutActivity}
|
||||
and ( $now - $session->data->{_lastSeen}
|
||||
> $class->tsv->{timeoutActivityInterval} )
|
||||
)
|
||||
if (
|
||||
$class->tsv->{timeoutActivity}
|
||||
and ( $now - $session->data->{_lastSeen} >
|
||||
$class->tsv->{timeoutActivityInterval} )
|
||||
)
|
||||
{
|
||||
$req->data->{session}->update( { '_lastSeen' => $now } );
|
||||
$class->data( $session->data );
|
||||
|
@ -593,9 +594,9 @@ sub _buildUrl {
|
|||
my $_https = $class->_isHttps( $req, $vhost );
|
||||
my $portString = $class->_getPort( $req, $vhost );
|
||||
$portString = (
|
||||
( $realvhost =~ /:\d+/ )
|
||||
or ( $_https && $portString == 443 )
|
||||
or ( !$_https && $portString == 80 )
|
||||
( $realvhost =~ /:\d+/ )
|
||||
or ( $_https && $portString == 443 )
|
||||
or ( !$_https && $portString == 80 )
|
||||
) ? '' : ":$portString";
|
||||
my $url = "http" . ( $_https ? "s" : "" ) . "://$realvhost$portString$s";
|
||||
$class->logger->debug("Build URL $url");
|
||||
|
@ -611,10 +612,10 @@ sub isUnprotected {
|
|||
my ( $class, $req, $uri ) = @_;
|
||||
my $vhost = $class->resolveAlias($req);
|
||||
for (
|
||||
my $i = 0;
|
||||
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 );
|
||||
my $i = 0 ;
|
||||
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 ) ;
|
||||
$i++
|
||||
)
|
||||
)
|
||||
{
|
||||
if ( $uri =~ $class->tsv->{locationRegexp}->{$vhost}->[$i] ) {
|
||||
return $class->tsv->{locationProtection}->{$vhost}->[$i];
|
||||
|
@ -631,8 +632,8 @@ sub sendHeaders {
|
|||
if ( defined $class->tsv->{forgeHeaders}->{$vhost} ) {
|
||||
|
||||
# Log headers in debug mode
|
||||
my %headers
|
||||
= $class->tsv->{forgeHeaders}->{$vhost}->( $req, $session );
|
||||
my %headers =
|
||||
$class->tsv->{forgeHeaders}->{$vhost}->( $req, $session );
|
||||
foreach my $h ( sort keys %headers ) {
|
||||
if ( defined( my $v = $headers{$h} ) ) {
|
||||
$class->logger->debug("Send header $h with value $v");
|
||||
|
@ -655,12 +656,12 @@ sub checkHeaders {
|
|||
if ( defined $class->tsv->{forgeHeaders}->{$vhost} ) {
|
||||
|
||||
# Create array of hashes with headers
|
||||
my %headers
|
||||
= $class->tsv->{forgeHeaders}->{$vhost}->( $req, $session );
|
||||
my %headers =
|
||||
$class->tsv->{forgeHeaders}->{$vhost}->( $req, $session );
|
||||
foreach my $h ( sort keys %headers ) {
|
||||
defined $headers{$h}
|
||||
? push @$array_headers, { key => $h, value => $headers{$h} }
|
||||
: push @$array_headers, { key => $h, value => '' };
|
||||
? push @$array_headers, { key => $h, value => $headers{$h} }
|
||||
: push @$array_headers, { key => $h, value => '' };
|
||||
}
|
||||
}
|
||||
return $array_headers;
|
||||
|
@ -685,7 +686,7 @@ sub resolveAlias {
|
|||
|
||||
$vhost =~ s/:\d+//;
|
||||
return $class->tsv->{vhostAlias}->{$vhost}
|
||||
if ( $class->tsv->{vhostAlias}->{$vhost} );
|
||||
if ( $class->tsv->{vhostAlias}->{$vhost} );
|
||||
return $vhost if ( $class->tsv->{defaultCondition}->{$vhost} );
|
||||
my $v = $vhost;
|
||||
while ( $v =~ s/[\w\-]+/\*/ ) {
|
||||
|
@ -758,8 +759,8 @@ sub postOutputFilter {
|
|||
$class->logger->debug("Filling a html form with fake data");
|
||||
|
||||
$class->unset_header_in( $req, "Accept-Encoding" );
|
||||
my %postdata = $class->tsv->{outputPostData}->{$vhost}->{$uri}
|
||||
->( $req, $session );
|
||||
my %postdata =
|
||||
$class->tsv->{outputPostData}->{$vhost}->{$uri}->( $req, $session );
|
||||
my $formParams = $class->tsv->{postFormParams}->{$vhost}->{$uri};
|
||||
my $js = $class->postJavascript( $req, \%postdata, $formParams );
|
||||
$class->addToHtmlHead( $req, $js );
|
||||
|
@ -776,8 +777,8 @@ sub postInputFilter {
|
|||
if ( defined( $class->tsv->{inputPostData}->{$vhost}->{$uri} ) ) {
|
||||
$class->logger->debug("Replacing fake data with real form data");
|
||||
|
||||
my %data = $class->tsv->{inputPostData}->{$vhost}->{$uri}
|
||||
->( $req, $session );
|
||||
my %data =
|
||||
$class->tsv->{inputPostData}->{$vhost}->{$uri}->( $req, $session );
|
||||
foreach ( keys %data ) {
|
||||
$data{$_} = uri_escape( $data{$_} );
|
||||
}
|
||||
|
@ -797,33 +798,32 @@ sub postJavascript {
|
|||
foreach my $name ( keys %$data ) {
|
||||
use bytes;
|
||||
my $value = "x" x bytes::length( $data->{$name} );
|
||||
$filler
|
||||
.= "form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n";
|
||||
$filler .=
|
||||
"form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n";
|
||||
}
|
||||
|
||||
my $submitter
|
||||
= $formParams->{buttonSelector} eq "none" ? ""
|
||||
: $formParams->{buttonSelector}
|
||||
? "form.find('$formParams->{buttonSelector}').click();\n"
|
||||
: "form.submit();\n";
|
||||
my $submitter =
|
||||
$formParams->{buttonSelector} eq "none" ? ""
|
||||
: $formParams->{buttonSelector}
|
||||
? "form.find('$formParams->{buttonSelector}').click();\n"
|
||||
: "form.submit();\n";
|
||||
|
||||
my $jqueryUrl = $formParams->{jqueryUrl} || "";
|
||||
$jqueryUrl
|
||||
= &{ $class->tsv->{portal} } . "skins/common/js/jquery-1.10.2.js"
|
||||
if ( $jqueryUrl eq "default" );
|
||||
$jqueryUrl = &{ $class->tsv->{portal} } . "skins/common/js/jquery-1.10.2.js"
|
||||
if ( $jqueryUrl eq "default" );
|
||||
$jqueryUrl = "<script type='text/javascript' src='$jqueryUrl'></script>\n"
|
||||
if ($jqueryUrl);
|
||||
if ($jqueryUrl);
|
||||
|
||||
return
|
||||
$jqueryUrl
|
||||
. "<script type='text/javascript'>\n"
|
||||
. "/* script added by Lemonldap::NG */\n"
|
||||
. "jQuery(window).on('load', function() {\n"
|
||||
. "var form = jQuery('$form');\n"
|
||||
. "form.attr('autocomplete', 'off');\n"
|
||||
. $filler
|
||||
. $submitter . "})\n"
|
||||
. "</script>\n";
|
||||
$jqueryUrl
|
||||
. "<script type='text/javascript'>\n"
|
||||
. "/* script added by Lemonldap::NG */\n"
|
||||
. "jQuery(window).on('load', function() {\n"
|
||||
. "var form = jQuery('$form');\n"
|
||||
. "form.attr('autocomplete', 'off');\n"
|
||||
. $filler
|
||||
. $submitter . "})\n"
|
||||
. "</script>\n";
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -51,7 +51,6 @@ sub defaultUnauthRoute {
|
|||
|
||||
sub _run {
|
||||
my $self = shift;
|
||||
$self->rule(1);
|
||||
|
||||
return sub {
|
||||
my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] );
|
||||
|
@ -61,6 +60,7 @@ sub _run {
|
|||
$req->userData( $self->api->data );
|
||||
}
|
||||
elsif ( $res->[0] != 403 ) {
|
||||
|
||||
# Unset headers (handler adds a Location header)
|
||||
$self->logger->debug(
|
||||
"User not authenticated, Try in use, cancel redirection");
|
||||
|
|
|
@ -1195,6 +1195,26 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||
'default' => -1,
|
||||
'type' => 'trool'
|
||||
},
|
||||
'impersonationHiddenAttributes' => {
|
||||
'default' => '_2fDevices _loginHistory',
|
||||
'type' => 'text'
|
||||
},
|
||||
'impersonationMergeSSOgroups' => {
|
||||
'default' => 0,
|
||||
'type' => 'bool'
|
||||
},
|
||||
'impersonationPrefix' => {
|
||||
'default' => 'real_',
|
||||
'type' => 'text'
|
||||
},
|
||||
'impersonationRule' => {
|
||||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'impersonationSkipEmptyValues' => {
|
||||
'default' => 1,
|
||||
'type' => 'bool'
|
||||
},
|
||||
'infoFormMethod' => {
|
||||
'default' => 'get',
|
||||
'select' => [ {
|
||||
|
|
|
@ -416,6 +416,59 @@ sub attributes {
|
|||
type => 'text',
|
||||
documentation => 'Secret token for CheckState plugin',
|
||||
},
|
||||
checkUser => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Enable check user',
|
||||
flags => 'p',
|
||||
},
|
||||
checkUserHiddenAttributes => {
|
||||
type => 'text',
|
||||
default => '_2fDevices _loginHistory hGroups',
|
||||
documentation => 'Attributes to hide in CheckUser plugin',
|
||||
flags => 'p',
|
||||
},
|
||||
checkUserDisplayPersistentInfo => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Display persistent session info',
|
||||
flags => 'p',
|
||||
},
|
||||
checkUserDisplayEmptyValues => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Display session empty values',
|
||||
flags => 'p',
|
||||
},
|
||||
impersonationMergeSSOgroups => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Merge spoofed and real SSO groups',
|
||||
flags => 'p',
|
||||
},
|
||||
impersonationPrefix => {
|
||||
type => 'text',
|
||||
default => 'real_',
|
||||
documentation => 'Prefix to rename real session attributes',
|
||||
flags => 'p',
|
||||
},
|
||||
impersonationRule => {
|
||||
type => 'boolOrExpr',
|
||||
default => 0,
|
||||
documentation => 'Impersonation activation rule',
|
||||
},
|
||||
impersonationHiddenAttributes => {
|
||||
type => 'text',
|
||||
default => '_2fDevices _loginHistory',
|
||||
documentation => 'Attributes to skip',
|
||||
flags => 'p',
|
||||
},
|
||||
impersonationSkipEmptyValues => {
|
||||
default => 1,
|
||||
type => 'bool',
|
||||
documentation => 'Skip session empty values',
|
||||
flags => 'p',
|
||||
},
|
||||
skipRenewConfirmation => {
|
||||
type => 'bool',
|
||||
default => 0,
|
||||
|
@ -578,30 +631,6 @@ sub attributes {
|
|||
documentation => 'Enable Cross Domain Authentication',
|
||||
flags => 'hp',
|
||||
},
|
||||
checkUser => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Enable check user',
|
||||
flags => 'p',
|
||||
},
|
||||
checkUserHiddenAttributes => {
|
||||
type => 'text',
|
||||
default => '_2fDevices _loginHistory hGroups',
|
||||
documentation => 'Attributes to hide in CheckUser plugin',
|
||||
flags => 'p',
|
||||
},
|
||||
checkUserDisplayPersistentInfo => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Display persistent session info',
|
||||
flags => 'p',
|
||||
},
|
||||
checkUserDisplayEmptyValues => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Display session empty values',
|
||||
flags => 'p',
|
||||
},
|
||||
checkXSS => {
|
||||
default => 1,
|
||||
type => 'bool',
|
||||
|
|
|
@ -22,7 +22,8 @@ sub cTrees {
|
|||
'locationRules',
|
||||
'exportedHeaders',
|
||||
'post',
|
||||
{ title => 'vhostOptions',
|
||||
{
|
||||
title => 'vhostOptions',
|
||||
help => 'configvhost.html#options',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
|
@ -36,7 +37,8 @@ sub cTrees {
|
|||
'samlIDPMetaDataXML',
|
||||
'samlIDPMetaDataExportedAttributes',
|
||||
|
||||
{ title => "samlIDPMetaDataOptionsSession",
|
||||
{
|
||||
title => "samlIDPMetaDataOptionsSession",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlIDPMetaDataOptionsAdaptSessionUtime",
|
||||
|
@ -45,7 +47,8 @@ sub cTrees {
|
|||
"samlIDPMetaDataOptionsUserAttribute"
|
||||
]
|
||||
},
|
||||
{ title => "samlIDPMetaDataOptionsSignature",
|
||||
{
|
||||
title => "samlIDPMetaDataOptionsSignature",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlIDPMetaDataOptionsSignSSOMessage",
|
||||
|
@ -54,14 +57,16 @@ sub cTrees {
|
|||
"samlIDPMetaDataOptionsCheckSLOMessageSignature"
|
||||
]
|
||||
},
|
||||
{ title => "samlIDPMetaDataOptionsBinding",
|
||||
{
|
||||
title => "samlIDPMetaDataOptionsBinding",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlIDPMetaDataOptionsSSOBinding",
|
||||
"samlIDPMetaDataOptionsSLOBinding"
|
||||
]
|
||||
},
|
||||
{ title => "samlIDPMetaDataOptionsSecurity",
|
||||
{
|
||||
title => "samlIDPMetaDataOptionsSecurity",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlIDPMetaDataOptionsEncryptionMode",
|
||||
|
@ -69,7 +74,8 @@ sub cTrees {
|
|||
"samlIDPMetaDataOptionsCheckAudience"
|
||||
]
|
||||
},
|
||||
{ title => 'samlIDPMetaDataOptions',
|
||||
{
|
||||
title => 'samlIDPMetaDataOptions',
|
||||
help => 'authsaml.html#options',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
|
@ -83,7 +89,8 @@ sub cTrees {
|
|||
'samlIDPMetaDataOptionsRelayStateURL',
|
||||
],
|
||||
},
|
||||
{ title => "samlIDPMetaDataOptionsDisplay",
|
||||
{
|
||||
title => "samlIDPMetaDataOptionsDisplay",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlIDPMetaDataOptionsDisplayName",
|
||||
|
@ -94,10 +101,11 @@ sub cTrees {
|
|||
samlSPMetaDataNode => [
|
||||
"samlSPMetaDataXML",
|
||||
"samlSPMetaDataExportedAttributes",
|
||||
{ title => "samlSPMetaDataOptions",
|
||||
{
|
||||
title => "samlSPMetaDataOptions",
|
||||
help => 'idpsaml.html#options',
|
||||
nodes => [
|
||||
{ title => "samlSPMetaDataOptionsAuthnResponse",
|
||||
nodes => [ {
|
||||
title => "samlSPMetaDataOptionsAuthnResponse",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlSPMetaDataOptionsNameIDFormat",
|
||||
|
@ -108,7 +116,8 @@ sub cTrees {
|
|||
"samlSPMetaDataOptionsForceUTF8"
|
||||
]
|
||||
},
|
||||
{ title => "samlSPMetaDataOptionsSignature",
|
||||
{
|
||||
title => "samlSPMetaDataOptionsSignature",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlSPMetaDataOptionsSignSSOMessage",
|
||||
|
@ -117,7 +126,8 @@ sub cTrees {
|
|||
"samlSPMetaDataOptionsCheckSLOMessageSignature"
|
||||
]
|
||||
},
|
||||
{ title => "samlSPMetaDataOptionsSecurity",
|
||||
{
|
||||
title => "samlSPMetaDataOptionsSecurity",
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
"samlSPMetaDataOptionsEncryptionMode",
|
||||
|
@ -132,9 +142,10 @@ sub cTrees {
|
|||
'oidcOPMetaDataJSON',
|
||||
'oidcOPMetaDataJWKS',
|
||||
'oidcOPMetaDataExportedVars',
|
||||
{ title => 'oidcOPMetaDataOptions',
|
||||
nodes => [
|
||||
{ title => 'oidcOPMetaDataOptionsConfiguration',
|
||||
{
|
||||
title => 'oidcOPMetaDataOptions',
|
||||
nodes => [ {
|
||||
title => 'oidcOPMetaDataOptionsConfiguration',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'oidcOPMetaDataOptionsConfigurationURI',
|
||||
|
@ -144,7 +155,8 @@ sub cTrees {
|
|||
'oidcOPMetaDataOptionsStoreIDToken'
|
||||
]
|
||||
},
|
||||
{ title => 'oidcOPMetaDataOptionsProtocol',
|
||||
{
|
||||
title => 'oidcOPMetaDataOptionsProtocol',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'oidcOPMetaDataOptionsScope',
|
||||
|
@ -161,7 +173,8 @@ sub cTrees {
|
|||
},
|
||||
]
|
||||
},
|
||||
{ title => 'oidcOPMetaDataOptionsDisplayParams',
|
||||
{
|
||||
title => 'oidcOPMetaDataOptionsDisplayParams',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'oidcOPMetaDataOptionsDisplayName',
|
||||
|
@ -172,9 +185,10 @@ sub cTrees {
|
|||
oidcRPMetaDataNode => [
|
||||
'oidcRPMetaDataExportedVars',
|
||||
'oidcRPMetaDataOptionsExtraClaims',
|
||||
{ title => 'oidcRPMetaDataOptions',
|
||||
nodes => [
|
||||
{ title => 'oidcRPMetaDataOptionsAuthentication',
|
||||
{
|
||||
title => 'oidcRPMetaDataOptions',
|
||||
nodes => [ {
|
||||
title => 'oidcRPMetaDataOptionsAuthentication',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'oidcRPMetaDataOptionsClientID',
|
||||
|
@ -187,7 +201,8 @@ sub cTrees {
|
|||
'oidcRPMetaDataOptionsAccessTokenExpiration',
|
||||
'oidcRPMetaDataOptionsRedirectUris',
|
||||
'oidcRPMetaDataOptionsBypassConsent',
|
||||
{ title => 'logout',
|
||||
{
|
||||
title => 'logout',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'oidcRPMetaDataOptionsPostLogoutRedirectUris',
|
||||
|
@ -199,7 +214,8 @@ sub cTrees {
|
|||
'oidcRPMetaDataOptionsRule',
|
||||
]
|
||||
},
|
||||
{ title => 'oidcRPMetaDataOptionsDisplay',
|
||||
{
|
||||
title => 'oidcRPMetaDataOptionsDisplay',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'oidcRPMetaDataOptionsDisplayName',
|
||||
|
@ -210,7 +226,8 @@ sub cTrees {
|
|||
casSrvMetaDataNode => [
|
||||
'casSrvMetaDataExportedVars',
|
||||
'casSrvMetaDataOptionsProxiedServices',
|
||||
{ title => 'casSrvMetaDataOptions',
|
||||
{
|
||||
title => 'casSrvMetaDataOptions',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'casSrvMetaDataOptionsUrl',
|
||||
|
@ -218,7 +235,8 @@ sub cTrees {
|
|||
'casSrvMetaDataOptionsGateway',
|
||||
]
|
||||
},
|
||||
{ title => 'casSrvMetaDataOptionsDisplay',
|
||||
{
|
||||
title => 'casSrvMetaDataOptionsDisplay',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'casSrvMetaDataOptionsDisplayName',
|
||||
|
@ -226,8 +244,8 @@ sub cTrees {
|
|||
]
|
||||
},
|
||||
],
|
||||
casAppMetaDataNode => [
|
||||
{ title => 'casAppMetaDataOptions',
|
||||
casAppMetaDataNode => [ {
|
||||
title => 'casAppMetaDataOptions',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'casAppMetaDataOptionsService',
|
||||
|
|
|
@ -498,8 +498,7 @@ sub tree {
|
|||
title => 'logParams',
|
||||
help => 'logs.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes =>
|
||||
[ 'whatToTrace', 'hiddenAttributes' ]
|
||||
nodes => [ 'whatToTrace', 'hiddenAttributes' ]
|
||||
},
|
||||
{
|
||||
title => 'cookieParams',
|
||||
|
@ -648,6 +647,18 @@ sub tree {
|
|||
'checkUserDisplayEmptyValues',
|
||||
]
|
||||
},
|
||||
{
|
||||
title => 'impersonation',
|
||||
help => 'impersonation.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'impersonationRule',
|
||||
'impersonationPrefix',
|
||||
'impersonationHiddenAttributes',
|
||||
'impersonationSkipEmptyValues',
|
||||
'impersonationMergeSSOgroups',
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -31,7 +31,8 @@ sub tests {
|
|||
portalIsInDomain => sub {
|
||||
return (
|
||||
1,
|
||||
( index( $conf->{portal}, $conf->{domain} ) > 0
|
||||
(
|
||||
index( $conf->{portal}, $conf->{domain} ) > 0
|
||||
? ''
|
||||
: "Portal seems not to be in the domain $conf->{domain}"
|
||||
)
|
||||
|
@ -43,7 +44,7 @@ sub tests {
|
|||
|
||||
# Checking for ending slash
|
||||
$conf->{portal} .= '/'
|
||||
unless ( $conf->{portal} =~ qr#/$# );
|
||||
unless ( $conf->{portal} =~ qr#/$# );
|
||||
|
||||
# Deleting trailing ending slash
|
||||
my $regex = qr#/+$#;
|
||||
|
@ -61,10 +62,11 @@ sub tests {
|
|||
}
|
||||
return (
|
||||
1,
|
||||
( @pb
|
||||
(
|
||||
@pb
|
||||
? 'Virtual hosts '
|
||||
. join( ', ', @pb )
|
||||
. " are not in $conf->{domain} and cross-domain-authentication is not set"
|
||||
. join( ', ', @pb )
|
||||
. " are not in $conf->{domain} and cross-domain-authentication is not set"
|
||||
: undef
|
||||
)
|
||||
);
|
||||
|
@ -78,9 +80,9 @@ sub tests {
|
|||
}
|
||||
if (@pb) {
|
||||
return ( 0,
|
||||
'Virtual hosts '
|
||||
. join( ', ', @pb )
|
||||
. " contain a port, this is not allowed" );
|
||||
'Virtual hosts '
|
||||
. join( ', ', @pb )
|
||||
. " contain a port, this is not allowed" );
|
||||
}
|
||||
else { return 1; }
|
||||
},
|
||||
|
@ -93,9 +95,9 @@ sub tests {
|
|||
}
|
||||
if (@pb) {
|
||||
return ( 0,
|
||||
'Virtual hosts '
|
||||
. join( ', ', @pb )
|
||||
. " must be in lower case" );
|
||||
'Virtual hosts '
|
||||
. join( ', ', @pb )
|
||||
. " must be in lower case" );
|
||||
}
|
||||
else { return 1; }
|
||||
},
|
||||
|
@ -103,12 +105,12 @@ sub tests {
|
|||
# Check if "userDB" and "authentication" are consistent
|
||||
authAndUserDBConsistency => sub {
|
||||
foreach
|
||||
my $type (qw(Facebook Google OpenID OpenIDConnect SAML WebID))
|
||||
my $type (qw(Facebook Google OpenID OpenIDConnect SAML WebID))
|
||||
{
|
||||
return ( 0,
|
||||
"\"$type\" can not be used as user database without using \"$type\" for authentication"
|
||||
)
|
||||
if ($conf->{userDB} =~ /$type/
|
||||
"\"$type\" can not be used as user database without using \"$type\" for authentication"
|
||||
)
|
||||
if ( $conf->{userDB} =~ /$type/
|
||||
and $conf->{authentication} !~ /$type/ );
|
||||
}
|
||||
return 1;
|
||||
|
@ -118,29 +120,30 @@ sub tests {
|
|||
checkAttrAndMacros => sub {
|
||||
my @tmp;
|
||||
foreach my $k ( keys %$conf ) {
|
||||
if ( $k
|
||||
=~ /^(?:openIdSreg_(?:(?:(?:full|nick)nam|languag|postcod|timezon)e|country|gender|email|dob)|whatToTrace)$/
|
||||
)
|
||||
if ( $k =~
|
||||
/^(?:openIdSreg_(?:(?:(?:full|nick)nam|languag|postcod|timezon)e|country|gender|email|dob)|whatToTrace)$/
|
||||
)
|
||||
{
|
||||
my $v = $conf->{$k};
|
||||
$v =~ s/^$//;
|
||||
next if ( $v =~ /^_/ );
|
||||
push @tmp,
|
||||
$k
|
||||
unless (
|
||||
$k
|
||||
unless (
|
||||
defined(
|
||||
$conf->{exportedVars}->{$v}
|
||||
or defined( $conf->{macros}->{$v} )
|
||||
or defined( $conf->{macros}->{$v} )
|
||||
)
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
1,
|
||||
( @tmp
|
||||
(
|
||||
@tmp
|
||||
? 'Values of parameter(s) "'
|
||||
. join( ', ', @tmp )
|
||||
. '" are not defined in exported attributes or macros'
|
||||
. join( ', ', @tmp )
|
||||
. '" are not defined in exported attributes or macros'
|
||||
: ''
|
||||
)
|
||||
);
|
||||
|
@ -152,18 +155,18 @@ sub tests {
|
|||
if ( $conf->{userDB} =~ /^Google$/ ) {
|
||||
foreach my $k ( keys %{ $conf->{exportedVars} } ) {
|
||||
my $v = $conf->{exportedVars}->{$k};
|
||||
if ( $v !~ Lemonldap::NG::Common::Regexp::GOOGLEAXATTR() )
|
||||
{
|
||||
if ( $v !~ Lemonldap::NG::Common::Regexp::GOOGLEAXATTR() ) {
|
||||
push @tmp, $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
1,
|
||||
( @tmp
|
||||
(
|
||||
@tmp
|
||||
? 'Values of parameter(s) "'
|
||||
. join( ', ', @tmp )
|
||||
. '" are not exported by Google'
|
||||
. join( ', ', @tmp )
|
||||
. '" are not exported by Google'
|
||||
: ''
|
||||
)
|
||||
);
|
||||
|
@ -175,8 +178,7 @@ sub tests {
|
|||
if ( $conf->{userDB} =~ /^OpenID$/ ) {
|
||||
foreach my $k ( keys %{ $conf->{exportedVars} } ) {
|
||||
my $v = $conf->{exportedVars}->{$k};
|
||||
if ( $v
|
||||
!~ Lemonldap::NG::Common::Regexp::OPENIDSREGATTR() )
|
||||
if ( $v !~ Lemonldap::NG::Common::Regexp::OPENIDSREGATTR() )
|
||||
{
|
||||
push @tmp, $v;
|
||||
}
|
||||
|
@ -184,10 +186,11 @@ sub tests {
|
|||
}
|
||||
return (
|
||||
1,
|
||||
( @tmp
|
||||
(
|
||||
@tmp
|
||||
? 'Values of parameter(s) "'
|
||||
. join( ', ', @tmp )
|
||||
. '" are not exported by OpenID SREG'
|
||||
. join( ', ', @tmp )
|
||||
. '" are not exported by OpenID SREG'
|
||||
: ''
|
||||
)
|
||||
);
|
||||
|
@ -196,40 +199,39 @@ sub tests {
|
|||
# Try to use Apache::Session module
|
||||
testApacheSession => sub {
|
||||
my ( $id, %h );
|
||||
my $gc
|
||||
= Lemonldap::NG::Handler::Main->tsv->{sessionStorageModule};
|
||||
my $gc = Lemonldap::NG::Handler::Main->tsv->{sessionStorageModule};
|
||||
return 1
|
||||
if ( ( $gc and $gc eq $conf->{globalStorage} )
|
||||
or $conf->{globalStorage}
|
||||
=~ /^Lemonldap::NG::Common::Apache::Session::/ );
|
||||
if ( ( $gc and $gc eq $conf->{globalStorage} )
|
||||
or $conf->{globalStorage} =~
|
||||
/^Lemonldap::NG::Common::Apache::Session::/ );
|
||||
eval "use $conf->{globalStorage}";
|
||||
return ( -1, "Unknown package $conf->{globalStorage}" ) if ($@);
|
||||
eval {
|
||||
tie %h, 'Lemonldap::NG::Common::Apache::Session', undef,
|
||||
{
|
||||
{
|
||||
%{ $conf->{globalStorageOptions} },
|
||||
backend => $conf->{globalStorage}
|
||||
};
|
||||
};
|
||||
};
|
||||
return ( -1, "Unable to create a session ($@)" )
|
||||
if ( $@ or not tied(%h) );
|
||||
if ( $@ or not tied(%h) );
|
||||
eval {
|
||||
$h{a} = 1;
|
||||
$id = $h{_session_id} or return ( -1, 'No _session_id' );
|
||||
untie(%h);
|
||||
tie %h, 'Lemonldap::NG::Common::Apache::Session', $id,
|
||||
{
|
||||
{
|
||||
%{ $conf->{globalStorageOptions} },
|
||||
backend => $conf->{globalStorage}
|
||||
};
|
||||
};
|
||||
};
|
||||
return ( -1, "Unable to insert data ($@)" ) if ($@);
|
||||
return ( -1, "Unable to recover data stored" )
|
||||
unless ( $h{a} == 1 );
|
||||
unless ( $h{a} == 1 );
|
||||
eval { tied(%h)->delete; };
|
||||
return ( -1, "Unable to delete session ($@)" ) if ($@);
|
||||
return ( -1,
|
||||
'All sessions may be lost and you must restart all your Apache servers'
|
||||
'All sessions may be lost and you must restart all your Apache servers'
|
||||
) if ( $gc and $conf->{globalStorage} ne $gc );
|
||||
return 1;
|
||||
},
|
||||
|
@ -239,8 +241,9 @@ sub tests {
|
|||
my $cn = Lemonldap::NG::Handler::Main->tsv->{cookieName};
|
||||
return (
|
||||
1,
|
||||
( $cn
|
||||
and $cn ne $conf->{cookieName}
|
||||
(
|
||||
$cn
|
||||
and $cn ne $conf->{cookieName}
|
||||
? 'Cookie name has changed, you must restart all your web servers'
|
||||
: ()
|
||||
)
|
||||
|
@ -251,10 +254,10 @@ sub tests {
|
|||
cookieTTL => sub {
|
||||
return 1 unless ( defined $conf->{cookieExpiration} );
|
||||
return ( 0, "Cookie TTL must be higher than one minute" )
|
||||
unless ( $conf->{cookieExpiration} == 0
|
||||
unless ( $conf->{cookieExpiration} == 0
|
||||
|| $conf->{cookieExpiration} > 60 );
|
||||
return ( 1, "Cookie TTL should be higher or equal than one hour" )
|
||||
unless ( $conf->{cookieExpiration} >= 3600
|
||||
unless ( $conf->{cookieExpiration} >= 3600
|
||||
|| $conf->{cookieExpiration} == 0 );
|
||||
|
||||
# Return
|
||||
|
@ -265,7 +268,7 @@ sub tests {
|
|||
sessionTimeout => sub {
|
||||
return 1 unless ( defined $conf->{timeout} );
|
||||
return ( -1, "Session timeout should be higher than ten minutes" )
|
||||
unless ( $conf->{timeout} > 600
|
||||
unless ( $conf->{timeout} > 600
|
||||
|| $conf->{timeout} == 0 );
|
||||
|
||||
# Return
|
||||
|
@ -276,9 +279,9 @@ sub tests {
|
|||
sessionTimeoutActivity => sub {
|
||||
return 1 unless ( defined $conf->{timeoutActivity} );
|
||||
return ( 0,
|
||||
"Session activity timeout must be higher or equal than one minute"
|
||||
)
|
||||
unless ( $conf->{timeoutActivity} > 59
|
||||
"Session activity timeout must be higher or equal than one minute"
|
||||
)
|
||||
unless ( $conf->{timeoutActivity} > 59
|
||||
|| $conf->{timeoutActivity} == 0 );
|
||||
|
||||
# Return
|
||||
|
@ -289,11 +292,11 @@ sub tests {
|
|||
timeoutActivityInterval => sub {
|
||||
return 1 unless ( defined $conf->{timeoutActivityInterval} );
|
||||
return ( 0,
|
||||
"Activity timeout interval must be lower than session activity timeout"
|
||||
)
|
||||
if ($conf->{timeoutActivity}
|
||||
and $conf->{timeoutActivity}
|
||||
<= $conf->{timeoutActivityInterval} );
|
||||
"Activity timeout interval must be lower than session activity timeout"
|
||||
)
|
||||
if ( $conf->{timeoutActivity}
|
||||
and $conf->{timeoutActivity} <=
|
||||
$conf->{timeoutActivityInterval} );
|
||||
|
||||
# Return
|
||||
return 1;
|
||||
|
@ -303,7 +306,8 @@ sub tests {
|
|||
managerProtection => sub {
|
||||
return (
|
||||
1,
|
||||
( $conf->{cfgAuthor} eq 'anonymous'
|
||||
(
|
||||
$conf->{cfgAuthor} eq 'anonymous'
|
||||
? 'Your manager seems to be unprotected'
|
||||
: ''
|
||||
)
|
||||
|
@ -319,7 +323,7 @@ sub tests {
|
|||
# Use SMTP
|
||||
eval "use Net::SMTP";
|
||||
return ( 1, "Net::SMTP module is required to use SMTP server" )
|
||||
if ($@);
|
||||
if ($@);
|
||||
|
||||
# Create SMTP object
|
||||
my $smtp = Net::SMTP->new(
|
||||
|
@ -329,15 +333,15 @@ sub tests {
|
|||
);
|
||||
return ( 1,
|
||||
"SMTP connection to " . $conf->{SMTPServer} . " failed" )
|
||||
unless ($smtp);
|
||||
unless ($smtp);
|
||||
|
||||
# Skip other tests if no authentication
|
||||
return 1
|
||||
unless ( $conf->{SMTPAuthUser} and $conf->{SMTPAuthPass} );
|
||||
unless ( $conf->{SMTPAuthUser} and $conf->{SMTPAuthPass} );
|
||||
|
||||
# Try authentication
|
||||
return ( 1, "SMTP authentication failed" )
|
||||
unless $smtp->auth( $conf->{SMTPAuthUser},
|
||||
unless $smtp->auth( $conf->{SMTPAuthUser},
|
||||
$conf->{SMTPAuthPass} );
|
||||
|
||||
# Return
|
||||
|
@ -347,14 +351,15 @@ sub tests {
|
|||
# SAML entity ID must be uniq
|
||||
samlIDPEntityIdUniqueness => sub {
|
||||
return 1
|
||||
unless ( $conf->{samlIDPMetaDataXML}
|
||||
unless ( $conf->{samlIDPMetaDataXML}
|
||||
and %{ $conf->{samlIDPMetaDataXML} } );
|
||||
my @msg;
|
||||
my $res = 1;
|
||||
my %entityIds;
|
||||
foreach my $idpId ( keys %{ $conf->{samlIDPMetaDataXML} } ) {
|
||||
unless ( $conf->{samlIDPMetaDataXML}->{$idpId}
|
||||
->{samlIDPMetaDataXML} =~ /entityID=(['"])(.+?)\1/si )
|
||||
unless (
|
||||
$conf->{samlIDPMetaDataXML}->{$idpId}->{samlIDPMetaDataXML}
|
||||
=~ /entityID=(['"])(.+?)\1/si )
|
||||
{
|
||||
push @msg, "$idpId SAML metadata has no EntityID";
|
||||
$res = 0;
|
||||
|
@ -363,7 +368,7 @@ sub tests {
|
|||
my $eid = $2;
|
||||
if ( defined $entityIds{$eid} ) {
|
||||
push @msg,
|
||||
"$idpId and $entityIds{$eid} have the same SAML EntityID";
|
||||
"$idpId and $entityIds{$eid} have the same SAML EntityID";
|
||||
$res = 0;
|
||||
next;
|
||||
}
|
||||
|
@ -373,15 +378,15 @@ sub tests {
|
|||
},
|
||||
samlSPEntityIdUniqueness => sub {
|
||||
return 1
|
||||
unless ( $conf->{samlSPMetaDataXML}
|
||||
unless ( $conf->{samlSPMetaDataXML}
|
||||
and %{ $conf->{samlSPMetaDataXML} } );
|
||||
my @msg;
|
||||
my $res = 1;
|
||||
my %entityIds;
|
||||
foreach my $spId ( keys %{ $conf->{samlSPMetaDataXML} } ) {
|
||||
unless (
|
||||
$conf->{samlSPMetaDataXML}->{$spId}->{samlSPMetaDataXML}
|
||||
=~ /entityID=(['"])(.+?)\1/si )
|
||||
$conf->{samlSPMetaDataXML}->{$spId}->{samlSPMetaDataXML} =~
|
||||
/entityID=(['"])(.+?)\1/si )
|
||||
{
|
||||
push @msg, "$spId SAML metadata has no EntityID";
|
||||
$res = 0;
|
||||
|
@ -390,7 +395,7 @@ sub tests {
|
|||
my $eid = $2;
|
||||
if ( defined $entityIds{$eid} ) {
|
||||
push @msg,
|
||||
"$spId and $entityIds{$eid} have the same SAML EntityID";
|
||||
"$spId and $entityIds{$eid} have the same SAML EntityID";
|
||||
$res = 0;
|
||||
next;
|
||||
}
|
||||
|
@ -404,7 +409,7 @@ sub tests {
|
|||
return 1 unless ( $conf->{authentication} eq 'Combination' );
|
||||
require Lemonldap::NG::Common::Combination::Parser;
|
||||
return ( 0, 'No module declared for combination' )
|
||||
unless ( $conf->{combModules} and %{ $conf->{combModules} } );
|
||||
unless ( $conf->{combModules} and %{ $conf->{combModules} } );
|
||||
my $moduleList;
|
||||
foreach my $md ( keys %{ $conf->{combModules} } ) {
|
||||
my $entry = $conf->{combModules}->{$md};
|
||||
|
@ -415,8 +420,8 @@ sub tests {
|
|||
);
|
||||
}
|
||||
eval {
|
||||
Lemonldap::NG::Common::Combination::Parser->parse(
|
||||
$moduleList, $conf->{combination} );
|
||||
Lemonldap::NG::Common::Combination::Parser->parse( $moduleList,
|
||||
$conf->{combination} );
|
||||
};
|
||||
return ( 0, $@ ) if ($@);
|
||||
|
||||
|
@ -428,9 +433,9 @@ sub tests {
|
|||
combinationParameters => sub {
|
||||
return 1 unless ( $conf->{authentication} eq "Combination" );
|
||||
return ( 0, "Combination rule must be defined" )
|
||||
unless ( $conf->{combination} );
|
||||
unless ( $conf->{combination} );
|
||||
return ( 0, 'userDB must be set to "Same" to enable Combination' )
|
||||
unless ( $conf->{userDB} eq "Same" );
|
||||
unless ( $conf->{userDB} eq "Same" );
|
||||
|
||||
# Return
|
||||
return 1;
|
||||
|
@ -453,7 +458,7 @@ sub tests {
|
|||
eval "use Convert::Base32";
|
||||
return ( 1,
|
||||
"Convert::Base32 module is required to enable TOTP" )
|
||||
if ($@);
|
||||
if ($@);
|
||||
}
|
||||
|
||||
# Use U2F
|
||||
|
@ -462,7 +467,7 @@ sub tests {
|
|||
{
|
||||
eval "use Crypt::U2F::Server::Simple";
|
||||
return ( 1,
|
||||
"Crypt::U2F::Server::Simple module is required to enable U2F"
|
||||
"Crypt::U2F::Server::Simple module is required to enable U2F"
|
||||
) if ($@);
|
||||
}
|
||||
|
||||
|
@ -470,7 +475,7 @@ sub tests {
|
|||
if ( $conf->{yubikey2fActivation} ) {
|
||||
eval "use Auth::Yubikey_WebClient";
|
||||
return ( 1,
|
||||
"Auth::Yubikey_WebClient module is required to enable Yubikey"
|
||||
"Auth::Yubikey_WebClient module is required to enable Yubikey"
|
||||
) if ($@);
|
||||
}
|
||||
|
||||
|
@ -484,7 +489,7 @@ sub tests {
|
|||
my $w = "";
|
||||
foreach ( 'totp', 'u' ) {
|
||||
$w .= uc($_) . "2F is activated twice \n"
|
||||
if ( $conf->{ $_ . '2fActivation' } eq '1' );
|
||||
if ( $conf->{ $_ . '2fActivation' } eq '1' );
|
||||
}
|
||||
return ( 1, ( $w ? $w : () ) );
|
||||
},
|
||||
|
@ -495,9 +500,9 @@ sub tests {
|
|||
return 1 unless ( defined $conf->{totp2fDigits} );
|
||||
return (
|
||||
1,
|
||||
(
|
||||
( $conf->{totp2fDigits} == 6
|
||||
or $conf->{totp2fDigits} == 8
|
||||
( (
|
||||
$conf->{totp2fDigits} == 6
|
||||
or $conf->{totp2fDigits} == 8
|
||||
)
|
||||
? ''
|
||||
: 'TOTP should be 6 or 8 digits long'
|
||||
|
@ -509,9 +514,9 @@ sub tests {
|
|||
totp2fParams => sub {
|
||||
return 1 unless ( $conf->{totp2fActivation} );
|
||||
return ( 0, 'TOTP range must be defined' )
|
||||
unless ( $conf->{totp2fRange} );
|
||||
unless ( $conf->{totp2fRange} );
|
||||
return ( 1, "TOTP interval should be higher than 10s" )
|
||||
unless ( $conf->{totp2fInterval} > 10 );
|
||||
unless ( $conf->{totp2fInterval} > 10 );
|
||||
|
||||
# Return
|
||||
return 1;
|
||||
|
@ -522,11 +527,12 @@ sub tests {
|
|||
yubikey2fParams => sub {
|
||||
return 1 unless ( $conf->{yubikey2fActivation} );
|
||||
return ( 0, "Yubikey client ID and secret key must be set" )
|
||||
unless ( defined $conf->{yubikey2fSecretKey}
|
||||
unless ( defined $conf->{yubikey2fSecretKey}
|
||||
&& defined $conf->{yubikey2fClientID} );
|
||||
return (
|
||||
1,
|
||||
( ( $conf->{yubikey2fPublicIDSize} == 12 )
|
||||
(
|
||||
( $conf->{yubikey2fPublicIDSize} == 12 )
|
||||
? ''
|
||||
: 'Yubikey public ID size should be 12 digits long'
|
||||
)
|
||||
|
@ -537,7 +543,7 @@ sub tests {
|
|||
rest2fVerifyUrl => sub {
|
||||
return 1 unless ( $conf->{rest2fActivation} );
|
||||
return ( 0, "REST 2F Verify URL must be set" )
|
||||
unless ( defined $conf->{rest2fVerifyUrl} );
|
||||
unless ( defined $conf->{rest2fVerifyUrl} );
|
||||
|
||||
# Return
|
||||
return 1;
|
||||
|
@ -551,16 +557,15 @@ sub tests {
|
|||
my $ok = 0;
|
||||
foreach (qw(u totp yubikey)) {
|
||||
$ok ||= $conf->{ $_ . '2fActivation' }
|
||||
&& $conf->{ $_ . '2fSelfRegistration' };
|
||||
&& $conf->{ $_ . '2fSelfRegistration' };
|
||||
last if ($ok);
|
||||
}
|
||||
|
||||
$ok ||= $conf->{'utotp2fActivation'}
|
||||
&& ( $conf->{'u2fSelfRegistration'}
|
||||
&& ( $conf->{'u2fSelfRegistration'}
|
||||
|| $conf->{'totp2fSelfRegistration'} );
|
||||
$msg
|
||||
= "A self registrable module should be enabled to require 2FA"
|
||||
unless ($ok);
|
||||
$msg = "A self registrable module should be enabled to require 2FA"
|
||||
unless ($ok);
|
||||
|
||||
return ( 1, $msg );
|
||||
},
|
||||
|
@ -569,10 +574,10 @@ sub tests {
|
|||
ext2fCommands => sub {
|
||||
return 1 unless ( $conf->{ext2fActivation} );
|
||||
return ( 0, "External 2F Send command must be set" )
|
||||
unless ( defined $conf->{ext2FSendCommand} );
|
||||
unless ( defined $conf->{ext2FSendCommand} );
|
||||
unless ( defined $conf->{ext2fCodeActivation} ) {
|
||||
return ( 0, "External 2F Validate command must be set" )
|
||||
unless ( defined $conf->{ext2FValidateCommand} );
|
||||
unless ( defined $conf->{ext2FValidateCommand} );
|
||||
}
|
||||
|
||||
# Return
|
||||
|
@ -583,9 +588,9 @@ sub tests {
|
|||
formTimeout => sub {
|
||||
return 1 unless ( defined $conf->{formTimeout} );
|
||||
return ( 0, "XSRF form token TTL must be higher than 30s" )
|
||||
unless ( $conf->{formTimeout} > 30 );
|
||||
unless ( $conf->{formTimeout} > 30 );
|
||||
return ( 1, "XSRF form token TTL should not be higher than 2mn" )
|
||||
if ( $conf->{formTimeout} > 120 );
|
||||
if ( $conf->{formTimeout} > 120 );
|
||||
|
||||
# Return
|
||||
return 1;
|
||||
|
@ -594,9 +599,8 @@ sub tests {
|
|||
# Warn if number of password reset retries is null
|
||||
passwordResetRetries => sub {
|
||||
return 1 unless ( $conf->{portalDisplayResetPassword} );
|
||||
return ( 1,
|
||||
"Number of reset password retries should not be null" )
|
||||
unless ( $conf->{passwordResetAllowedRetries} );
|
||||
return ( 1, "Number of reset password retries should not be null" )
|
||||
unless ( $conf->{passwordResetAllowedRetries} );
|
||||
|
||||
# Return
|
||||
return 1;
|
||||
|
@ -606,10 +610,10 @@ sub tests {
|
|||
bruteForceProtection => sub {
|
||||
return 1 unless ( $conf->{bruteForceProtection} );
|
||||
return ( 1,
|
||||
'"History" plugin is required to enable "BruteForceProtection" plugin'
|
||||
'"History" plugin is required to enable "BruteForceProtection" plugin'
|
||||
) unless ( $conf->{loginHistoryEnabled} );
|
||||
return ( 1,
|
||||
'Number of failed logins must be higher than 2 to enable "BruteForceProtection" plugin'
|
||||
'Number of failed logins must be higher than 2 to enable "BruteForceProtection" plugin'
|
||||
) unless ( $conf->{failedLoginNumber} > 2 );
|
||||
|
||||
# Return
|
||||
|
@ -620,15 +624,25 @@ sub tests {
|
|||
checkMailResetSecurity => sub {
|
||||
return 1 unless ( $conf->{portalDisplayResetPassword} );
|
||||
return ( -1,
|
||||
'"passwordMailReset" plugin is enabled without CSRF Token neither Captcha required !!!'
|
||||
)
|
||||
unless ( $conf->{requireToken}
|
||||
'"passwordMailReset" plugin is enabled without CSRF Token neither Captcha required !!!'
|
||||
)
|
||||
unless ( $conf->{requireToken}
|
||||
or $conf->{captcha_mail_enabled} );
|
||||
|
||||
# Return
|
||||
return 1;
|
||||
},
|
||||
|
||||
## Warn if IdSpoofing plugin is enabled
|
||||
# checkIdSpoofing => sub {
|
||||
# return ( -1,
|
||||
# '"IdSpoofing" plugin is enabled!!!'
|
||||
# )
|
||||
# if ( $conf->{idSpoofingRule} );
|
||||
|
||||
# # Return
|
||||
# return 1;
|
||||
# },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
"clickHereToForce":"انقر هنا لإجبار",
|
||||
"checkState":"Activation",
|
||||
"checkStateSecret":"Shared secret",
|
||||
"checkUsers":"Session Check",
|
||||
"checkUsers":"SSO profile Check",
|
||||
"checkUser":"Activation",
|
||||
"checkUserHiddenAttributes":"Hidden attributes",
|
||||
"checkUserDisplayPersistentInfo":"Display persistent session",
|
||||
|
@ -286,6 +286,12 @@
|
|||
"hideTree":"إخفاء الشجرة",
|
||||
"httpOnly":"الحماية بواسطة جافا سكريبت",
|
||||
"https":"إتش تي تي بي س",
|
||||
"impersonation":"Impersonation",
|
||||
"impersonationRule":"Use rule",
|
||||
"impersonationHiddenAttributes":"Hidden attributes",
|
||||
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
|
||||
"impersonationPrefix":"Real attributes prefix",
|
||||
"impersonationSkipEmptyValues":"Skip empty values",
|
||||
"incompleteForm":"الحقول المطلوبة مفقودة",
|
||||
"index":"فهرس",
|
||||
"infoFormMethod":"طريقة للحصول على معلومات الإستمارة",
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
"clickHereToForce":"Click here to force",
|
||||
"checkState":"Activation",
|
||||
"checkStateSecret":"Shared secret",
|
||||
"checkUsers":"Session Check",
|
||||
"checkUsers":"SSO profile Check",
|
||||
"choiceParams":"Choice parameters",
|
||||
"checkUser":"Activation",
|
||||
"checkUserHiddenAttributes":"Hidden attributes",
|
||||
|
@ -286,6 +286,12 @@
|
|||
"hideTree":"Hide tree",
|
||||
"httpOnly":"Javascript protection",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Impersonation",
|
||||
"impersonationRule":"Use rule",
|
||||
"impersonationHiddenAttributes":"Hidden attributes",
|
||||
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
|
||||
"impersonationPrefix":"Real attributes prefix",
|
||||
"impersonationSkipEmptyValues":"Skip empty values",
|
||||
"incompleteForm":"Required fields are missing",
|
||||
"index":"Index",
|
||||
"infoFormMethod":"Method for info form",
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
"clickHereToForce":"Click here to force",
|
||||
"checkState":"Activation",
|
||||
"checkStateSecret":"Shared secret",
|
||||
"checkUsers":"Session Check",
|
||||
"checkUsers":"SSO profile Check",
|
||||
"checkUser":"Activation",
|
||||
"checkUserHiddenAttributes":"Hidden attributes",
|
||||
"checkUserDisplayPersistentInfo":"Display persistent session",
|
||||
|
@ -286,6 +286,12 @@
|
|||
"hideTree":"Hide tree",
|
||||
"httpOnly":"Javascript protection",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Impersonation",
|
||||
"impersonationRule":"Use rule",
|
||||
"impersonationHiddenAttributes":"Hidden attributes",
|
||||
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
|
||||
"impersonationPrefix":"Real attributes prefix",
|
||||
"impersonationSkipEmptyValues":"Skip empty values",
|
||||
"incompleteForm":"Required fields are missing",
|
||||
"index":"Index",
|
||||
"infoFormMethod":"Method for info form",
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
"clickHereToForce":"Cliquer ici pour forcer",
|
||||
"checkState":"Activation",
|
||||
"checkStateSecret":"Secret partagé",
|
||||
"checkUsers":"Vérification de session",
|
||||
"checkUsers":"Vérification des profils SSO",
|
||||
"checkUser":"Activation",
|
||||
"checkUserHiddenAttributes":"Attributs masqués",
|
||||
"checkUserDisplayPersistentInfo":"Afficher les données de session persistante",
|
||||
|
@ -286,6 +286,12 @@
|
|||
"hideTree":"Masquer l'arbre",
|
||||
"httpOnly":"Protection contre javascript",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Usurpation d'identité",
|
||||
"impersonationRule":"Règle d'utilisation",
|
||||
"impersonationHiddenAttributes":"Attributs masqués",
|
||||
"impersonationMergeSSOgroups":"Fusionner les groupes SSO réels et usurpés",
|
||||
"impersonationPrefix":"Préfix des vrais attributs",
|
||||
"impersonationSkipEmptyValues":"Ignorer les valeurs nulles",
|
||||
"incompleteForm":"Des champs requis manquent",
|
||||
"index":"Index",
|
||||
"infoFormMethod":"Méthode du formulaire d'information",
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
"clickHereToForce":"Clicca qui per forzare",
|
||||
"checkState":"Attivazione",
|
||||
"checkStateSecret":"Segreto condiviso",
|
||||
"checkUsers":"Session Check",
|
||||
"checkUsers":"SSO profile Check",
|
||||
"checkUser":"Activation",
|
||||
"checkUserHiddenAttributes":"Hidden attributes",
|
||||
"checkUserDisplayPersistentInfo":"Display persistent session",
|
||||
|
@ -286,6 +286,12 @@
|
|||
"hideTree":"Nascondi l'albero",
|
||||
"httpOnly":"Protezione Javascript",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Impersonation",
|
||||
"impersonationRule":"Use rule",
|
||||
"impersonationHiddenAttributes":"Hidden attributes",
|
||||
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
|
||||
"impersonationPrefix":"Real attributes prefix",
|
||||
"impersonationSkipEmptyValues":"Skip empty values",
|
||||
"incompleteForm":"Mancano campi obbligatori",
|
||||
"index":"Indice",
|
||||
"infoFormMethod":"Metodo per il modulo informazioni",
|
||||
|
|
|
@ -286,6 +286,12 @@
|
|||
"hideTree":"Ẩn cây",
|
||||
"httpOnly":"Bảo vệ Javascript",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Impersonation",
|
||||
"impersonationRule":"Use rule",
|
||||
"impersonationHiddenAttributes":"Hidden attributes",
|
||||
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
|
||||
"impersonationPrefix":"Real attributes prefix",
|
||||
"impersonationSkipEmptyValues":"Skip empty values",
|
||||
"incompleteForm":"Các trường bắt buộc bị thiếu",
|
||||
"index":"Chỉ mục",
|
||||
"infoFormMethod":"Phương pháp cho mẫu thông tin",
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
"clickHereToForce":"Click here to force",
|
||||
"checkState":"Activation",
|
||||
"checkStateSecret":"Shared secret",
|
||||
"checkUsers":"Session Check",
|
||||
"checkUsers":"SSO profile Check",
|
||||
"checkUser":"Activation",
|
||||
"checkUserHiddenAttributes":"Hidden attributes",
|
||||
"checkUserDisplayPersistentInfo":"Display persistent session",
|
||||
|
@ -286,6 +286,12 @@
|
|||
"hideTree":"Hide tree",
|
||||
"httpOnly":"Javascript protection",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Impersonation",
|
||||
"impersonationRule":"Use rule",
|
||||
"impersonationHiddenAttributes":"Hidden attributes",
|
||||
"impersonationMergeSSOgroups":"Merge spoofed and real SSO groups",
|
||||
"impersonationPrefix":"Real attributes prefix",
|
||||
"impersonationSkipEmptyValues":"Skip empty values",
|
||||
"incompleteForm":"Required fields are missing",
|
||||
"index":"Index",
|
||||
"infoFormMethod":"Method for info form",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<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" />
|
||||
|
|
|
@ -104,6 +104,7 @@ lib/Lemonldap/NG/Portal/Plugins/CheckUser.pm
|
|||
lib/Lemonldap/NG/Portal/Plugins/ForceAuthn.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/History.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/Impersonation.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/Notifications.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/PublicPages.pm
|
||||
|
@ -338,6 +339,7 @@ site/templates/bootstrap/footer.tpl
|
|||
site/templates/bootstrap/gpgform.tpl
|
||||
site/templates/bootstrap/header.tpl
|
||||
site/templates/bootstrap/idpchoice.tpl
|
||||
site/templates/bootstrap/impersonation.tpl
|
||||
site/templates/bootstrap/info.tpl
|
||||
site/templates/bootstrap/ldapPpGrace.tpl
|
||||
site/templates/bootstrap/login.json
|
||||
|
@ -503,6 +505,8 @@ t/66-CDA-with-SOAP.t
|
|||
t/66-CDA.t
|
||||
t/67-CheckUser-with-token.t
|
||||
t/67-CheckUser.t
|
||||
t/68-Impersonation-with-merge.t
|
||||
t/68-Impersonation.t
|
||||
t/70-2F-TOTP-with-History.t
|
||||
t/70-2F-TOTP.t
|
||||
t/70-2F-TOTP_8.t
|
||||
|
|
|
@ -4,11 +4,11 @@ use strict;
|
|||
use Mouse;
|
||||
use String::Random;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_BADCREDENTIALS
|
||||
PE_ERROR
|
||||
PE_FORMEMPTY
|
||||
PE_OK
|
||||
PE_SENDRESPONSE
|
||||
PE_BADCREDENTIALS
|
||||
PE_ERROR
|
||||
PE_FORMEMPTY
|
||||
PE_OK
|
||||
PE_SENDRESPONSE
|
||||
);
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
@ -30,7 +30,7 @@ sub init {
|
|||
}
|
||||
}
|
||||
$self->logo( $self->conf->{ext2fLogo} )
|
||||
if ( $self->conf->{ext2fLogo} );
|
||||
if ( $self->conf->{ext2fLogo} );
|
||||
return $self->SUPER::init();
|
||||
}
|
||||
if ( $self->conf->{ext2fCodeActivation} ) {
|
||||
|
@ -40,7 +40,7 @@ sub init {
|
|||
}
|
||||
$self->random( String::Random->new );
|
||||
$self->logo( $self->conf->{ext2fLogo} )
|
||||
if ( $self->conf->{ext2fLogo} );
|
||||
if ( $self->conf->{ext2fLogo} );
|
||||
return $self->SUPER::init();
|
||||
}
|
||||
return 0;
|
||||
|
@ -57,22 +57,22 @@ sub run {
|
|||
# Generate Code to send
|
||||
my $code;
|
||||
if ( $self->conf->{ext2fCodeActivation} ) {
|
||||
$code
|
||||
= $self->random->randregex( $self->conf->{ext2fCodeActivation} );
|
||||
$code = $self->random->randregex( $self->conf->{ext2fCodeActivation} );
|
||||
$self->logger->debug("Generated ext2f code : $code");
|
||||
$self->ott->updateToken( $token, __ext2fcode => $code );
|
||||
}
|
||||
|
||||
# Prepare command and launch it
|
||||
$self->logger->debug( 'Launching "Send" external 2F command -> '
|
||||
. $self->conf->{ext2FSendCommand} );
|
||||
if (my $c = $self->launch(
|
||||
. $self->conf->{ext2FSendCommand} );
|
||||
if (
|
||||
my $c = $self->launch(
|
||||
$req->sessionInfo, $self->conf->{ext2FSendCommand}, $code
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
$self->logger->error("External send command failed (code $c)");
|
||||
return $self->p->do( $req, [ sub {PE_ERROR} ] );
|
||||
return $self->p->do( $req, [ sub { PE_ERROR } ] );
|
||||
}
|
||||
|
||||
# Prepare form
|
||||
|
@ -104,15 +104,16 @@ sub verify {
|
|||
|
||||
# Prepare command and launch it
|
||||
$self->logger->debug( 'Launching "Validate" external 2F command -> '
|
||||
. $self->conf->{ext2FValidateCommand} );
|
||||
. $self->conf->{ext2FValidateCommand} );
|
||||
$self->logger->debug(" code -> $usercode");
|
||||
if (my $c = $self->launch(
|
||||
if (
|
||||
my $c = $self->launch(
|
||||
$session, $self->conf->{ext2FValidateCommand}, $usercode
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
$self->userLogger->warn( 'Second factor failed for '
|
||||
. $session->{ $self->conf->{whatToTrace} } );
|
||||
. $session->{ $self->conf->{whatToTrace} } );
|
||||
$self->logger->error("External verify command failed (code $c)");
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
|
@ -130,7 +131,7 @@ sub verify {
|
|||
return PE_OK if ( $usercode eq $savedcode );
|
||||
|
||||
$self->userLogger->warn( 'Second factor failed for '
|
||||
. $session->{ $self->conf->{whatToTrace} } );
|
||||
. $session->{ $self->conf->{whatToTrace} } );
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,18 +4,18 @@ use strict;
|
|||
use Mouse;
|
||||
use String::Random;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_BADCREDENTIALS
|
||||
PE_ERROR
|
||||
PE_FORMEMPTY
|
||||
PE_OK
|
||||
PE_SENDRESPONSE
|
||||
PE_MUSTHAVEMAIL
|
||||
PE_BADCREDENTIALS
|
||||
PE_ERROR
|
||||
PE_FORMEMPTY
|
||||
PE_OK
|
||||
PE_SENDRESPONSE
|
||||
PE_MUSTHAVEMAIL
|
||||
);
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::SecondFactor',
|
||||
'Lemonldap::NG::Portal::Lib::SMTP';
|
||||
'Lemonldap::NG::Portal::Lib::SMTP';
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
|
@ -31,10 +31,10 @@ has ott => (
|
|||
is => 'rw',
|
||||
lazy => 1,
|
||||
default => sub {
|
||||
my $ott = $_[0]->{p}
|
||||
->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken');
|
||||
my $ott =
|
||||
$_[0]->{p}->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken');
|
||||
$ott->timeout( $_[0]->{conf}->{mail2fTimeout}
|
||||
|| $_[0]->{conf}->{formTimeout} );
|
||||
|| $_[0]->{conf}->{formTimeout} );
|
||||
return $ott;
|
||||
}
|
||||
);
|
||||
|
@ -47,7 +47,7 @@ sub init {
|
|||
return 0;
|
||||
}
|
||||
$self->logo( $self->conf->{mail2fLogo} )
|
||||
if ( $self->conf->{mail2fLogo} );
|
||||
if ( $self->conf->{mail2fLogo} );
|
||||
return $self->SUPER::init();
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ sub run {
|
|||
my $dest = $req->{sessionInfo}->{ $self->conf->{mailSessionKey} };
|
||||
unless ($dest) {
|
||||
$self->logger->error( "Could not find mail attribute for login "
|
||||
. $req->{sessionInfo}->{_user} );
|
||||
. $req->{sessionInfo}->{_user} );
|
||||
return PE_MUSTHAVEMAIL;
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ sub verify {
|
|||
return PE_OK if ( $usercode eq $savedcode );
|
||||
|
||||
$self->userLogger->warn( 'Second factor failed for '
|
||||
. $session->{ $self->conf->{whatToTrace} } );
|
||||
. $session->{ $self->conf->{whatToTrace} } );
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ sub authenticate {
|
|||
|
||||
unless ( $req->data->{password} ) {
|
||||
$self->p->{user} = $req->userData->{_dn} = $req->data->{dn};
|
||||
unless($self->p->{_passwordDB}) {
|
||||
unless ( $self->p->{_passwordDB} ) {
|
||||
$self->logger->error('No password database configured, aborting');
|
||||
return PE_ERROR;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_OK
|
||||
PE_PASSWORDFORMEMPTY
|
||||
PE_TOKENEXPIRED
|
||||
PE_MALFORMEDUSER
|
||||
);
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
@ -53,6 +54,13 @@ sub init {
|
|||
sub extractFormInfo {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
if ( $req->param('user') ) {
|
||||
unless ( $req->param('user') =~ /$self->{conf}->{userControl}/o ) {
|
||||
$self->setSecurity($req);
|
||||
return PE_MALFORMEDUSER;
|
||||
}
|
||||
}
|
||||
|
||||
# Detect first access and empty forms
|
||||
my $defUser = defined $req->param('user');
|
||||
my $defPassword = defined $req->param('password');
|
||||
|
|
|
@ -4,7 +4,8 @@ use strict;
|
|||
use Mouse;
|
||||
use URI::Escape;
|
||||
use Lemonldap::NG::Common::FormEncode;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_BADURL PE_GET_SERVICE_NOT_ALLOWED);
|
||||
use Lemonldap::NG::Portal::Main::Constants
|
||||
qw(PE_OK PE_BADURL PE_GET_SERVICE_NOT_ALLOWED);
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
|
@ -19,11 +20,9 @@ sub init {
|
|||
|
||||
# Parse activation rule
|
||||
my $hd = $self->p->HANDLER;
|
||||
$self->logger->debug(
|
||||
"GET rule -> " . $self->conf->{issuerDBGetRule} );
|
||||
$self->logger->debug( "GET rule -> " . $self->conf->{issuerDBGetRule} );
|
||||
my $rule =
|
||||
$hd->buildSub(
|
||||
$hd->substitute( $self->conf->{issuerDBGetRule} ) );
|
||||
$hd->buildSub( $hd->substitute( $self->conf->{issuerDBGetRule} ) );
|
||||
unless ($rule) {
|
||||
$self->error( "Bad GET rule -> " . $hd->tsv->{jail}->error );
|
||||
return 0;
|
||||
|
|
|
@ -62,8 +62,7 @@ sub init {
|
|||
$self->logger->debug(
|
||||
"OpenID rule -> " . $self->conf->{issuerDBOpenIDRule} );
|
||||
my $rule =
|
||||
$hd->buildSub(
|
||||
$hd->substitute( $self->conf->{issuerDBOpenIDRule} ) );
|
||||
$hd->buildSub( $hd->substitute( $self->conf->{issuerDBOpenIDRule} ) );
|
||||
unless ($rule) {
|
||||
$self->error( "Bad OpenID rule -> " . $hd->tsv->{jail}->error );
|
||||
return 0;
|
||||
|
|
|
@ -145,11 +145,13 @@ sub init {
|
|||
|
||||
return 0 unless ( $self->lassoServer( $self->loadService ) );
|
||||
$self->addUnauthRoute(
|
||||
( $self->{path} || 'saml' ) => { 'metadata' => { ':type' => 'metadata' }},
|
||||
( $self->{path} || 'saml' ) =>
|
||||
{ 'metadata' => { ':type' => 'metadata' } },
|
||||
['GET']
|
||||
);
|
||||
$self->addAuthRoute(
|
||||
( $self->{path} || 'saml' ) => { 'metadata' => { ':type' => 'metadata' }},
|
||||
( $self->{path} || 'saml' ) =>
|
||||
{ 'metadata' => { ':type' => 'metadata' } },
|
||||
['GET']
|
||||
);
|
||||
return 1;
|
||||
|
@ -3075,7 +3077,7 @@ sub metadata {
|
|||
my $type = $req->param('type');
|
||||
require Lemonldap::NG::Common::Conf::SAML::Metadata;
|
||||
if ( my $metadata = Lemonldap::NG::Common::Conf::SAML::Metadata->new() ) {
|
||||
my $s = $metadata->serviceToXML( $self->conf, $type);
|
||||
my $s = $metadata->serviceToXML( $self->conf, $type );
|
||||
return [
|
||||
200,
|
||||
[
|
||||
|
|
|
@ -10,95 +10,95 @@ use constant {
|
|||
|
||||
# Portal errors
|
||||
# Developers warning, do not use PE_INFO, it's reserved to autoRedirect.
|
||||
PE_IDPCHOICE => -5,
|
||||
PE_SENDRESPONSE => -4,
|
||||
PE_INFO => -3,
|
||||
PE_REDIRECT => -2,
|
||||
PE_DONE => -1,
|
||||
PE_OK => 0,
|
||||
PE_SESSIONEXPIRED => 1,
|
||||
PE_FORMEMPTY => 2,
|
||||
PE_WRONGMANAGERACCOUNT => 3,
|
||||
PE_USERNOTFOUND => 4,
|
||||
PE_BADCREDENTIALS => 5,
|
||||
PE_LDAPCONNECTFAILED => 6,
|
||||
PE_LDAPERROR => 7,
|
||||
PE_APACHESESSIONERROR => 8,
|
||||
PE_FIRSTACCESS => 9,
|
||||
PE_BADCERTIFICATE => 10,
|
||||
PE_PP_ACCOUNT_LOCKED => 21,
|
||||
PE_PP_PASSWORD_EXPIRED => 22,
|
||||
PE_CERTIFICATEREQUIRED => 23,
|
||||
PE_ERROR => 24,
|
||||
PE_PP_CHANGE_AFTER_RESET => 25,
|
||||
PE_PP_PASSWORD_MOD_NOT_ALLOWED => 26,
|
||||
PE_PP_MUST_SUPPLY_OLD_PASSWORD => 27,
|
||||
PE_PP_INSUFFICIENT_PASSWORD_QUALITY => 28,
|
||||
PE_PP_PASSWORD_TOO_SHORT => 29,
|
||||
PE_PP_PASSWORD_TOO_YOUNG => 30,
|
||||
PE_PP_PASSWORD_IN_HISTORY => 31,
|
||||
PE_PP_GRACE => 32,
|
||||
PE_PP_EXP_WARNING => 33,
|
||||
PE_PASSWORD_MISMATCH => 34,
|
||||
PE_PASSWORD_OK => 35,
|
||||
PE_NOTIFICATION => 36,
|
||||
PE_BADURL => 37,
|
||||
PE_NOSCHEME => 38,
|
||||
PE_BADOLDPASSWORD => 39,
|
||||
PE_MALFORMEDUSER => 40,
|
||||
PE_SESSIONNOTGRANTED => 41,
|
||||
PE_CONFIRM => 42,
|
||||
PE_MAILFORMEMPTY => 43,
|
||||
PE_BADMAILTOKEN => 44,
|
||||
PE_MAILERROR => 45,
|
||||
PE_MAILOK => 46,
|
||||
PE_LOGOUT_OK => 47,
|
||||
PE_SAML_ERROR => 48,
|
||||
PE_SAML_LOAD_SERVICE_ERROR => 49,
|
||||
PE_SAML_LOAD_IDP_ERROR => 50,
|
||||
PE_SAML_SSO_ERROR => 51,
|
||||
PE_SAML_UNKNOWN_ENTITY => 52,
|
||||
PE_SAML_DESTINATION_ERROR => 53,
|
||||
PE_SAML_CONDITIONS_ERROR => 54,
|
||||
PE_SAML_IDPSSOINITIATED_NOTALLOWED => 55,
|
||||
PE_SAML_SLO_ERROR => 56,
|
||||
PE_SAML_SIGNATURE_ERROR => 57,
|
||||
PE_SAML_ART_ERROR => 58,
|
||||
PE_SAML_SESSION_ERROR => 59,
|
||||
PE_SAML_LOAD_SP_ERROR => 60,
|
||||
PE_SAML_ATTR_ERROR => 61,
|
||||
PE_OPENID_EMPTY => 62,
|
||||
PE_OPENID_BADID => 63,
|
||||
PE_MISSINGREQATTR => 64,
|
||||
PE_BADPARTNER => 65,
|
||||
PE_MAILCONFIRMATION_ALREADY_SENT => 66,
|
||||
PE_PASSWORDFORMEMPTY => 67,
|
||||
PE_CAS_SERVICE_NOT_ALLOWED => 68,
|
||||
PE_MAILFIRSTACCESS => 69,
|
||||
PE_MAILNOTFOUND => 70,
|
||||
PE_PASSWORDFIRSTACCESS => 71,
|
||||
PE_MAILCONFIRMOK => 72,
|
||||
PE_RADIUSCONNECTFAILED => 73,
|
||||
PE_MUST_SUPPLY_OLD_PASSWORD => 74,
|
||||
PE_FORBIDDENIP => 75,
|
||||
PE_CAPTCHAERROR => 76,
|
||||
PE_CAPTCHAEMPTY => 77,
|
||||
PE_REGISTERFIRSTACCESS => 78,
|
||||
PE_REGISTERFORMEMPTY => 79,
|
||||
PE_REGISTERALREADYEXISTS => 80,
|
||||
PE_NOTOKEN => 81,
|
||||
PE_TOKENEXPIRED => 82,
|
||||
PE_U2FFAILED => 83,
|
||||
PE_UNAUTHORIZEDPARTNER => 84,
|
||||
PE_RENEWSESSION => 85,
|
||||
PE_WAIT => 86,
|
||||
PE_MUSTAUTHN => 87,
|
||||
PE_MUSTHAVEMAIL => 88,
|
||||
PE_SAML_SERVICE_NOT_ALLOWED => 89,
|
||||
PE_OIDC_SERVICE_NOT_ALLOWED => 90,
|
||||
PE_OID_SERVICE_NOT_ALLOWED => 91,
|
||||
PE_GET_SERVICE_NOT_ALLOWED => 92,
|
||||
|
||||
PE_IDPCHOICE => -5,
|
||||
PE_SENDRESPONSE => -4,
|
||||
PE_INFO => -3,
|
||||
PE_REDIRECT => -2,
|
||||
PE_DONE => -1,
|
||||
PE_OK => 0,
|
||||
PE_SESSIONEXPIRED => 1,
|
||||
PE_FORMEMPTY => 2,
|
||||
PE_WRONGMANAGERACCOUNT => 3,
|
||||
PE_USERNOTFOUND => 4,
|
||||
PE_BADCREDENTIALS => 5,
|
||||
PE_LDAPCONNECTFAILED => 6,
|
||||
PE_LDAPERROR => 7,
|
||||
PE_APACHESESSIONERROR => 8,
|
||||
PE_FIRSTACCESS => 9,
|
||||
PE_BADCERTIFICATE => 10,
|
||||
PE_PP_ACCOUNT_LOCKED => 21,
|
||||
PE_PP_PASSWORD_EXPIRED => 22,
|
||||
PE_CERTIFICATEREQUIRED => 23,
|
||||
PE_ERROR => 24,
|
||||
PE_PP_CHANGE_AFTER_RESET => 25,
|
||||
PE_PP_PASSWORD_MOD_NOT_ALLOWED => 26,
|
||||
PE_PP_MUST_SUPPLY_OLD_PASSWORD => 27,
|
||||
PE_PP_INSUFFICIENT_PASSWORD_QUALITY => 28,
|
||||
PE_PP_PASSWORD_TOO_SHORT => 29,
|
||||
PE_PP_PASSWORD_TOO_YOUNG => 30,
|
||||
PE_PP_PASSWORD_IN_HISTORY => 31,
|
||||
PE_PP_GRACE => 32,
|
||||
PE_PP_EXP_WARNING => 33,
|
||||
PE_PASSWORD_MISMATCH => 34,
|
||||
PE_PASSWORD_OK => 35,
|
||||
PE_NOTIFICATION => 36,
|
||||
PE_BADURL => 37,
|
||||
PE_NOSCHEME => 38,
|
||||
PE_BADOLDPASSWORD => 39,
|
||||
PE_MALFORMEDUSER => 40,
|
||||
PE_SESSIONNOTGRANTED => 41,
|
||||
PE_CONFIRM => 42,
|
||||
PE_MAILFORMEMPTY => 43,
|
||||
PE_BADMAILTOKEN => 44,
|
||||
PE_MAILERROR => 45,
|
||||
PE_MAILOK => 46,
|
||||
PE_LOGOUT_OK => 47,
|
||||
PE_SAML_ERROR => 48,
|
||||
PE_SAML_LOAD_SERVICE_ERROR => 49,
|
||||
PE_SAML_LOAD_IDP_ERROR => 50,
|
||||
PE_SAML_SSO_ERROR => 51,
|
||||
PE_SAML_UNKNOWN_ENTITY => 52,
|
||||
PE_SAML_DESTINATION_ERROR => 53,
|
||||
PE_SAML_CONDITIONS_ERROR => 54,
|
||||
PE_SAML_IDPSSOINITIATED_NOTALLOWED => 55,
|
||||
PE_SAML_SLO_ERROR => 56,
|
||||
PE_SAML_SIGNATURE_ERROR => 57,
|
||||
PE_SAML_ART_ERROR => 58,
|
||||
PE_SAML_SESSION_ERROR => 59,
|
||||
PE_SAML_LOAD_SP_ERROR => 60,
|
||||
PE_SAML_ATTR_ERROR => 61,
|
||||
PE_OPENID_EMPTY => 62,
|
||||
PE_OPENID_BADID => 63,
|
||||
PE_MISSINGREQATTR => 64,
|
||||
PE_BADPARTNER => 65,
|
||||
PE_MAILCONFIRMATION_ALREADY_SENT => 66,
|
||||
PE_PASSWORDFORMEMPTY => 67,
|
||||
PE_CAS_SERVICE_NOT_ALLOWED => 68,
|
||||
PE_MAILFIRSTACCESS => 69,
|
||||
PE_MAILNOTFOUND => 70,
|
||||
PE_PASSWORDFIRSTACCESS => 71,
|
||||
PE_MAILCONFIRMOK => 72,
|
||||
PE_RADIUSCONNECTFAILED => 73,
|
||||
PE_MUST_SUPPLY_OLD_PASSWORD => 74,
|
||||
PE_FORBIDDENIP => 75,
|
||||
PE_CAPTCHAERROR => 76,
|
||||
PE_CAPTCHAEMPTY => 77,
|
||||
PE_REGISTERFIRSTACCESS => 78,
|
||||
PE_REGISTERFORMEMPTY => 79,
|
||||
PE_REGISTERALREADYEXISTS => 80,
|
||||
PE_NOTOKEN => 81,
|
||||
PE_TOKENEXPIRED => 82,
|
||||
PE_U2FFAILED => 83,
|
||||
PE_UNAUTHORIZEDPARTNER => 84,
|
||||
PE_RENEWSESSION => 85,
|
||||
PE_WAIT => 86,
|
||||
PE_MUSTAUTHN => 87,
|
||||
PE_MUSTHAVEMAIL => 88,
|
||||
PE_SAML_SERVICE_NOT_ALLOWED => 89,
|
||||
PE_OIDC_SERVICE_NOT_ALLOWED => 90,
|
||||
PE_OID_SERVICE_NOT_ALLOWED => 91,
|
||||
PE_GET_SERVICE_NOT_ALLOWED => 92,
|
||||
PE_IMPERSONATION_SERVICE_NOT_ALLOWED => 93,
|
||||
};
|
||||
|
||||
# EXPORTER PARAMETERS
|
||||
|
@ -126,7 +126,7 @@ our @EXPORT_OK = qw( PE_SENDRESPONSE PE_INFO PE_REDIRECT PE_DONE PE_OK
|
|||
PE_REGISTERALREADYEXISTS PE_NOTOKEN PE_TOKENEXPIRED HANDLER PE_U2FFAILED
|
||||
PE_UNAUTHORIZEDPARTNER PE_RENEWSESSION PE_IDPCHOICE PE_WAIT PE_MUSTAUTHN
|
||||
PE_MUSTHAVEMAIL PE_SAML_SERVICE_NOT_ALLOWED PE_OIDC_SERVICE_NOT_ALLOWED
|
||||
PE_OID_SERVICE_NOT_ALLOWED PE_GET_SERVICE_NOT_ALLOWED
|
||||
PE_OID_SERVICE_NOT_ALLOWED PE_GET_SERVICE_NOT_ALLOWED PE_IMPERSONATION_SERVICE_NOT_ALLOWED
|
||||
);
|
||||
our %EXPORT_TAGS = ( 'all' => [ @EXPORT_OK, 'import' ], );
|
||||
|
||||
|
|
|
@ -291,6 +291,7 @@ sub display {
|
|||
REGISTER_URL => $self->conf->{registerUrl},
|
||||
HIDDEN_INPUTS => $self->buildHiddenForm($req),
|
||||
STAYCONNECTED => $self->conf->{stayConnected},
|
||||
SPOOFID => $self->conf->{impersonationRule},
|
||||
(
|
||||
$req->data->{customScript}
|
||||
? ( CUSTOM_SCRIPT => $req->data->{customScript} )
|
||||
|
|
|
@ -88,9 +88,9 @@ has csp => ( is => 'rw' );
|
|||
sub init {
|
||||
my ( $self, $args ) = @_;
|
||||
$args ||= {};
|
||||
$self->localConfig(
|
||||
{ %{ Lemonldap::NG::Common::Conf->new( $args->{configStorage} )
|
||||
->getLocalConf('portal')
|
||||
$self->localConfig( {
|
||||
%{ Lemonldap::NG::Common::Conf->new( $args->{configStorage} )
|
||||
->getLocalConf('portal')
|
||||
},
|
||||
%$args
|
||||
}
|
||||
|
@ -101,8 +101,7 @@ sub init {
|
|||
and -r $self->{localConfig}->{translations} )
|
||||
{
|
||||
open my $tr_file, '<', $self->{localConfig}->{translations}
|
||||
or die "Can't open"
|
||||
. $self->{localConfig}->{translations} . " : $!";
|
||||
or die "Can't open" . $self->{localConfig}->{translations} . " : $!";
|
||||
while (<$tr_file>) {
|
||||
chomp;
|
||||
$_ =~ /^([\w_]+)\s+=\s+(.+)$/;
|
||||
|
@ -141,33 +140,33 @@ sub init {
|
|||
# Handle requests (other path may be declared in enabled plugins)
|
||||
$self
|
||||
|
||||
# "/" or undeclared paths
|
||||
->addUnauthRoute( '*' => 'login', ['GET'] )
|
||||
->addUnauthRoute( '*' => 'postLogin', ['POST'] )
|
||||
->addAuthRoute( '*' => 'authenticatedRequest', ['GET'] )
|
||||
->addAuthRoute( '*' => 'postAuthenticatedRequest', ['POST'] )
|
||||
# "/" or undeclared paths
|
||||
->addUnauthRoute( '*' => 'login', ['GET'] )
|
||||
->addUnauthRoute( '*' => 'postLogin', ['POST'] )
|
||||
->addAuthRoute( '*' => 'authenticatedRequest', ['GET'] )
|
||||
->addAuthRoute( '*' => 'postAuthenticatedRequest', ['POST'] )
|
||||
|
||||
# psgi.js
|
||||
->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||
# psgi.js
|
||||
->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||
|
||||
# portal.css
|
||||
->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||
# portal.css
|
||||
->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||
|
||||
# lmerror
|
||||
->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||
# lmerror
|
||||
->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||
|
||||
# Core REST API
|
||||
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
|
||||
->addAuthRoute( ping => 'authenticated', ['GET'] )
|
||||
# Core REST API
|
||||
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
|
||||
->addAuthRoute( ping => 'authenticated', ['GET'] )
|
||||
|
||||
# Refresh session
|
||||
->addAuthRoute( refresh => 'refresh', ['GET'] )
|
||||
# Refresh session
|
||||
->addAuthRoute( refresh => 'refresh', ['GET'] )
|
||||
|
||||
# Logout
|
||||
->addAuthRoute( logout => 'logout', ['GET'] );
|
||||
# Logout
|
||||
->addAuthRoute( logout => 'logout', ['GET'] );
|
||||
|
||||
# Default routes must point to routines declared above
|
||||
$self->defaultAuthRoute('');
|
||||
|
@ -201,8 +200,8 @@ sub reloadConf {
|
|||
$self->csp($csp);
|
||||
|
||||
# Initialize templateDir
|
||||
$self->{templateDir}
|
||||
= $self->conf->{templateDir} . '/' . $self->conf->{portalSkin};
|
||||
$self->{templateDir} =
|
||||
$self->conf->{templateDir} . '/' . $self->conf->{portalSkin};
|
||||
unless ( -d $self->{templateDir} ) {
|
||||
$self->error("Template dir $self->{templateDir} doesn't exist");
|
||||
return $self->fail;
|
||||
|
@ -222,8 +221,8 @@ sub reloadConf {
|
|||
# Initialize persistent session DB
|
||||
unless ( $self->conf->{persistentStorage} ) {
|
||||
$self->conf->{persistentStorage} = $self->conf->{globalStorage};
|
||||
$self->conf->{persistentStorageOptions}
|
||||
= $self->conf->{globalStorageOptions};
|
||||
$self->conf->{persistentStorageOptions} =
|
||||
$self->conf->{globalStorageOptions};
|
||||
}
|
||||
|
||||
# Initialize cookie domain
|
||||
|
@ -247,19 +246,19 @@ sub reloadConf {
|
|||
return $self->fail;
|
||||
}
|
||||
$mod = $self->conf->{$type}
|
||||
unless ( $self->conf->{$type} eq 'Same' );
|
||||
unless ( $self->conf->{$type} eq 'Same' );
|
||||
my $module = '::' . ucfirst($type) . '::' . $mod;
|
||||
$module =~ s/Authentication/Auth/;
|
||||
|
||||
# Launch and initialize module
|
||||
return $self->fail
|
||||
unless ( $self->{"_$type"} = $self->loadPlugin($module) );
|
||||
unless ( $self->{"_$type"} = $self->loadPlugin($module) );
|
||||
}
|
||||
|
||||
# Load second-factor engine
|
||||
return $self->fail
|
||||
unless $self->{_sfEngine}
|
||||
= $self->loadPlugin( $self->conf->{'sfEngine'} );
|
||||
unless $self->{_sfEngine} =
|
||||
$self->loadPlugin( $self->conf->{'sfEngine'} );
|
||||
|
||||
# Initialize trusted domain regexp
|
||||
if ( $self->conf->{trustedDomains}
|
||||
|
@ -282,8 +281,8 @@ sub reloadConf {
|
|||
# - $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;
|
||||
$_ =~
|
||||
s/\*\\\./(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9]\\.)*/g;
|
||||
$re->add("$_");
|
||||
}
|
||||
}
|
||||
|
@ -294,8 +293,8 @@ sub reloadConf {
|
|||
$self->logger->debug("Vhost $vhost added in trusted domains");
|
||||
$re->add( quotemeta($vhost) );
|
||||
$self->conf->{vhostOptions} ||= {};
|
||||
if ( my $tmp
|
||||
= $self->conf->{vhostOptions}->{$vhost}->{vhostAliases} )
|
||||
if ( my $tmp =
|
||||
$self->conf->{vhostOptions}->{$vhost}->{vhostAliases} )
|
||||
{
|
||||
foreach my $alias ( split /\s+/, $tmp ) {
|
||||
$self->logger->debug(
|
||||
|
@ -313,22 +312,22 @@ sub reloadConf {
|
|||
$self->{"_$type"} = {};
|
||||
if ( $self->conf->{$type} ) {
|
||||
for my $name ( sort keys %{ $self->conf->{$type} } ) {
|
||||
my $sub = HANDLER->buildSub(
|
||||
my $sub =
|
||||
HANDLER->buildSub(
|
||||
HANDLER->substitute( $self->conf->{$type}->{$name} ) );
|
||||
if ($sub) {
|
||||
$self->{"_$type"}->{$name} = $sub;
|
||||
}
|
||||
else {
|
||||
$self->logger->error( "$type $name returns an error: "
|
||||
. HANDLER->tsv->{jail}->error );
|
||||
. HANDLER->tsv->{jail}->error );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$self->{_jsRedirect}
|
||||
= HANDLER->buildSub(
|
||||
HANDLER->substitute( $self->conf->{jsRedirect} ) )
|
||||
or $self->logger->error(
|
||||
$self->{_jsRedirect} =
|
||||
HANDLER->buildSub( HANDLER->substitute( $self->conf->{jsRedirect} ) )
|
||||
or $self->logger->error(
|
||||
'jsRedirect returns an error: ' . HANDLER->tsv->{jail}->error );
|
||||
|
||||
# Load plugins
|
||||
|
@ -351,6 +350,9 @@ sub reloadConf {
|
|||
return PE_OK;
|
||||
}
|
||||
};
|
||||
my $portal = $self->conf->{portal};
|
||||
$portal =~ s#^https?://(.*?)(?:/|$)/#$1#;
|
||||
HANDLER->tsv->{defaultCondition}->{$portal} ||= sub { 1 };
|
||||
|
||||
1;
|
||||
}
|
||||
|
@ -364,7 +366,7 @@ sub loadPlugin {
|
|||
}
|
||||
my $obj;
|
||||
return 0
|
||||
unless ( $obj = $self->loadModule("$plugin") );
|
||||
unless ( $obj = $self->loadModule("$plugin") );
|
||||
return $self->findEP( $plugin, $obj );
|
||||
}
|
||||
|
||||
|
@ -436,7 +438,7 @@ sub findEP {
|
|||
if ( $obj->can('spRules') ) {
|
||||
foreach my $k ( keys %{ $obj->{spRules} } ) {
|
||||
$self->logger->info(
|
||||
"$k is defined more than one time, it can have some bad effect on Menu display"
|
||||
"$k is defined more than one time, it can have some bad effect on Menu display"
|
||||
) if ( $self->spRules->{$k} );
|
||||
$self->spRules->{$k} = $obj->{spRules}->{$k};
|
||||
}
|
||||
|
|
|
@ -39,13 +39,13 @@ sub _addRoute {
|
|||
return sub {
|
||||
shift;
|
||||
return $sub->( $self, @_ );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return sub {
|
||||
shift;
|
||||
return $self->$sub(@_);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
$self->p->$type( $word, $subName, $methods, $transform );
|
||||
|
@ -57,21 +57,6 @@ sub loadTemplate {
|
|||
return $self->p->loadTemplate(@_);
|
||||
}
|
||||
|
||||
sub accessCtrl {
|
||||
my ( $self, $req, $uri ) = @_;
|
||||
my $url = $self->conf->{portal} . $uri;
|
||||
$self->logger->debug("Plugin calls accessCtrl for URL: $url");
|
||||
|
||||
# Check access rule
|
||||
my ( $vhost, $appuri ) = $url =~ m#^https?://([^/]*)(.*)#;
|
||||
$vhost =~ s/:\d+$//;
|
||||
$appuri ||= '/';
|
||||
$self->logger->debug(
|
||||
"grant function call with VH: $vhost and URI: $appuri");
|
||||
return $self->p->HANDLER->grant( $req, $req->{userData}, $appuri,
|
||||
undef, $vhost );
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ our @pList = (
|
|||
checkState => '::Plugins::CheckState',
|
||||
portalForceAuthn => '::Plugins::ForceAuthn',
|
||||
checkUser => '::Plugins::CheckUser',
|
||||
impersonationRule => '::Plugins::Impersonation',
|
||||
);
|
||||
|
||||
##@method list enabledPlugins
|
||||
|
|
|
@ -3,9 +3,10 @@ package Lemonldap::NG::Portal::Plugins::CheckUser;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_BADCREDENTIALS
|
||||
PE_TOKENEXPIRED
|
||||
PE_NOTOKEN
|
||||
PE_BADCREDENTIALS
|
||||
PE_TOKENEXPIRED
|
||||
PE_NOTOKEN
|
||||
PE_MALFORMEDUSER
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.3';
|
||||
|
@ -18,8 +19,8 @@ has ott => (
|
|||
is => 'rw',
|
||||
lazy => 1,
|
||||
default => sub {
|
||||
my $ott = $_[0]->{p}
|
||||
->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken');
|
||||
my $ott =
|
||||
$_[0]->{p}->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken');
|
||||
$ott->timeout( $_[0]->{conf}->{formTimeout} );
|
||||
return $ott;
|
||||
}
|
||||
|
@ -27,7 +28,7 @@ has ott => (
|
|||
|
||||
sub hAttr {
|
||||
$_[0]->{conf}->{checkUserHiddenAttributes} . ' '
|
||||
. $_[0]->{conf}->{hiddenAttributes};
|
||||
. $_[0]->{conf}->{hiddenAttributes};
|
||||
}
|
||||
|
||||
sub init {
|
||||
|
@ -44,28 +45,43 @@ sub check {
|
|||
my ( $attrs, $array_attrs, $array_hdrs ) = ( {}, [], [] );
|
||||
my $msg = my $auth = '';
|
||||
|
||||
# Check access rule
|
||||
unless ( $self->accessCtrl( $req, 'checkuser' ) ) {
|
||||
$self->userLogger->error(
|
||||
"user $req->{user} not allowed to access /checkuser");
|
||||
return $self->p->lmError( $req, 403 );
|
||||
}
|
||||
$self->userLogger->notice(
|
||||
"user $req->{user} is allowed to access /checkuser");
|
||||
|
||||
# Check token
|
||||
if ( $self->conf->{requireToken} ) {
|
||||
my $token = $req->param('token');
|
||||
unless ($token) {
|
||||
$self->userLogger->warn('CheckUser try without token');
|
||||
$msg = PE_NOTOKEN;
|
||||
$token = $self->ott->createToken( $req->sessionInfo );
|
||||
$token = $self->ott->createToken( $req->userData );
|
||||
}
|
||||
unless ( $self->ott->getToken($token) ) {
|
||||
$self->userLogger->warn('Checkuser try with expired/bad token');
|
||||
$msg = PE_TOKENEXPIRED;
|
||||
$token = $self->ott->createToken( $req->sessionInfo );
|
||||
$token = $self->ott->createToken( $req->userData );
|
||||
}
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => "PE$msg",
|
||||
ALERTE => 'alert-warning',
|
||||
TOKEN => $token,
|
||||
};
|
||||
return $self->p->sendJSONresponse( $req, $params )
|
||||
if ( $req->wantJSON );
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params, )
|
||||
if $msg;
|
||||
}
|
||||
|
||||
## Check user session datas
|
||||
# Use submitted attribute if exists
|
||||
my $url = $req->param('url') || '';
|
||||
my $user = $req->param('user') || '';
|
||||
|
||||
if ( $user and $user !~ /$self->{conf}->{userControl}/o ) {
|
||||
$user = '';
|
||||
$attrs = {};
|
||||
return $self->p->sendError( $req, 'Malformed user', 400 )
|
||||
if ( $req->wantJSON );
|
||||
return $self->p->sendHtml(
|
||||
$req,
|
||||
'checkuser',
|
||||
|
@ -73,22 +89,36 @@ sub check {
|
|||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => "PE$msg",
|
||||
MSG => 'PE' . PE_MALFORMEDUSER,
|
||||
ALERTE => 'alert-warning',
|
||||
TOKEN => $token,
|
||||
LOGIN => $req->{user},
|
||||
TOKEN => (
|
||||
$self->conf->{requireToken}
|
||||
? $self->ott->createToken( $req->userData )
|
||||
: ''
|
||||
)
|
||||
}
|
||||
) if $msg;
|
||||
);
|
||||
}
|
||||
|
||||
if ( $user eq $req->{user} or !$user ) {
|
||||
$self->userLogger->notice("Retrieve session from Sessions database");
|
||||
$self->userLogger->warn("Using spoofed SSO groups if exist!!!")
|
||||
if ( $self->conf->{impersonationRule} );
|
||||
$attrs = $req->userData;
|
||||
}
|
||||
else {
|
||||
$self->logger->debug("Check requested for $req->{user}");
|
||||
$req->{user} = $user;
|
||||
$self->userLogger->notice(
|
||||
"Retrieve session from userDB and compute Groups & Macros");
|
||||
$attrs = $self->_userDatas($req);
|
||||
}
|
||||
|
||||
## Check user session datas
|
||||
# Use submitted attribute if exists
|
||||
my $url = $req->param('url') || '';
|
||||
$req->{user} = $req->param('user') if ( $req->param('user') );
|
||||
$self->logger->debug("Check requested for $req->{user}");
|
||||
$attrs = $self->_userDatas($req);
|
||||
if ( $req->error ) {
|
||||
$msg = 'PE' . $req->{error};
|
||||
$msg = 'PE' . $req->{error};
|
||||
$array_attrs = [ [], [], [] ];
|
||||
$attrs = {};
|
||||
}
|
||||
else {
|
||||
$msg = 'checkUser';
|
||||
|
@ -100,7 +130,7 @@ sub check {
|
|||
|
||||
# Ignore hidden attributes
|
||||
push @$array_attrs, { key => $k, value => $attrs->{$k} }
|
||||
unless ( $self->hAttr =~ /\b$k\b/ );
|
||||
unless ( $self->hAttr =~ /\b$k\b/ );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -108,7 +138,7 @@ sub check {
|
|||
|
||||
# Ignore hidden attributes and empty values
|
||||
push @$array_attrs, { key => $k, value => $attrs->{$k} }
|
||||
unless ( $self->hAttr =~ /\b$k\b/ or !$attrs->{$k} );
|
||||
unless ( $self->hAttr =~ /\b$k\b/ or !$attrs->{$k} );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,87 +150,86 @@ sub check {
|
|||
if ( $url and %$attrs ) {
|
||||
|
||||
# User is allowed ?
|
||||
$url = 'http://' . $url unless ( $url =~ m#^https?://[^/]*.*# );
|
||||
$auth = $self->_authorization( $req, $url );
|
||||
$self->logger->debug(
|
||||
"checkUser requested for user: $req->{user} and URL: $url");
|
||||
$auth = $auth ? "allowed" : "forbidden";
|
||||
$self->userLogger->notice( "checkUser -> $req->{user} is "
|
||||
. uc($auth)
|
||||
. " to access: $url" );
|
||||
if ( $auth >= 0 ) {
|
||||
|
||||
# Return VirtualHost headers
|
||||
$array_hdrs = $self->_headers( $req, $url );
|
||||
$auth = $auth ? "allowed" : "forbidden";
|
||||
$self->userLogger->notice( "checkUser -> $req->{user} is "
|
||||
. uc($auth)
|
||||
. " to access: $url" );
|
||||
|
||||
# Return VirtualHost headers
|
||||
$array_hdrs = $self->_headers( $req, $url );
|
||||
}
|
||||
else {
|
||||
$auth = 'VHnotFound';
|
||||
$self->userLogger->notice(
|
||||
"checkUser -> URL: $url has no configuration");
|
||||
}
|
||||
}
|
||||
|
||||
my $alert_auth = 'alert-warning';
|
||||
if ( $auth eq 'allowed' ) { $alert_auth = 'alert-success' }
|
||||
elsif ( $auth eq 'forbidden' ) { $alert_auth = 'alert-danger' }
|
||||
|
||||
# TODO:
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => $msg,
|
||||
ALERTE => ( $msg eq 'checkUser' ? 'alert-info' : 'alert-warning' ),
|
||||
LOGIN => (
|
||||
$self->p->checkXSSAttack( 'LOGIN', $req->{user} ) ? ""
|
||||
: $req->{user}
|
||||
),
|
||||
URL => (
|
||||
$self->p->checkXSSAttack( 'URL', $url ) ? ""
|
||||
: $url
|
||||
),
|
||||
ALLOWED => $auth,
|
||||
ALERTE_AUTH => $alert_auth,
|
||||
HEADERS => $array_hdrs,
|
||||
ATTRIBUTES => $array_attrs->[2],
|
||||
MACROS => $array_attrs->[1],
|
||||
GROUPS => $array_attrs->[0],
|
||||
TOKEN => (
|
||||
$self->conf->{requireToken}
|
||||
? $self->ott->createToken( $req->userData )
|
||||
: ''
|
||||
)
|
||||
};
|
||||
return $self->p->sendJSONresponse( $req, $params ) if ( $req->wantJSON );
|
||||
|
||||
# Display form
|
||||
return $self->p->sendHtml(
|
||||
$req,
|
||||
'checkuser',
|
||||
params => {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => $msg,
|
||||
ALERTE =>
|
||||
( $msg eq 'checkUser' ? 'alert-info' : 'alert-warning' ),
|
||||
LOGIN => (
|
||||
$self->p->checkXSSAttack( 'LOGIN', $req->{user} ) ? ""
|
||||
: $req->{user}
|
||||
),
|
||||
URL => (
|
||||
$self->p->checkXSSAttack( 'URL', $url ) ? ""
|
||||
: $url
|
||||
),
|
||||
ALLOWED => $auth,
|
||||
ALERTE_AUTH =>
|
||||
( $auth eq 'allowed' ? 'alert-success' : 'alert-danger' ),
|
||||
HEADERS => $array_hdrs,
|
||||
ATTRIBUTES => $array_attrs->[2],
|
||||
MACROS => $array_attrs->[1],
|
||||
GROUPS => $array_attrs->[0],
|
||||
TOKEN => (
|
||||
$self->conf->{requireToken}
|
||||
? $self->ott->createToken( $req->sessionInfo )
|
||||
: ''
|
||||
)
|
||||
}
|
||||
);
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params, );
|
||||
}
|
||||
|
||||
sub display {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
# Check access rule
|
||||
unless ( $self->accessCtrl( $req, 'checkuser' ) ) {
|
||||
$self->userLogger->error(
|
||||
"user $req->{user} not allowed to access /checkuser");
|
||||
return $self->p->lmError( $req, 403 );
|
||||
}
|
||||
$self->userLogger->notice(
|
||||
"user $req->{user} is allowed to access /checkuser");
|
||||
|
||||
# Display form
|
||||
return $self->p->sendHtml(
|
||||
$req,
|
||||
'checkuser',
|
||||
params => {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => 'checkUser',
|
||||
ALERTE => 'alert-info',
|
||||
LOGIN => (
|
||||
$self->p->checkXSSAttack( 'LOGIN', $req->{user} )
|
||||
? ""
|
||||
: $req->{user}
|
||||
),
|
||||
TOKEN => (
|
||||
$self->conf->{requireToken}
|
||||
? $self->ott->createToken( $req->sessionInfo )
|
||||
: ''
|
||||
)
|
||||
}
|
||||
);
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => 'checkUser',
|
||||
ALERTE => 'alert-info',
|
||||
LOGIN => (
|
||||
$self->p->checkXSSAttack( 'LOGIN', $req->{user} ) ? ""
|
||||
: $req->{user}
|
||||
),
|
||||
TOKEN => (
|
||||
$self->conf->{requireToken}
|
||||
? $self->ott->createToken( $req->userData )
|
||||
: ''
|
||||
)
|
||||
};
|
||||
return $self->sendJSONresponse( $req, $params ) if ( $req->wantJSON );
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params, );
|
||||
}
|
||||
|
||||
sub _userDatas {
|
||||
|
@ -209,14 +238,13 @@ sub _userDatas {
|
|||
# Search user in database
|
||||
my $steps = [ 'getUser', 'setSessionInfo', 'setMacros', 'setGroups' ];
|
||||
$self->conf->{checkUserDisplayPersistentInfo}
|
||||
? push @$steps, 'setPersistentSessionInfo', 'setLocalGroups'
|
||||
: push @$steps, 'setLocalGroups';
|
||||
? push @$steps, 'setPersistentSessionInfo', 'setLocalGroups'
|
||||
: push @$steps, 'setLocalGroups';
|
||||
$req->steps($steps);
|
||||
if ( my $error = $self->p->process($req) ) {
|
||||
if ( $error == PE_BADCREDENTIALS ) {
|
||||
$self->userLogger->warn( 'Check requested for an unvalid user ('
|
||||
. $req->{user}
|
||||
. ")" );
|
||||
$self->userLogger->warn(
|
||||
'Check requested for an unvalid user (' . $req->{user} . ")" );
|
||||
}
|
||||
$self->logger->debug("Process returned error: $error");
|
||||
return $req->error($error);
|
||||
|
@ -227,10 +255,21 @@ sub _userDatas {
|
|||
sub _authorization {
|
||||
my ( $self, $req, $uri ) = @_;
|
||||
my ( $vhost, $appuri ) = $uri =~ m#^https?://([^/]*)(.*)#;
|
||||
my $exist = 0;
|
||||
$vhost =~ s/:\d+$//;
|
||||
$appuri ||= '/';
|
||||
return $self->p->HANDLER->grant( $req, $req->{sessionInfo}, $appuri,
|
||||
undef, $vhost );
|
||||
|
||||
foreach my $vh ( keys %{ $self->conf->{locationRules} } ) {
|
||||
if ( $vh eq $vhost ) {
|
||||
$exist = 1;
|
||||
$self->logger->debug("VirtualHost: $vh found in Conf");
|
||||
last;
|
||||
}
|
||||
}
|
||||
return $exist
|
||||
? $self->p->HANDLER->grant( $req, $req->{userData}, $appuri,
|
||||
undef, $vhost )
|
||||
: -1;
|
||||
}
|
||||
|
||||
sub _headers {
|
||||
|
@ -239,7 +278,7 @@ sub _headers {
|
|||
$vhost =~ s/:\d+$//;
|
||||
$req->{env}->{HTTP_HOST} = $vhost;
|
||||
$self->p->HANDLER->headersInit( $self->{conf} );
|
||||
return $self->p->HANDLER->checkHeaders( $req, $req->{sessionInfo} );
|
||||
return $self->p->HANDLER->checkHeaders( $req, $req->{userData} );
|
||||
}
|
||||
|
||||
sub _splitAttributes {
|
||||
|
@ -249,7 +288,9 @@ sub _splitAttributes {
|
|||
$self->logger->debug("Dispatching attributes...");
|
||||
while (@$attrs) {
|
||||
my $element = shift @$attrs;
|
||||
my $ok = 0;
|
||||
$self->logger->debug(
|
||||
'Processing element: ' . Data::Dumper::Dumper($element) );
|
||||
my $ok = 0;
|
||||
if ( $element->{key} eq 'groups' ) {
|
||||
$self->logger->debug('Key "groups" found');
|
||||
my $separator = $self->{conf}->{multiValuesSeparator};
|
||||
|
@ -257,11 +298,14 @@ sub _splitAttributes {
|
|||
$grps = [ map { { value => $_ } } sort @tmp ];
|
||||
next;
|
||||
}
|
||||
foreach my $key ( sort keys %$macros ) {
|
||||
if ( $element->{key} eq $key ) {
|
||||
push @$mcrs, $element;
|
||||
$ok = 1;
|
||||
last;
|
||||
if (%$macros) {
|
||||
foreach my $key ( sort keys %$macros ) {
|
||||
if ( $element->{key} eq $key ) {
|
||||
$self->logger->debug('Macro found');
|
||||
push @$mcrs, $element;
|
||||
$ok = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
push @$others, $element unless $ok;
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
package Lemonldap::NG::Portal::Plugins::Impersonation;
|
||||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Main::Constants
|
||||
qw( PE_OK PE_BADCREDENTIALS PE_IMPERSONATION_SERVICE_NOT_ALLOWED PE_MALFORMEDUSER );
|
||||
|
||||
our $VERSION = '2.0.3';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
use constant endAuth => 'run';
|
||||
|
||||
has rule => ( is => 'rw', default => sub { 1 } );
|
||||
|
||||
sub hAttr {
|
||||
$_[0]->{conf}->{impersonationHiddenAttributes} . ' '
|
||||
. $_[0]->{conf}->{hiddenAttributes};
|
||||
}
|
||||
|
||||
sub init {
|
||||
my ($self) = @_;
|
||||
|
||||
# Parse activation rule
|
||||
my $hd = $self->p->HANDLER;
|
||||
$self->logger->debug(
|
||||
"impersonation rule -> " . $self->conf->{impersonationRule} );
|
||||
my $rule =
|
||||
$hd->buildSub( $hd->substitute( $self->conf->{impersonationRule} ) );
|
||||
unless ($rule) {
|
||||
$self->error( "Bad impersonation rule -> " . $hd->tsv->{jail}->error );
|
||||
return 0;
|
||||
}
|
||||
$self->{rule} = $rule;
|
||||
return 1;
|
||||
}
|
||||
|
||||
# RUNNING METHOD
|
||||
|
||||
sub run {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $spoofId = $req->param('spoofId') || '';
|
||||
if ( $spoofId
|
||||
and $req->param('spoofId') !~ /$self->{conf}->{userControl}/o )
|
||||
{
|
||||
return PE_MALFORMEDUSER;
|
||||
}
|
||||
|
||||
# Skip if no submitted SpoofId
|
||||
return PE_OK unless $spoofId;
|
||||
|
||||
# Check activation rule
|
||||
unless ( $self->rule->( $req, $req->sessionInfo ) ) {
|
||||
$self->userLogger->error('Impersonation service not authorized');
|
||||
return PE_IMPERSONATION_SERVICE_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
# Fill spoof session
|
||||
my ( $realSession, $spoofSession ) = ( {}, {} );
|
||||
$self->logger->debug("Spoofing Id: $spoofId...");
|
||||
my $spk = '';
|
||||
foreach my $k ( keys %{ $req->{sessionInfo} } ) {
|
||||
if ( $self->{conf}->{impersonationSkipEmptyValues} ) {
|
||||
next unless defined $req->{sessionInfo}->{$k};
|
||||
}
|
||||
$spk = "$self->{conf}->{impersonationPrefix}$k";
|
||||
unless ( $self->hAttr =~ /\b$k\b/ ) {
|
||||
$realSession->{$spk} = $req->{sessionInfo}->{$k};
|
||||
$self->logger->debug("-> Store $k in realSession key: $spk");
|
||||
}
|
||||
$self->logger->debug("Delete $k");
|
||||
delete $req->{sessionInfo}->{$k};
|
||||
}
|
||||
$req->{user} = $spoofId;
|
||||
$spoofSession = $self->_userDatas($req);
|
||||
$spoofSession->{groups} ||= '';
|
||||
|
||||
# Merging SSO groups and hGroups & Dedup
|
||||
if ( $self->{conf}->{impersonationMergeSSOgroups} ) {
|
||||
$self->userLogger->warn("MERGING SSO groups and hGroups...");
|
||||
my $spg = "$self->{conf}->{impersonationPrefix}groups";
|
||||
my $sphg = "$self->{conf}->{impersonationPrefix}hGroups";
|
||||
my $separator = $self->{conf}->{multiValuesSeparator};
|
||||
$realSession->{$spg} ||= '';
|
||||
|
||||
$self->logger->debug("Processing groups...");
|
||||
my @spoofGrps = my @realGrps = ();
|
||||
@spoofGrps = split /\Q$separator/, $spoofSession->{groups};
|
||||
@realGrps = split /\Q$separator/, $realSession->{$spg};
|
||||
@spoofGrps = ( @spoofGrps, @realGrps );
|
||||
my %hash = map { $_, 1 } @spoofGrps;
|
||||
$spoofSession->{groups} = join $separator, sort keys %hash;
|
||||
|
||||
$self->logger->debug("Processing hGroups...");
|
||||
$spoofSession->{hGroups} ||= {};
|
||||
$realSession->{$sphg} ||= {};
|
||||
$spoofSession->{hGroups} =
|
||||
{ %{ $spoofSession->{hGroups} }, %{ $realSession->{$sphg} } };
|
||||
}
|
||||
|
||||
# Create spoofed session
|
||||
foreach (qw (_auth _userDB)) {
|
||||
$self->logger->debug("Processing $_...");
|
||||
$spk = "$self->{conf}->{impersonationPrefix}$_";
|
||||
$spoofSession->{$_} = $realSession->{$spk};
|
||||
}
|
||||
$spoofSession = { %$spoofSession, %$realSession };
|
||||
|
||||
# Main session
|
||||
$self->p->updateSession( $req, $spoofSession );
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
sub _userDatas {
|
||||
my ( $self, $req ) = @_;
|
||||
$req->{sessionInfo} = {};
|
||||
|
||||
# Search user in database
|
||||
$req->steps( [
|
||||
'getUser', 'setSessionInfo',
|
||||
'setMacros', 'setGroups',
|
||||
'setLocalGroups'
|
||||
]
|
||||
);
|
||||
if ( my $error = $self->p->process($req) ) {
|
||||
if ( $error == PE_BADCREDENTIALS ) {
|
||||
$self->userLogger->warn(
|
||||
'Impersonation requested for an unvalid user ('
|
||||
. $req->{user}
|
||||
. ")" );
|
||||
}
|
||||
$self->logger->debug("Process returned error: $error");
|
||||
return $req->error($error);
|
||||
}
|
||||
$self->logger->debug("Populating spoofed session...");
|
||||
return $req->{sessionInfo};
|
||||
}
|
||||
|
||||
1;
|
|
@ -154,4 +154,8 @@ div.oidc_consent_message > ul {
|
|||
|
||||
.nodecor:hover, .nodecor:active.nodecor:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fa.icon-blue {
|
||||
color: blue;
|
||||
}
|
|
@ -1 +1 @@
|
|||
html,body{height:100%;background:radial-gradient(circle at 50% 0,#fff 0,#ddd 100%) no-repeat scroll 0 0 #ddd}#wrap{min-height:100%;height:auto;margin:0 auto -80px;padding:20px 0 80px}#footer{height:80px;background-color:#fff;background-color:rgba(255,255,255,0.9);text-align:center;padding-top:10px;overflow:hidden}#header img{background-color:#fff;background-color:rgba(255,255,255,0.8);margin-bottom:20px}.card,.navbar-light{background-color:#fff;background-color:rgba(255,255,255,0.9);background-image:none}.login,.password{text-align:center;padding:20px}div.form{margin:0 auto;max-width:330px}div.actions{margin:10px 0 0 0}div.actions a{margin-top:10px}.buttons{text-align:center;margin:10px 0 0 0;cursor:pointer}.btn{white-space:normal}.btn span.fa{padding-right:8px}li.ui-state-active{background-color:#fafafa;background-color:rgba(250,250,250,0.9)}#appslist,#password,#loginHistory,#logout,#oidcConsents{margin-top:20px}div.category{margin:10px 0;cursor:grab}div.application{margin:5px 0;overflow:hidden}div.application a,div.application a:hover{text-decoration:none}p.notifCheck label{margin-left:5px;margin-top:3px;display:inline-block}img.langicon{cursor:pointer}button.idploop{max-width:300px}button.idploop img{max-height:30px}div.oidc_consent_message>ul{text-align:left;list-style:circle}@media(min-width:768px){div.application{height:80px}div.application h4.appname{margin:0}#wrap{margin:0 auto -60px}#footer{height:60px}}.hiddenFrame{border:0;display:hidden;margin:0}.noborder{border:0}.max{width:100%}.link{cursor:pointer}.nodecor:hover,.nodecor:active.nodecor:focus{text-decoration:none}
|
||||
html,body{height:100%;background:radial-gradient(circle at 50% 0,#fff 0,#ddd 100%) no-repeat scroll 0 0 #ddd}#wrap{min-height:100%;height:auto;margin:0 auto -80px;padding:20px 0 80px}#footer{height:80px;background-color:#fff;background-color:rgba(255,255,255,0.9);text-align:center;padding-top:10px;overflow:hidden}#header img{background-color:#fff;background-color:rgba(255,255,255,0.8);margin-bottom:20px}.card,.navbar-light{background-color:#fff;background-color:rgba(255,255,255,0.9);background-image:none}.login,.password{text-align:center;padding:20px}div.form{margin:0 auto;max-width:330px}div.actions{margin:10px 0 0 0}div.actions a{margin-top:10px}.buttons{text-align:center;margin:10px 0 0 0;cursor:pointer}.btn{white-space:normal}.btn span.fa{padding-right:8px}li.ui-state-active{background-color:#fafafa;background-color:rgba(250,250,250,0.9)}#appslist,#password,#loginHistory,#logout,#oidcConsents{margin-top:20px}div.category{margin:10px 0;cursor:grab}div.application{margin:5px 0;overflow:hidden}div.application a,div.application a:hover{text-decoration:none}p.notifCheck label{margin-left:5px;margin-top:3px;display:inline-block}img.langicon{cursor:pointer}button.idploop{max-width:300px}button.idploop img{max-height:30px}div.oidc_consent_message>ul{text-align:left;list-style:circle}@media(min-width:768px){div.application{height:80px}div.application h4.appname{margin:0}#wrap{margin:0 auto -60px}#footer{height:60px}}.hiddenFrame{border:0;display:hidden;margin:0}.noborder{border:0}.max{width:100%}.link{cursor:pointer}.nodecor:hover,.nodecor:active.nodecor:focus{text-decoration:none}.fa.icon-blue{color:blue}
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"قبول",
|
||||
"accessDenied":"ليس لديك إذن بالدخول لهذا التطبيق",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Generate new key",
|
||||
"changePwd":"غير كلمة المرور الخاصة بك",
|
||||
"checkLastLogins":"تحقق من آخر تسجيلات دخول الخاصة بي",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"اختر أحد التطبيقات المسموح لك بالدخول إليها",
|
||||
"clickHere":"الرجاء الضغط هنا",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"إعادة تعيين كلمة المرور الخاصة بي",
|
||||
"rightsReloadNeedsLogout":" إعادة تحميل الحقوق تحتاج إلى تسجيل الخروج وتسجيل الدخول مرة أخرى",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"اختر موفر الهوية الخاص بك",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"الخدمة المقدمة من قبل",
|
||||
"sessionsDeleted":"الجلسات التالية تم غلقها",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"جلسة الدخول الموحد غير نشطة",
|
||||
"stayConnected":"ابق على اتصال على هذا الجهاز",
|
||||
"submit":"قدم",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"استخدم اليوبي كي الخاص بك",
|
||||
"value":"Value",
|
||||
"verify":"التحقق",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"انتظر",
|
||||
"warning":"تحذير",
|
||||
"welcomeOnPortal":"مرحبا بك على بوابة إثبات الهوية الآمنة.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"Dieser Dienst benötigt Zwei-Faktor-Authentifizierung. Bitte legen Sie ein Gerät an und gehen dann zum Portal zurück.",
|
||||
"accept":"Akzeptieren",
|
||||
"accessDenied":"Sie haben keine Zugriffsberechtigung für diese Anwendung",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Neuen Schlüssel erzeugen",
|
||||
"changePwd":"Ändere dein Passwort",
|
||||
"checkLastLogins":"Überprüfe meine letzten Logins",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Wählen deinen Ihren zweiten Faktor",
|
||||
"chooseApp":"Wählen Sie eine Anwendung aus, auf die du zugreifen darfst",
|
||||
"clickHere":"Bitte hier klicken",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Mein Passwort zurücksetzen",
|
||||
"rightsReloadNeedsLogout":"Zum Neuladen der Rechte musst du dich ab- und wieder anmelden",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Wähle deinen Identitätsanbieter aus",
|
||||
"service":"Dienst",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Dienst angeboten von",
|
||||
"sessionsDeleted":"Die folgenden Sitzungen wurden geschlossen",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"SSO Sitzung inaktiv",
|
||||
"stayConnected":"Auf diesem Gerät verbunden bleiben",
|
||||
"submit":"Absenden",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"use your Yubikey",
|
||||
"value":"Value",
|
||||
"verify":"Verify",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Warten",
|
||||
"warning":"Warnung",
|
||||
"welcomeOnPortal":"Willkommen in Ihrem gesicherten Authentifizierungsportal.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey": "Generate new key",
|
||||
"changePwd":"Change your password",
|
||||
"checkLastLogins":"Check my last logins",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"clickHere":"Please click here",
|
||||
|
@ -210,7 +211,8 @@
|
|||
"resentConfirm":"Do you want the confirmation mail to be resent?",
|
||||
"resetPwd":"Reset my password",
|
||||
"rightsReloadNeedsLogout": "Rights reloads need to logout and login again",
|
||||
"scope": "Scope",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Select your Identity Provider",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Service provided by",
|
||||
"sessionsDeleted":"The following sessions have been closed",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"SSO session inactive",
|
||||
"stayConnected": "Stay connected on this device",
|
||||
"submit":"Submit",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"use your Yubikey",
|
||||
"value":"Value",
|
||||
"verify": "Verify",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Wait",
|
||||
"warning":"Warning",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Generate new key",
|
||||
"changePwd":"Change your password",
|
||||
"checkLastLogins":"Check my last logins",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"clickHere":"Please click here",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Reset my password",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Select your Identity Provider",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Service provided by",
|
||||
"sessionsDeleted":"The following sessions have been closed",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"SSO session inactive",
|
||||
"stayConnected":"Stay connected on this device",
|
||||
"submit":"Submit",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"use your Yubikey",
|
||||
"value":"Value",
|
||||
"verify":"Verify",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Wait",
|
||||
"warning":"Warning",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Accès non autorisé au service OIDC",
|
||||
"PE91":"Accès non autorisé au service OID",
|
||||
"PE92":"Accès non autorisé au service GET",
|
||||
"PE93":"Accès non autorisé au service d'Usurpation d'Identité",
|
||||
"2fRegRequired":"Ce service requiert une authentification à deux facteurs. Enregistrez un équipement ici et retournez au portail.",
|
||||
"accept":"Accepter",
|
||||
"accessDenied":"Vous n'avez pas les droits d'accès à cette application",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey": "Générer une nouvelle clef",
|
||||
"changePwd":"Changez votre mot de passe",
|
||||
"checkLastLogins":"Voir mes dernières connexions",
|
||||
"checkUser":"Vérifier la session d'un utilisateur",
|
||||
"checkUser":"Vérifier le profil SSO d'un utilisateur",
|
||||
"choose2f":"Choisissez votre second facteur",
|
||||
"chooseApp":"Choisissez une application à laquelle vous êtes autorisé à accéder",
|
||||
"clickHere":"Cliquez ici",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Réinitialiser mon mot de passe",
|
||||
"rightsReloadNeedsLogout": "Le rechargement des droits nécessite une déconnexion",
|
||||
"scope": "Informations",
|
||||
"search":"Chercher",
|
||||
"selectIdP":"Choisissez votre fournisseur d'identité",
|
||||
"service":"Service",
|
||||
"sendPwd":"Envoyez-moi un lien",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Ce service est fourni par",
|
||||
"sessionsDeleted":"Les sessions suivantes ont été fermées",
|
||||
"sfaManager":"Gestionnaire 2ndFA",
|
||||
"spoofId":"Identifiant usurpé",
|
||||
"SSOSessionInactive":"Session SSO inactive",
|
||||
"stayConnected": "Rester connecté sur cet appareil",
|
||||
"submit":"Envoyer",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"Utilisez votre Yubikey",
|
||||
"value":"Valeur",
|
||||
"verify": "Vérifier",
|
||||
"VHnotFound":"Hôte virtuel erroné ou inexistant",
|
||||
"wait":"Attendre",
|
||||
"warning":"Attention",
|
||||
"welcomeOnPortal":"Bienvenue sur votre portail d'authentification sécurisée.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"Questo servizio richiede un'autenticazione a doppio fattore. Registrare un dispositivo ora, quindi tornare al portale.",
|
||||
"accept":"Accetta",
|
||||
"accessDenied":"Non hai un'autorizzazione di accesso per questa applicazione",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Genera nuova chiave",
|
||||
"changePwd":"Cambia la tua password",
|
||||
"checkLastLogins":"Controllare i miei ultimi accessi",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Scegli il tuo secondo fattore",
|
||||
"chooseApp":"Scegli un'applicazione alla quale ti è consentito l'accesso",
|
||||
"clickHere":"Per favore clicka qui",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Reimpostare la password",
|
||||
"rightsReloadNeedsLogout":"Le ricariche dei diritti necessitano di disconnettersi e di riconnettersi",
|
||||
"scope":"Ambito",
|
||||
"search":"Search",
|
||||
"selectIdP":"Seleziona il tuo provider di identità",
|
||||
"service":"Servizio",
|
||||
"sendPwd":"Inviami il link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Servizio offerto da",
|
||||
"sessionsDeleted":"Le sessioni seguenti sono state chiuse",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"Sessione SSO inattiva",
|
||||
"stayConnected":"Resta connesso su questo dispositivo",
|
||||
"submit":"Invia",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"Usa la tua Yubikey",
|
||||
"value":"Value",
|
||||
"verify":"Verifica",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Attendere",
|
||||
"warning":"Avvertimento",
|
||||
"welcomeOnPortal":"Benvenuto sul tuo portale di autenticazione protetta.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Generate new key",
|
||||
"changePwd":"Change your password",
|
||||
"checkLastLogins":"Check my last logins",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"clickHere":"Please click here",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Reset my password",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Select your Identity Provider",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Service provided by",
|
||||
"sessionsDeleted":"The following sessions have been closed",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"SSO session inactive",
|
||||
"stayConnected":"Stay connected on this device",
|
||||
"submit":"Submit",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"use your Yubikey",
|
||||
"value":"Value",
|
||||
"verify":"Verify",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Wait",
|
||||
"warning":"Warning",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Generate new key",
|
||||
"changePwd":"Change your password",
|
||||
"checkLastLogins":"Check my last logins",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"clickHere":"Please click here",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Reset my password",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Select your Identity Provider",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Service provided by",
|
||||
"sessionsDeleted":"The following sessions have been closed",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"SSO session inactive",
|
||||
"stayConnected":"Stay connected on this device",
|
||||
"submit":"Submit",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"use your Yubikey",
|
||||
"value":"Value",
|
||||
"verify":"Verify",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Wait",
|
||||
"warning":"Warning",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Generate new key",
|
||||
"changePwd":"Change your password",
|
||||
"checkLastLogins":"Check my last logins",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"clickHere":"Please click here",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Reset my password",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Select your Identity Provider",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Service provided by",
|
||||
"sessionsDeleted":"The following sessions have been closed",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"SSO session inactive",
|
||||
"stayConnected":"Stay connected on this device",
|
||||
"submit":"Submit",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"use your Yubikey",
|
||||
"value":"Value",
|
||||
"verify":"Verify",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Wait",
|
||||
"warning":"Warning",
|
||||
"welcomeOnPortal":"Welcome on your secured authentication portal.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Chấp nhận",
|
||||
"accessDenied":"Bạn không có quyền truy cập vào ứng dụng này",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Generate new key",
|
||||
"changePwd":"Thay đổi mật khẩu của bạn",
|
||||
"checkLastLogins":"Kiểm tra lần đăng nhập cuối cùng của bạn",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Chọn một ứng dụng bạn được phép truy cập vào",
|
||||
"clickHere":"Vui lòng nhấp vào đây",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"Đặt lại mật khẩu của tôi",
|
||||
"rightsReloadNeedsLogout":"Tải lại quyền cần đăng xuất và đăng nhập lại",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Chọn bộ cung cấp danh tính của bạn",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Dịch vụ được cung cấp bởi",
|
||||
"sessionsDeleted":"Các phiên làm việc sau đã được đóng lại",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"Phiên SSO không hoạt động",
|
||||
"stayConnected":"Giữ kết nối trên thiết bị này",
|
||||
"submit":"Gửi",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"sử dụng Yubikey của bạn",
|
||||
"value":"Value",
|
||||
"verify":"Xác minh",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"Hãy đợi",
|
||||
"warning":"Cảnh báo",
|
||||
"welcomeOnPortal":"Chào mừng bạn đến với cổng thông tin xác thực được bảo mật của bạn.",
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
"PE90":"Access non granted on OIDC service",
|
||||
"PE91":"Access non granted on OID service",
|
||||
"PE92":"Access non granted on GET service",
|
||||
"PE93":"Access non granted on IMPERSONATION service",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept 方法",
|
||||
"accessDenied":"您无权访问此应用",
|
||||
|
@ -116,7 +117,7 @@
|
|||
"changeKey":"Generate new key",
|
||||
"changePwd":"修改您的密码",
|
||||
"checkLastLogins":"Check my last logins",
|
||||
"checkUser":"Check user session",
|
||||
"checkUser":"Check user SSO profile",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"clickHere":"请点击这里",
|
||||
|
@ -211,6 +212,7 @@
|
|||
"resetPwd":"重置我的密码",
|
||||
"rightsReloadNeedsLogout":"Rights reloads need to logout and login again",
|
||||
"scope":"Scope",
|
||||
"search":"Search",
|
||||
"selectIdP":"Select your Identity Provider",
|
||||
"service":"Service",
|
||||
"sendPwd":"Send me a link",
|
||||
|
@ -218,6 +220,7 @@
|
|||
"serviceProvidedBy":"Service provided by",
|
||||
"sessionsDeleted":"The following sessions have been closed",
|
||||
"sfaManager":"2ndFA Manager",
|
||||
"spoofId":"Spoofed Id",
|
||||
"SSOSessionInactive":"SSO session inactive",
|
||||
"stayConnected":"Stay connected on this device",
|
||||
"submit":"提交",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"useYubikey":"使用您的 Yubikey",
|
||||
"value":"Value",
|
||||
"verify":"验证",
|
||||
"VHnotFound":"Virtual Host not found",
|
||||
"wait":"等待",
|
||||
"warning":"警告",
|
||||
"welcomeOnPortal":"欢迎来到您的加密认证 portal",
|
||||
|
@ -254,4 +258,4 @@
|
|||
"yourPhone":"您的电话号码",
|
||||
"yourProfile":"您的档案",
|
||||
"yourTotpKey":"Your TOTP key"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
-->
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE"> alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
|
||||
<form id="checkuser" action="/checkuser" method="post" class="password" role="form">
|
||||
<div class="buttons">
|
||||
|
||||
<TMPL_IF NAME="TOKEN">
|
||||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
|
@ -21,26 +22,23 @@
|
|||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-link"></i> </span>
|
||||
</div>
|
||||
<input name="url" type="text" class="form-control" value="<TMPL_VAR NAME="URL">" trplaceholder="http://auth.example.com" aria-required="true"/>
|
||||
<input name="url" type="text" class="form-control" value="<TMPL_VAR NAME="URL">" trplaceholder="URL / DNS" aria-required="true"/>
|
||||
</div>
|
||||
|
||||
|
||||
<TMPL_IF NAME="ALLOWED">
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE_AUTH">"><span trspan="<TMPL_VAR NAME="ALLOWED">"></span></div>
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="HEADERS">
|
||||
<div class="buttons">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-sign-in"></span>
|
||||
<span trspan="checkUser">Check user</span>
|
||||
<span class="fa fa-search"></span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
</div>
|
||||
<div> </div>
|
||||
|
||||
<TMPL_IF NAME="ALLOWED">
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE_AUTH">"><b><span trspan="<TMPL_VAR NAME="ALLOWED">"></span></b></div>
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="HEADERS">
|
||||
<div class="card mb-3 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><span trspan="headers">HEADERS</span></tr>
|
||||
<tr class="align-middle"><b><span trspan="headers">HEADERS</span></b></tr>
|
||||
<tr>
|
||||
<th class="align-middle"><span trspan="key">Key</span></th>
|
||||
<th class="align-middle"><span trspan="value">Value</span></th>
|
||||
|
@ -62,11 +60,11 @@
|
|||
<div class="container">
|
||||
<div class="row">
|
||||
<TMPL_IF NAME="GROUPS">
|
||||
<div class="card col-md-4 border-secondary">
|
||||
<div class="card col-md-2 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><span trspan="groups_sso">GROUPS SSO</span></tr>
|
||||
<tr class="align-middle"><b><span trspan="groups_sso">SSO GROUPS</span></b></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="GROUPS">
|
||||
|
@ -85,7 +83,7 @@
|
|||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><span trspan="macros">MACROS</span></tr>
|
||||
<tr class="align-middle"><b><span trspan="macros">MACROS</span></b></tr>
|
||||
<tr>
|
||||
<th class="align-middle"><span trspan="key">Key</span></th>
|
||||
<th class="align-middle"><span trspan="value">Value</span></th>
|
||||
|
@ -105,21 +103,21 @@
|
|||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="ATTRIBUTES">
|
||||
<div class="card col-md-4 border-secondary">
|
||||
<div class="card col-md-6 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><span trspan="attributes">ATTRIBUTES</span></tr>
|
||||
<tr class="align-middle"><b><span trspan="attributes">ATTRIBUTES</span></b></tr>
|
||||
<tr>
|
||||
<th class="align-middle"><span trspan="key">Key</span></th>
|
||||
<th class="align-middle"><span trspan="value">Value</span></th>
|
||||
<th class="text-left"><span trspan="key">Key</span></th>
|
||||
<th class="text-left"><span trspan="value">Value</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="ATTRIBUTES">
|
||||
<tr>
|
||||
<td class="align-middle"><TMPL_VAR NAME="key"></td>
|
||||
<td class="align-middle"><TMPL_VAR NAME="value"></td>
|
||||
<td class="text-left"><TMPL_VAR NAME="key"></td>
|
||||
<td class="text-left"><TMPL_VAR NAME="value"></td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
|
@ -131,10 +129,12 @@
|
|||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<!--
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-sign-in"></span>
|
||||
<span trspan="checkUser">Check user</span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
-->
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
</TMPL_IF>
|
||||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<button type="submit" class="btn btn-success" >
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<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 name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<!-- //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" />
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<TMPL_IF NAME="SPOOFID">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-user icon-blue"></i> </span>
|
||||
</div>
|
||||
<input name="spoofId" type="text" class="form-control" trplaceholder="spoofId" aria-required="false"/>
|
||||
</div>
|
||||
</TMPL_IF>
|
|
@ -73,6 +73,8 @@
|
|||
<TMPL_IF NAME="logoFile">
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/modules/<TMPL_VAR NAME="logoFile">" alt="<TMPL_VAR NAME="module">" class="img-thumbnail mb-3" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<div class="buttons">
|
||||
|
@ -200,6 +202,7 @@
|
|||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/modules/<TMPL_VAR NAME="module">.png" alt="<TMPL_VAR NAME="module">" class="img-thumbnail" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<div class="buttons">
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<input name="openid_identifier" type="text" class="form-control" trplaceholder="enterOpenIDLogin" aria-required="true"/>
|
||||
</div>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<button type="submit" class="btn btn-success" >
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/modules/SSL.png" alt="<TMPL_VAR NAME="module">" class="img-thumbnail mb-3" />
|
||||
</div>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<button type="submit" class="btn btn-success sslclick" >
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/modules/SSL.png" alt="<TMPL_VAR NAME="module">" class="img-thumbnail mb-3" />
|
||||
</div>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<button type="submit" class="btn btn-success sslclick" >
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<button type="submit" class="btn btn-success" >
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<input name="yubikeyOTP" type="text" class="form-control" trplaceholder="enterYubikey" aria-required="true" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="checklogins.tpl">
|
||||
|
||||
<button type="submit" class="btn btn-success" >
|
||||
|
|
|
@ -25,11 +25,9 @@ ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu' );
|
|||
ok( $res->[2]->[0] !~ m%<span id="languages"></span>%,
|
||||
' No language icon found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
ok( $res->[2]->[0] =~ m%"trOver"%,
|
||||
' trOver found' )
|
||||
ok( $res->[2]->[0] =~ m%"trOver"%, ' trOver found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
ok( $res->[2]->[0] =~ m%"all":\{\}%,
|
||||
' all found' )
|
||||
ok( $res->[2]->[0] =~ m%"all":\{\}%, ' all found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
ok( $res->[2]->[0] =~ m%"en":\{"PE9":"You are welcome! Please login..."\}%,
|
||||
' en found' )
|
||||
|
@ -40,14 +38,26 @@ ok( $res->[2]->[0] =~ m%"PE0":"Souriez, vous êtes surveillés !"%,
|
|||
ok( $res->[2]->[0] =~ m%"selectIdP":"Portail de Fédération des Identités"%,
|
||||
' selectIdP found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
ok( $res->[2]->[0] =~ m%"fr":\{%,
|
||||
' fr found' )
|
||||
ok( $res->[2]->[0] =~ m%"fr":\{%, ' fr found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
ok( $res->[2]->[0] =~ m%"PE85":"From lemonlap-ng.ini"%,
|
||||
' PE85 found' )
|
||||
ok( $res->[2]->[0] =~ m%"PE85":"From lemonlap-ng.ini"%, ' PE85 found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
count(9);
|
||||
|
||||
# Try yo authenticate
|
||||
# -------------------
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho*&password=dwho'),
|
||||
accept => 'text/html',
|
||||
length => 24
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<span trmsg="40"></span>%, ' PE40 found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
count(2);
|
||||
|
||||
# Try yo authenticate
|
||||
# -------------------
|
||||
|
|
|
@ -13,8 +13,7 @@ SKIP: {
|
|||
skip( 'LLNGTESTLDAP is not set', $maintests ) unless ( $ENV{LLNGTESTLDAP} );
|
||||
require 't/test-ldap.pm';
|
||||
|
||||
my $client = LLNG::Manager::Test->new(
|
||||
{
|
||||
my $client = LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => 'error',
|
||||
useSafeJail => 1,
|
||||
|
|
|
@ -86,7 +86,8 @@ SKIP: {
|
|||
'Post authentication'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ /trmsg="89"/, 'Reject reason is 89' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
|
||||
# Simple SP access
|
||||
ok(
|
||||
$res = $sp->_get(
|
||||
|
|
|
@ -111,7 +111,7 @@ ok(
|
|||
);
|
||||
count(1);
|
||||
ok( $res->[2]->[0] =~ /trmsg="68"/, 'Reject reason is 68' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
count(1);
|
||||
|
||||
# Simple SP access
|
||||
|
@ -143,8 +143,7 @@ $pdata = 'lemonldappdata=' . expectCookie( $res, 'lemonldappdata' );
|
|||
$body = $res->[2]->[0];
|
||||
$body =~ s/^.*?<form.*?>//s;
|
||||
$body =~ s#</form>.*$##s;
|
||||
%fields =
|
||||
( $body =~ /<input type="hidden".+?name="(.+?)".+?value="(.*?)"/sg );
|
||||
%fields = ( $body =~ /<input type="hidden".+?name="(.+?)".+?value="(.*?)"/sg );
|
||||
$fields{user} = $fields{password} = 'french';
|
||||
use URI::Escape;
|
||||
$s = join( '&', map { "$_=" . uri_escape( $fields{$_} ) } keys %fields );
|
||||
|
|
|
@ -114,7 +114,7 @@ ok(
|
|||
);
|
||||
count(1);
|
||||
ok( $res->[2]->[0] =~ /trmsg="90"/, 'Reject reason is 90' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
count(1);
|
||||
|
||||
# Initialization
|
||||
|
|
|
@ -106,7 +106,7 @@ SKIP: {
|
|||
'Try to authenticate'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ /trmsg="91"/, 'Reject reason is 91' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
count(1);
|
||||
|
||||
# Simple SP access
|
||||
|
|
|
@ -45,7 +45,7 @@ ok(
|
|||
);
|
||||
count(1);
|
||||
ok( $res->[2]->[0] =~ /trmsg="92"/, 'Reject reason is 92' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
count(1);
|
||||
|
||||
# Try to authenticate with an authorized user
|
||||
|
|
|
@ -8,34 +8,33 @@ BEGIN {
|
|||
|
||||
my $res;
|
||||
|
||||
my $client = LLNG::Manager::Test->new(
|
||||
{ ini => {
|
||||
logLevel => 'error',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
loginHistoryEnabled => 0,
|
||||
brutForceProtection => 0,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
checkUser => 1,
|
||||
requireToken => 1,
|
||||
formTimeout => 2,
|
||||
my $client = LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => 'error',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
loginHistoryEnabled => 0,
|
||||
brutForceProtection => 0,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
checkUser => 1,
|
||||
requireToken => 1,
|
||||
formTimeout => 2,
|
||||
checkUserDisplayPersistentInfo => 1,
|
||||
checkUserDisplayEmptyValues => 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
## Try to authenticate
|
||||
ok( $res = $client->_get( '/', accept => 'text/html' ),
|
||||
'Get Menu', );
|
||||
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
|
||||
count(1);
|
||||
my ( $host, $url, $query ) =
|
||||
expectForm( $res, '#', undef, 'user', 'password', 'token' );
|
||||
|
||||
$query =~ s/user=/user=dwho/;
|
||||
$query =~ s/password=/password=dwho/;
|
||||
ok( $res = $client->_post(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new($query),
|
||||
length => length($query),
|
||||
|
@ -50,7 +49,8 @@ expectRedirection( $res, 'http://auth.example.com/' );
|
|||
|
||||
# CheckUser form
|
||||
# ------------------------
|
||||
ok( $res = $client->_get(
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/checkuser',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
|
@ -58,11 +58,10 @@ ok( $res = $client->_get(
|
|||
'CheckUser form',
|
||||
);
|
||||
count(1);
|
||||
( $host, $url, $query )
|
||||
= expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%,
|
||||
'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
count(1);
|
||||
|
||||
# Expired token
|
||||
|
@ -70,7 +69,8 @@ sleep 3;
|
|||
$query =~ s/user=dwho/user=rtyler/;
|
||||
$query =~ s/url=/url=http%3A%2F%2Ftest1.example.com/;
|
||||
|
||||
ok( $res = $client->_post(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
|
@ -79,18 +79,18 @@ ok( $res = $client->_post(
|
|||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="PE82"></span>%,
|
||||
'Found PE_TOKENEXPIRED' )
|
||||
or explain( $res->[2]->[0], 'trspan="PE82"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="PE82"></span>%, 'Found PE_TOKENEXPIRED' )
|
||||
or explain( $res->[2]->[0], 'trspan="PE82"' );
|
||||
count(2);
|
||||
( $host, $url, $query )
|
||||
= expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
|
||||
|
||||
# Valid token
|
||||
$query =~ s/user=/user=rtyler/;
|
||||
$query =~ s/url=/url=http%3A%2F%2Ftest1.example.com/;
|
||||
$query =~ s/url=/url=test1.example.com/;
|
||||
|
||||
ok( $res = $client->_post(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
|
@ -101,45 +101,45 @@ ok( $res = $client->_post(
|
|||
);
|
||||
count(1);
|
||||
|
||||
( $host, $url, $query )
|
||||
= expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%,
|
||||
'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok( $res->[2]->[0]
|
||||
=~ m%<div class="alert alert-success"><span trspan="allowed"></span></div>%,
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/checkuser', 'user', 'url', 'token' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
or explain( $res->[2]->[0], 'trspan="headers"' );
|
||||
or explain( $res->[2]->[0], 'trspan="headers"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%,
|
||||
'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Macro Value uid' );
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(11);
|
||||
|
||||
$query =~ s/user=dwho/user=msmith/;
|
||||
$query
|
||||
=~ s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Fmanager.example.com%2Fmanager.html/;
|
||||
$query =~
|
||||
s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Fmanager.example.com%2Fmanager.html/;
|
||||
|
||||
ok( $res = $client->_post(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
|
@ -148,8 +148,9 @@ ok( $res = $client->_post(
|
|||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
ok( $res->[2]->[0]
|
||||
=~ m%<div class="alert alert-danger"><span trspan="forbidden"></span></div>%,
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-danger"><b><span trspan="forbidden"></span></b></div>%,
|
||||
'Found trspan="forbidden"'
|
||||
) or explain( $res->[2]->[0], 'trspan="forbidden"' );
|
||||
count(2);
|
||||
|
@ -157,4 +158,4 @@ count(2);
|
|||
$client->logout($id);
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
||||
done_testing( count() );
|
||||
|
|
|
@ -8,16 +8,16 @@ BEGIN {
|
|||
|
||||
my $res;
|
||||
|
||||
my $client = LLNG::Manager::Test->new(
|
||||
{ ini => {
|
||||
logLevel => 'error',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
loginHistoryEnabled => 0,
|
||||
brutForceProtection => 0,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
checkUser => 1,
|
||||
requireToken => 0,
|
||||
my $client = LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => 'error',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
loginHistoryEnabled => 0,
|
||||
brutForceProtection => 0,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
checkUser => 1,
|
||||
requireToken => 0,
|
||||
checkUserDisplayPersistentInfo => 1,
|
||||
checkUserDisplayEmptyValues => 1,
|
||||
}
|
||||
|
@ -25,9 +25,10 @@ my $client = LLNG::Manager::Test->new(
|
|||
);
|
||||
|
||||
## Try to authenticate
|
||||
ok( $res = $client->_post(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=rtyler&password=rtyler'),
|
||||
IO::String->new('user=msmith&password=msmith'),
|
||||
length => 27,
|
||||
accept => 'text/html',
|
||||
),
|
||||
|
@ -38,7 +39,8 @@ count(1);
|
|||
my $id = expectCookie($res);
|
||||
expectRedirection( $res, 'http://auth.example.com/' );
|
||||
|
||||
ok( $res = $client->_get(
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/checkuser',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
|
@ -47,17 +49,16 @@ ok( $res = $client->_get(
|
|||
);
|
||||
count(1);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<img src="/static/common/logos/logo_llng_old.png"%,
|
||||
'Found custom Main Logo' )
|
||||
or explain( $res->[2]->[0], 'custom Main logo not found"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="accessDenied">%,
|
||||
'Found trspan="accessDenied"' )
|
||||
or explain( $res->[2]->[0], 'trspan="accessDenied"' );
|
||||
count(2);
|
||||
ok( $res->[2]->[0] =~ m%An error occurs, you're going to be redirected to%,
|
||||
'Found redirection page' )
|
||||
or explain( $res->[2]->[0],
|
||||
"An error occurs, you're going to be redirected to" );
|
||||
count(1);
|
||||
$client->logout($id);
|
||||
|
||||
## Try to authenticate
|
||||
ok( $res = $client->_post(
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho&password=dwho'),
|
||||
length => 23,
|
||||
|
@ -72,7 +73,8 @@ expectRedirection( $res, 'http://auth.example.com/' );
|
|||
|
||||
# CheckUser form -> granted
|
||||
# ------------------------
|
||||
ok( $res = $client->_get(
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/checkuser',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
|
@ -80,17 +82,18 @@ ok( $res = $client->_get(
|
|||
'CheckUser form',
|
||||
);
|
||||
count(1);
|
||||
my ( $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"' );
|
||||
|
||||
# Request with bad VH
|
||||
my ( $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"' );
|
||||
count(1);
|
||||
|
||||
$query =~ s/user=dwho/user=rtyler/;
|
||||
$query =~ s/url=/url=http%3A%2F%2Ftest1.example.com/;
|
||||
|
||||
ok( $res = $client->_post(
|
||||
$query =~ s/url=/url=http%3A%2F%2Ftry.example.com/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
|
@ -101,50 +104,75 @@ ok( $res = $client->_post(
|
|||
);
|
||||
count(1);
|
||||
|
||||
( $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"' );
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/checkuser', 'user', 'url' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="VHnotFound">%,
|
||||
'Found trspan="VHnotFound"' )
|
||||
or explain( $res->[2]->[0], 'trspan="VHnotFound"' );
|
||||
count(1);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%,
|
||||
'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok( $res->[2]->[0]
|
||||
=~ m%<div class="alert alert-success"><span trspan="allowed"></span></div>%,
|
||||
( $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"' );
|
||||
count(1);
|
||||
|
||||
$query =~
|
||||
s/url=http%3A%2F%2Ftry.example.com/url=http%3A%2F%2Ftest1.example.com/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
count(1);
|
||||
|
||||
( $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"' );
|
||||
count(1);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
or explain( $res->[2]->[0], 'trspan="headers"' );
|
||||
or explain( $res->[2]->[0], 'trspan="headers"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%,
|
||||
'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Macro Value uid' );
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(11);
|
||||
|
||||
$query =~ s/user=dwho/user=msmith/;
|
||||
$query
|
||||
=~ s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Fmanager.example.com%2Fmanager.html/;
|
||||
|
||||
ok( $res = $client->_post(
|
||||
$query =~
|
||||
s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Fmanager.example.com%2Fmanager.html/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
|
@ -153,8 +181,9 @@ ok( $res = $client->_post(
|
|||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
ok( $res->[2]->[0]
|
||||
=~ m%<div class="alert alert-danger"><span trspan="forbidden"></span></div>%,
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-danger"><b><span trspan="forbidden"></span></b></div>%,
|
||||
'Found trspan="forbidden"'
|
||||
) or explain( $res->[2]->[0], 'trspan="forbidden"' );
|
||||
count(2);
|
||||
|
@ -162,4 +191,4 @@ count(2);
|
|||
$client->logout($id);
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
||||
done_testing( count() );
|
||||
|
|
121
lemonldap-ng-portal/t/68-Impersonation-with-merge.t
Normal file
121
lemonldap-ng-portal/t/68-Impersonation-with-merge.t
Normal file
|
@ -0,0 +1,121 @@
|
|||
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 => 0,
|
||||
brutForceProtection => 0,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
requireToken => 0,
|
||||
checkUser => 1,
|
||||
impersonationRule => 1,
|
||||
checkUserDisplayPersistentInfo => 0,
|
||||
checkUserDisplayEmptyValues => 0,
|
||||
impersonationMergeSSOgroups => 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
## Try to authenticate
|
||||
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
|
||||
count(1);
|
||||
my ( $host, $url, $query ) =
|
||||
expectForm( $res, '#', undef, 'user', 'password', 'spoofId' );
|
||||
|
||||
$query =~ s/user=/user=rtyler/;
|
||||
$query =~ s/password=/password=rtyler/;
|
||||
$query =~ s/spoofId=/spoofId=dwho/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new($query),
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
count(1);
|
||||
|
||||
my $id = expectCookie($res);
|
||||
expectRedirection( $res, 'http://auth.example.com/' );
|
||||
|
||||
# CheckUser form
|
||||
# ------------------------
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/checkuser',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'CheckUser form',
|
||||
);
|
||||
count(1);
|
||||
( $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"' );
|
||||
count(1);
|
||||
|
||||
$query =~ s/url=/url=test1.example.com/;
|
||||
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
count(1);
|
||||
|
||||
( $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"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
or explain( $res->[2]->[0], 'trspan="headers"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_userDB</td>%, 'Found _userDB' )
|
||||
or explain( $res->[2]->[0], '_userDB' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(12);
|
||||
|
||||
$client->logout($id);
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
154
lemonldap-ng-portal/t/68-Impersonation.t
Normal file
154
lemonldap-ng-portal/t/68-Impersonation.t
Normal file
|
@ -0,0 +1,154 @@
|
|||
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 => 0,
|
||||
brutForceProtection => 0,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
requireToken => 0,
|
||||
checkUser => 1,
|
||||
impersonationRule => 1,
|
||||
checkUserDisplayPersistentInfo => 0,
|
||||
checkUserDisplayEmptyValues => 0,
|
||||
impersonationMergeSSOgroups => 0,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
## Try to authenticate with bad spoofed user
|
||||
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
|
||||
count(1);
|
||||
my ( $host, $url, $query ) =
|
||||
expectForm( $res, '#', undef, 'user', 'password', 'spoofId' );
|
||||
|
||||
$query =~ s/user=/user=rtyler/;
|
||||
$query =~ s/password=/password=rtyler/;
|
||||
$query =~ s/spoofId=/spoofId=dwho*/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new($query),
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<span trmsg="40"></span>%, ' PE40 found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
count(2);
|
||||
|
||||
my $id = expectCookie($res);
|
||||
$client->logout($id);
|
||||
|
||||
## Try to authenticate
|
||||
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
|
||||
count(1);
|
||||
my ( $host, $url, $query ) =
|
||||
expectForm( $res, '#', undef, 'user', 'password', 'spoofId' );
|
||||
|
||||
$query =~ s/user=/user=rtyler/;
|
||||
$query =~ s/password=/password=rtyler/;
|
||||
$query =~ s/spoofId=/spoofId=dwho/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new($query),
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
count(1);
|
||||
|
||||
$id = expectCookie($res);
|
||||
expectRedirection( $res, 'http://auth.example.com/' );
|
||||
|
||||
# CheckUser form
|
||||
# ------------------------
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/checkuser',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'CheckUser form',
|
||||
);
|
||||
count(1);
|
||||
( $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"' );
|
||||
count(1);
|
||||
|
||||
$query =~ s/url=/url=test1.example.com/;
|
||||
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/checkuser',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
count(1);
|
||||
|
||||
( $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"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
or explain( $res->[2]->[0], 'trspan="headers"' );
|
||||
|
||||
ok( $res->[2]->[0] !~ m%<span trspan="groups_sso">%,
|
||||
'trspan="groups_sso" NOT found' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_userDB</td>%, 'Found _userDB' )
|
||||
or explain( $res->[2]->[0], '_userDB' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">real_groups</td>%,
|
||||
'Found real_groups' )
|
||||
or explain( $res->[2]->[0], 'real_groups' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">su</td>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">real_uid</td>%, 'Found real_uid' )
|
||||
or explain( $res->[2]->[0], 'real_groups' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">rtyler</td>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'su' );
|
||||
count(14);
|
||||
|
||||
$client->logout($id);
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
|
@ -10,12 +10,12 @@ count(1);
|
|||
|
||||
my $client = LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => 'error',
|
||||
ext2fActivation => 1,
|
||||
ext2fCodeActivation => 'A1b2C0',
|
||||
ext2FSendCommand => 't/sendCode.pl -uid $uid -code $code',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
logLevel => 'error',
|
||||
ext2fActivation => 1,
|
||||
ext2fCodeActivation => 'A1b2C0',
|
||||
ext2FSendCommand => 't/sendCode.pl -uid $uid -code $code',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Same',
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -35,8 +35,9 @@
|
|||
"key": "qwertyui",
|
||||
"locationRules": {
|
||||
"auth.example.com" : {
|
||||
"(?#checkUser)/checkuser" : "$uid eq \"dwho\"",
|
||||
"default" : "deny"
|
||||
"(?#checkUser)^/checkuser" : "$uid eq \"dwho\" or $uid eq \"rtyler\"",
|
||||
"(?#errors)^/lmerror/": "accept",
|
||||
"default" : "accept"
|
||||
},
|
||||
"manager.example.com": {
|
||||
"(?#Configuration)^/(manager\\.html|conf/)": "$uid eq \"dwho\"",
|
||||
|
|
|
@ -4,4 +4,7 @@ use warnings;
|
|||
|
||||
my ( $swt1, $user, $swt2, $code ) = @ARGV;
|
||||
|
||||
exit !( $swt1 eq '-uid' && $user eq 'dwho' && $swt2 eq '-code' && defined $code );
|
||||
exit !($swt1 eq '-uid'
|
||||
&& $user eq 'dwho'
|
||||
&& $swt2 eq '-code'
|
||||
&& defined $code );
|
||||
|
|
Loading…
Reference in New Issue
Block a user