Merge branch 'v2.0'
This commit is contained in:
commit
3f7ae26d49
6
COPYING
6
COPYING
|
@ -115,6 +115,12 @@ License: CC-3
|
|||
Comment: This work, "star1.png", is a derivative of
|
||||
"Golden star with red border.png" by ANGELUS, under CC-BYSA-3.0.
|
||||
|
||||
Files: lemonldap-ng-portal/site/htdocs/static/common/icons/decryptValue.png
|
||||
Copyright: Christophe Maudoux <chrmdx@gmail.com>
|
||||
License: CC-3
|
||||
Comment: This work, "decryptValue.png", is a derivative of
|
||||
"secure.png" by Austin Condiff, under CC-BY-3.0.
|
||||
|
||||
Files: lemonldap-ng-portal/site/htdocs/static/common/icons/switchcontext_OFF.png
|
||||
Copyright: Christophe Maudoux <chrmdx@gmail.com>
|
||||
License: CC-4
|
||||
|
|
|
@ -62,12 +62,12 @@ sub retrieveSession {
|
|||
}
|
||||
|
||||
## @rmethod protected boolean createSession(id)
|
||||
# Ask portal to create it through a SOAP request
|
||||
# Send a create session request to the Portal
|
||||
# @return true if the session is created, else false
|
||||
sub createSession {
|
||||
my ( $class, $req, $id ) = @_;
|
||||
|
||||
# Add client IP as X-Forwarded-For IP in SOAP request
|
||||
# Add client IP as X-Forwarded-For IP in request
|
||||
my $xheader = $req->env->{'HTTP_X_FORWARDED_FOR'};
|
||||
$xheader .= ", " if ($xheader);
|
||||
$xheader .= $req->{env}->{REMOTE_ADDR};
|
||||
|
@ -149,7 +149,7 @@ sub hideCookie {
|
|||
# else redirect him to the portal to display some message defined by $arg
|
||||
# @param $url Url requested
|
||||
# @param $arg optionnal GET parameters
|
||||
# @return Apache2::Const::REDIRECT or Apache2::Const::AUTH_REQUIRED
|
||||
# @return AUTH_REDIRECT or AUTH_REQUIRED constant
|
||||
sub goToPortal {
|
||||
my ( $class, $req, $url, $arg ) = @_;
|
||||
if ($arg) {
|
||||
|
@ -171,7 +171,6 @@ sub ua {
|
|||
lwpSslOpts => $class->tsv->{lwpSslOpts}
|
||||
}
|
||||
);
|
||||
|
||||
return $_ua;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ sub fetchId {
|
|||
my ( $t, $_session_id, @vhosts ) = split /:/, $s;
|
||||
|
||||
# Looking for service headers
|
||||
my $vh = $class->resolveAlias($req);
|
||||
my $vhost = $class->resolveAlias($req);
|
||||
my %serviceHeaders;
|
||||
@vhosts = grep {
|
||||
if (/^([\w\-]+)=(.+)$/) {
|
||||
|
@ -32,27 +32,31 @@ sub fetchId {
|
|||
# $_session_id and at least one vhost
|
||||
unless ( @vhosts and $_session_id ) {
|
||||
$class->userLogger->error('Bad service token');
|
||||
$class->logger->debug(
|
||||
@vhosts ? 'No _session_id found' : 'No VH found' );
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Is vhost listed in token ?
|
||||
unless ( grep { $_ eq $vh } @vhosts ) {
|
||||
unless ( grep { $_ eq $vhost } @vhosts ) {
|
||||
$class->userLogger->error(
|
||||
"$vh not authorized in token (" . join( ', ', @vhosts ) . ')' );
|
||||
"$vhost not authorized in token (" . join( ', ', @vhosts ) . ')' );
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Is token in good interval ?
|
||||
my $localConfig = $class->localConfig;
|
||||
my $ttl =
|
||||
$localConfig->{vhostOptions}->{$vh}->{vhostServiceTokenTTL} <= 0
|
||||
? $class->tsv->{handlerServiceTokenTTL}
|
||||
: $localConfig->{vhostOptions}->{$vh}->{vhostServiceTokenTTL};
|
||||
unless ( $t <= time and $t > time - $ttl ) {
|
||||
my $ttl = $class->localConfig->{vhostOptions}->{$vhost}->{vhostServiceTokenTTL}
|
||||
|| $class->tsv->{serviceTokenTTL}->{$vhost};
|
||||
$ttl = $class->tsv->{handlerServiceTokenTTL} unless ( $ttl and $ttl > 0 );
|
||||
my $now = time;
|
||||
unless ( $t <= $now and $t > $now - $ttl ) {
|
||||
$class->userLogger->warn('Expired service token');
|
||||
$class->logger->debug("VH: $vhost with ServiceTokenTTL: $ttl");
|
||||
$class->logger->debug("TokenTime: $t / Time: $now");
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Send service headers if exist
|
||||
if (%serviceHeaders) {
|
||||
$class->logger->debug("Append service header(s)...");
|
||||
$class->set_header_out( $req, %serviceHeaders );
|
||||
|
|
|
@ -231,6 +231,8 @@ sub defaultValuesInit {
|
|||
$conf->{vhostOptions}->{$vhost}->{vhostType};
|
||||
$class->tsv->{authnLevel}->{$vhost} =
|
||||
$conf->{vhostOptions}->{$vhost}->{vhostAuthnLevel};
|
||||
$class->tsv->{serviceTokenTTL}->{$vhost} =
|
||||
$conf->{vhostOptions}->{$vhost}->{vhostServiceTokenTTL};
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -97,10 +97,10 @@ sub checkType {
|
|||
|
||||
## @rmethod int run
|
||||
# Check configuration and launch Lemonldap::NG::Handler::Main::run().
|
||||
# Each $checkTime, the Apache child verify if its configuration is the same
|
||||
# Each $checkTime, server child verifies if its configuration is the same
|
||||
# as the configuration stored in the local storage.
|
||||
# @param $rule optional Perl expression to grant access
|
||||
# @return Apache constant
|
||||
# @return constant
|
||||
|
||||
sub run {
|
||||
my ( $class, $req, $rule, $protection ) = @_;
|
||||
|
@ -121,11 +121,10 @@ sub run {
|
|||
}
|
||||
}
|
||||
|
||||
# Cross domain authentication
|
||||
# Authentication process
|
||||
my $uri = $req->{env}->{REQUEST_URI};
|
||||
|
||||
$uri = $req->{env}->{REQUEST_URI};
|
||||
my ($cond);
|
||||
|
||||
( $cond, $protection ) = $class->conditionSub($rule) if ($rule);
|
||||
$protection = $class->isUnprotected( $req, $uri ) || 0
|
||||
unless ( defined $protection );
|
||||
|
@ -273,6 +272,12 @@ sub grant {
|
|||
$vhost ||= $class->resolveAlias($req);
|
||||
if ( my $level = $class->tsv->{authnLevel}->{$vhost} ) {
|
||||
if ( $session->{authenticationLevel} < $level ) {
|
||||
$class->logger->debug(
|
||||
"User authentication level = $session->{authenticationLevel}");
|
||||
$class->logger->debug("Required authentication level = $level");
|
||||
$class->logger->warn(
|
||||
"User rejected due to insufficient authentication level -> Session upgrade enabled"
|
||||
);
|
||||
$session->{_upgrade} = 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -415,7 +420,7 @@ sub fetchId {
|
|||
my $value =
|
||||
$lookForHttpCookie
|
||||
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
|
||||
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
|
||||
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
|
||||
|
||||
if ( $value && $lookForHttpCookie && $class->tsv->{securedCookie} == 3 ) {
|
||||
$value = $class->tsv->{cipher}->decryptHex( $value, "http" );
|
||||
|
|
|
@ -166,7 +166,7 @@ ok( @headers == 0, 'NONE service header found' )
|
|||
or print STDERR Data::Dumper::Dumper( $res->[1] );
|
||||
count(1);
|
||||
|
||||
$token = $crypt->encrypt( join ':', time, $sessionId, '' );
|
||||
$token = $crypt->encrypt( join ':', time, $sessionId );
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/', undef, 'test2.example.com', undef,
|
||||
|
|
|
@ -1139,6 +1139,11 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
'dbiUserUser' => {
|
||||
'type' => 'text'
|
||||
},
|
||||
'decryptValueFunctions' => {
|
||||
'msgFail' => '__badCustomFuncName__',
|
||||
'test' => qr/^(?:\w+(?:::\w+)*(?:\s+\w+(?:::\w+)*)*)?$/,
|
||||
'type' => 'text'
|
||||
},
|
||||
'decryptValueRule' => {
|
||||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
|
|
|
@ -540,6 +540,13 @@ sub attributes {
|
|||
documentation => 'Decrypt value activation rule',
|
||||
flags => 'p',
|
||||
},
|
||||
decryptValueFunctions => {
|
||||
type => 'text',
|
||||
test => qr/^(?:\w+(?:::\w+)*(?:\s+\w+(?:::\w+)*)*)?$/,
|
||||
msgFail => "__badCustomFuncName__",
|
||||
documentation => 'Custom function used for decrypting values',
|
||||
flags => 'p',
|
||||
},
|
||||
skipRenewConfirmation => {
|
||||
type => 'bool',
|
||||
default => 0,
|
||||
|
|
|
@ -755,10 +755,11 @@ sub tree {
|
|||
},
|
||||
{
|
||||
title => 'decryptValue',
|
||||
help => 'decryptValueRule.html',
|
||||
help => 'decryptvalue.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'decryptValueRule',
|
||||
'decryptValueFunctions',
|
||||
]
|
||||
},
|
||||
]
|
||||
|
|
|
@ -246,6 +246,7 @@
|
|||
"dbiSchema":"مخطط",
|
||||
"dbiUserTable":"جدول المستخدم",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueFunctions":"Decrypt functions",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"الاعْتيادي",
|
||||
"defaultRule":"القاعدة الاعتيادية ",
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"User table",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueFunctions":"Decrypt functions",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Default",
|
||||
"defaultRule":"Default rule",
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"User table",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueFunctions":"Decrypt functions",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Default",
|
||||
"defaultRule":"Default rule",
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
"dbiSchema":"Schéma",
|
||||
"dbiUserTable":"Table des utilisateurs",
|
||||
"decryptValue":"Déchiffrement",
|
||||
"decryptValueFunctions":"Fonctions de déchiffrement",
|
||||
"decryptValueRule":"Règle d'utilisation",
|
||||
"default":"Défaut",
|
||||
"defaultRule":"Règle par défaut",
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"Tabella utente",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueFunctions":"Decrypt functions",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Predefinito",
|
||||
"defaultRule":"Regola predefinita",
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
"dbiSchema":"Giản đồ",
|
||||
"dbiUserTable":"Bảng người dùng",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueFunctions":"Decrypt functions",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Mặc định",
|
||||
"defaultRule":"Quy tắc mặc định",
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"用户表",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueFunctions":"Decrypt functions",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"默认",
|
||||
"defaultRule":"默认规则",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -266,6 +266,7 @@ site/htdocs/static/common/fr.png
|
|||
site/htdocs/static/common/icons/application_cascade.png
|
||||
site/htdocs/static/common/icons/arrow_refresh.png
|
||||
site/htdocs/static/common/icons/calendar.png
|
||||
site/htdocs/static/common/icons/decryptValue.png
|
||||
site/htdocs/static/common/icons/door_out.png
|
||||
site/htdocs/static/common/icons/key.png
|
||||
site/htdocs/static/common/icons/oidc.png
|
||||
|
@ -574,6 +575,8 @@ t/43-MailPasswordReset-with-token.t
|
|||
t/43-MailPasswordReset.t
|
||||
t/44-CertificateResetByMail-LDAP.t
|
||||
t/50-IssuerGet.t
|
||||
t/58-DecryptValue-with-custom-function.t
|
||||
t/58-DecryptValue-with-internal-function.t
|
||||
t/59-Double-cookies-for-a-Single-session.t
|
||||
t/59-Double-cookies-for-Double-sessions.t
|
||||
t/59-Double-cookies-Refresh-and-Logout.t
|
||||
|
@ -645,6 +648,7 @@ t/lib/Apache/Session/Timeout.pm
|
|||
t/lib/Lemonldap/NG/Common/Conf/Backends/Timeout.pm
|
||||
t/lib/Lemonldap/NG/Handler/Test.pm
|
||||
t/lib/Lemonldap/NG/Portal/Auth/LDAPPolicy.pm
|
||||
t/lib/Lemonldap/NG/Portal/Custom.pm
|
||||
t/lmConf-1.json
|
||||
t/pdata.pm
|
||||
t/README.md
|
||||
|
|
|
@ -356,7 +356,11 @@ sub reloadConf {
|
|||
|
||||
# Clean $req->pdata after authentication
|
||||
push @{ $self->endAuth }, sub {
|
||||
my $tmp = $_[0]->pdata->{keepPdata} //= [];
|
||||
|
||||
my $tmp =
|
||||
( ref( $_[0]->pdata->{keepPdata} ) eq 'ARRAY' )
|
||||
? $_[0]->pdata->{keepPdata}
|
||||
: [];
|
||||
foreach my $k ( keys %{ $_[0]->pdata } ) {
|
||||
unless ( grep { $_ eq $k } @$tmp ) {
|
||||
$self->logger->debug("Removing $k from pdata");
|
||||
|
|
|
@ -130,6 +130,15 @@ sub params {
|
|||
$self->logger->debug("Display SwitchContext link -> $res{contextSwitching}")
|
||||
if $res{contextSwitching};
|
||||
|
||||
# Display DecryptValue link if allowed
|
||||
my $dvPlugin =
|
||||
$self->p->loadedModules->{'Lemonldap::NG::Portal::Plugins::DecryptValue'};
|
||||
$res{decryptValue} =
|
||||
$dvPlugin
|
||||
? $dvPlugin->displayLink( $req, $req->userData )
|
||||
: '';
|
||||
$self->logger->debug("Display DecryptValue link") if $res{decryptValue};
|
||||
|
||||
return %res;
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,10 @@ sub authLogout {
|
|||
my ( $self, $req ) = @_;
|
||||
my $res = $self->_authentication->authLogout($req);
|
||||
$self->logger->debug('Cleaning pdata');
|
||||
my $tmp = $req->pdata->{keepPdata} //= [];
|
||||
my $tmp =
|
||||
( ref( $req->pdata->{keepPdata} ) eq 'ARRAY' )
|
||||
? $req->pdata->{keepPdata}
|
||||
: [];
|
||||
foreach my $k ( keys %{ $req->pdata } ) {
|
||||
delete $req->pdata->{$k} unless ( grep { $_ eq $k } @$tmp );
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ sub display {
|
|||
|
||||
sub run {
|
||||
my ( $self, $req ) = @_;
|
||||
my $msg = '';
|
||||
my ( $msg, $decryptedValue ) = ( '', '' );
|
||||
|
||||
# Check access rules
|
||||
unless ( $self->rule->( $req, $req->userData ) ) {
|
||||
|
@ -121,12 +121,43 @@ sub run {
|
|||
}
|
||||
|
||||
my $cipheredValue = $req->param('cipheredValue') || '';
|
||||
my $decryptedValue =
|
||||
$self->p->HANDLER->tsv->{cipher}->decrypt($cipheredValue)
|
||||
if $cipheredValue;
|
||||
$self->logger->debug("decryptValue tried with value: $cipheredValue");
|
||||
|
||||
$self->logger->debug("decryptValue try with : $cipheredValue");
|
||||
$self->logger->debug("Decrypted value = $decryptedValue") if $decryptedValue;
|
||||
if ($cipheredValue) {
|
||||
if ( $self->{conf}->{decryptValueFunctions}
|
||||
and $self->{conf}->{decryptValueFunctions} =~
|
||||
qr/^(?:\w+(?:::\w+)*(?:\s+\w+(?:::\w+)*)*)?$/ )
|
||||
{
|
||||
foreach ( split( /\s+/, $self->{conf}->{decryptValueFunctions} ) ) {
|
||||
$self->userLogger->notice(
|
||||
"Try to decrypt value with function: $_");
|
||||
/^([\w:{2}]*?)(?:::)?(?:\w+)$/;
|
||||
eval "require Lemonldap::NG::Portal::$1";
|
||||
$self->logger->debug("Unable to load decrypt module: $@")
|
||||
if ($@);
|
||||
$decryptedValue = eval "$_" . '($cipheredValue)' unless ($@);
|
||||
$self->logger->debug(
|
||||
$@
|
||||
? "Unable to eval decrypt function: $@"
|
||||
: "Decrypted value = $decryptedValue"
|
||||
);
|
||||
last if $decryptedValue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->userLogger->notice("Malformed decrypt functions")
|
||||
if $self->{conf}->{decryptValueFunctions};
|
||||
$self->userLogger->notice(
|
||||
"Try to decrypt value with internal LL::NG decrypt function");
|
||||
$decryptedValue =
|
||||
$self->p->HANDLER->tsv->{cipher}->decrypt($cipheredValue);
|
||||
$self->logger->debug(
|
||||
$@
|
||||
? "Unable to decrypt value: $@"
|
||||
: "Decrypted value = $decryptedValue"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# Display form
|
||||
my $params = {
|
||||
|
@ -155,4 +186,9 @@ sub run {
|
|||
return $self->p->sendHtml( $req, 'decryptvalue', params => $params );
|
||||
}
|
||||
|
||||
sub displayLink {
|
||||
my ( $self, $req ) = @_;
|
||||
return $self->rule->( $req, $req->userData );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 693 B |
|
@ -74,10 +74,16 @@
|
|||
</TMPL_IF>
|
||||
<TMPL_IF NAME="contextSwitching">
|
||||
<li class="dropdown-item"><a href="/switchcontext" class="nav-link">
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/switchcontext_<TMPL_VAR NAME="contextSwitching">.png" width="20" height="20" alt="refresh" />
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/switchcontext_<TMPL_VAR NAME="contextSwitching">.png" width="20" height="20" alt="switchContext" />
|
||||
<span trspan="contextSwitching_<TMPL_VAR NAME="contextSwitching">">contextSwitching_<TMPL_VAR NAME="contextSwitching"></span>
|
||||
</a></li>
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="decryptValue">
|
||||
<li class="dropdown-item"><a href="/decryptvalue" class="nav-link">
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/decryptValue.png" width="20" height="20" alt="decryptValue" />
|
||||
<span trspan="decryptCipheredValue">decryptCipheredValue</span>
|
||||
</a></li>
|
||||
</TMPL_IF>
|
||||
<li class="dropdown-item"><a href="/refresh" class="nav-link">
|
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/arrow_refresh.png" width="16" height="16" alt="refresh" />
|
||||
<span trspan="refreshrights">Refresh</span>
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
use Test::More;
|
||||
use strict;
|
||||
use IO::String;
|
||||
use lib 't/lib';
|
||||
|
||||
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,
|
||||
requireToken => 0,
|
||||
decryptValueRule => 1,
|
||||
decryptValueFunctions =>
|
||||
'Custom::empty Custom::test_uc Custom::undefined',
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
## Try to authenticate
|
||||
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
|
||||
count(1);
|
||||
my ( $host, $url, $query ) = expectForm( $res, '#', undef, 'user', 'password' );
|
||||
|
||||
$query = 'user=dwho&password=dwho';
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new($query),
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
|
||||
my $id = expectCookie($res);
|
||||
expectRedirection( $res, 'http://auth.example.com/' );
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'CheckUser form',
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<img src="/static/common/icons/decryptValue\.png"%,
|
||||
'Found decryptValue.png' )
|
||||
or explain( $res->[2]->[0], 'decryptValue.png' );
|
||||
count(3);
|
||||
|
||||
# DecryptValue form
|
||||
# ------------------------
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/decryptvalue',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'DecryptValue form',
|
||||
);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/decryptvalue', 'cipheredValue' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="decryptCipheredValue">%,
|
||||
'Found trspan="decryptCipheredValue"' )
|
||||
or explain( $res->[2]->[0], 'trspan="decryptCipheredValue"' );
|
||||
count(2);
|
||||
|
||||
# Decrypt ciphered value
|
||||
$query =~
|
||||
s%cipheredValue=%cipheredValue=lowercase%;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/decryptvalue',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'POST decryptvalue with valid value'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="LOWERCASE"></span>%, 'Found decryted value' )
|
||||
or explain( $res->[2]->[0], 'Decryted value NOT found' );
|
||||
count(2);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/decryptvalue', 'cipheredValue' );
|
||||
|
||||
$client->logout($id);
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
|
@ -0,0 +1,153 @@
|
|||
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,
|
||||
decryptValueRule => '$uid eq "dwho"',
|
||||
requireToken => 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
## Try to authenticate
|
||||
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=rtyler/;
|
||||
$query =~ s/password=/password=rtyler/;
|
||||
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/' );
|
||||
|
||||
# DecryptValue form for a foridden user
|
||||
# ------------------------
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/decryptvalue',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'Try DecryptValue form for a forbidden user',
|
||||
);
|
||||
count(1);
|
||||
ok( $res->[2]->[0] =~ m%<span trmsg="95">%, 'Found trmsg="95"' )
|
||||
or explain( $res->[2]->[0], 'trmsg="95"' );
|
||||
count(1);
|
||||
$client->logout($id);
|
||||
|
||||
## Try to authenticate
|
||||
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
|
||||
count(1);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, '#', undef, 'user', 'password', 'token' );
|
||||
|
||||
$query =~ s/user=/user=dwho/;
|
||||
$query =~ s/password=/password=dwho/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new($query),
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
|
||||
$id = expectCookie($res);
|
||||
expectRedirection( $res, 'http://auth.example.com/' );
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'CheckUser form',
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<img src="/static/common/icons/decryptValue\.png"%,
|
||||
'Found decryptValue.png' )
|
||||
or explain( $res->[2]->[0], 'decryptValue.png' );
|
||||
count(3);
|
||||
|
||||
# DecryptValue form
|
||||
# ------------------------
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/decryptvalue',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'DecryptValue form',
|
||||
);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/decryptvalue', 'cipheredValue', 'token' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="decryptCipheredValue">%,
|
||||
'Found trspan="decryptCipheredValue"' )
|
||||
or explain( $res->[2]->[0], 'trspan="decryptCipheredValue"' );
|
||||
count(2);
|
||||
|
||||
# Valid ciphered value
|
||||
$query =~
|
||||
s%cipheredValue=%cipheredValue=CNCERR4E3BPrrEY0BZGnl3ISfUZARKXNhnDj3x7/xO5kxodXbeLzTk2VSHh1rq/C4TU78wzyWiove81YseYj/g==%;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/decryptvalue',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'POST decryptvalue with valid value'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="dwho"></span>%, 'Found decryted value' )
|
||||
or explain( $res->[2]->[0], 'Decryted value NOT found' );
|
||||
count(2);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/decryptvalue', 'cipheredValue', 'token' );
|
||||
|
||||
# Unvalid ciphered value
|
||||
$query =~ s%cipheredValue=%cipheredValue=test%;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/decryptvalue',
|
||||
IO::String->new($query),
|
||||
cookie => "lemonldap=$id",
|
||||
length => length($query),
|
||||
accept => 'text/html',
|
||||
),
|
||||
'POST decryptvalue with unvalid value'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="notAnEncryptedValue">%,
|
||||
'Found trspan="notAnEncryptedValue"' )
|
||||
or explain( $res->[2]->[0], 'trspan="notAnEncryptedValue"' );
|
||||
count(2);
|
||||
( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/decryptvalue', 'cipheredValue', 'token' );
|
||||
|
||||
$client->logout($id);
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
|
@ -0,0 +1,15 @@
|
|||
package Custom;
|
||||
|
||||
sub empty {
|
||||
return '';
|
||||
}
|
||||
|
||||
sub undefined {
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub test_uc {
|
||||
return uc $_[0];
|
||||
}
|
||||
|
||||
1;
|
Loading…
Reference in New Issue