Merge branch 'v2.0'

This commit is contained in:
Christophe Maudoux 2020-04-01 15:55:31 +02:00
commit 7c0e6a2d00
26 changed files with 243 additions and 69 deletions

View File

@ -67,7 +67,7 @@ sub build_jail {
$self->customFunctions ? split( /\s+/, $self->customFunctions ) : ();
foreach (@builtCustomFunctions) {
no warnings 'redefine';
$api->logger->debug("Custom function : $_");
$api->logger->debug("Custom function: $_");
my $sub = $_;
unless (/::/) {
$sub = "$self\::$_";

View File

@ -185,7 +185,8 @@ sub jailInit {
multiValuesSeparator => $conf->{multiValuesSeparator},
}
);
$class->tsv->{jail}->build_jail( $class, $conf->{require}, $conf->{requireDontDie} );
$class->tsv->{jail}
->build_jail( $class, $conf->{require}, $conf->{requireDontDie} );
}
## @imethod protected void defaultValuesInit(hashRef args)
@ -363,13 +364,14 @@ sub sessionStorageInit {
if ( $conf->{status} ) {
my $params = "";
if ( $class->tsv->{sessionCacheModule} ) {
$params = ' ' . join(
$params = $class->tsv->{sessionCacheModule} . ',{' . join(
',',
$class->tsv->{sessionCacheModule} . map {
"$_ => "
. $class->tsv->{sessionCacheOptions}->{$_}
} keys %{ $class->tsv->{sessionCacheOptions} // {} }
);
map {
"$_ => '"
. $class->tsv->{sessionCacheOptions}->{$_} . "'"
}
keys %{ $class->tsv->{sessionCacheOptions} // {} }
) . '}';
}
$class->tsv->{statusPipe}->print("RELOADCACHE $params\n");
}

View File

@ -19,9 +19,10 @@ sub perlExpr {
$cpt->reval("BEGIN { 'warnings'->unimport; } $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; } split( /\n/, $@, 0 ) )
grep( { $_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_; }
split( /\n/, $@, 0 ) )
);
return $err ? ( 1, "__badExpression__: $err" ) : 1;
return $err ? ( -1, "__badExpression__: $err" ) : 1;
}
sub types {

View File

@ -25,8 +25,8 @@ sub perlExpr {
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { 'warnings'->unimport; } $val");
my $err = join( '',
grep { $_ =~ /Undefined subroutine/ ? () : $_ } split( /\n/, $@ ) );
return $err ? ( 1, "__badExpression__: $err" ) : (1);
grep { $_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_ } split( /\n/, $@ ) );
return $err ? ( -1, "__badExpression__: $err" ) : (1);
}
my $url = $RE{URI}{HTTP}{ -scheme => "https?" };

View File

@ -1207,7 +1207,14 @@ sub _execTest {
if ( $ref eq 'CODE' ) {
my ( $r, $m ) = ( $test->( $value, $conf, $attr ) );
if ($m) {
push @{ $self->{ ( $r ? 'warnings' : 'errors' ) } },
push @{
$self->{ (
$r > 0
? 'warnings'
: ( $r < 0 ? 'needConfirmation' : 'errors' )
)
}
},
{ message => "$key: $m" };
}
elsif ( !$r ) {

View File

@ -122,7 +122,7 @@ sub verify {
$args->{$k} = (
$k eq 'code'
? $code
: $req->sessionInfo->{ $self->{vrfyAttrs}->{$k} }
: $session->{ $self->{vrfyAttrs}->{$k} }
);
}

View File

@ -112,8 +112,7 @@ sub verify {
}
else {
$self->userLogger->notice( 'Invalid TOTP for '
. $session->{ $self->conf->{whatToTrace} }
. ')' );
. $session->{ $self->conf->{whatToTrace} } );
return PE_BADOTP;
}
}

View File

@ -35,7 +35,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{issuerDBCASRule} ) );
unless ($rule) {
$self->error( "Bad CAS rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad CAS activation rule -> $error");
return 0;
}
$self->{rule} = $rule;

View File

@ -24,7 +24,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{issuerDBGetRule} ) );
unless ($rule) {
$self->error( "Bad GET rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error( "Bad GET activation rule -> $error" );
return 0;
}
$self->{rule} = $rule;

View File

@ -64,7 +64,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{issuerDBOpenIDRule} ) );
unless ($rule) {
$self->error( "Bad OpenID rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error( "Bad OpenID activation rule -> $error" );
return 0;
}
$self->{rule} = $rule;

View File

@ -76,7 +76,8 @@ sub init {
$hd->buildSub(
$hd->substitute( $self->conf->{issuerDBOpenIDConnectRule} ) );
unless ($rule) {
$self->error( "Bad OIDC rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error( "Bad OIDC activation rule -> $error" );
return 0;
}
$self->{rule} = $rule;
@ -544,7 +545,7 @@ sub run {
$imgSrc =
( $icon =~ m#^https?://# )
? $icon
: $self->p->staticPrefic . "/common/" . $icon;
: $self->p->staticPrefix . "/common/" . $icon;
}
my $scope_messages = {

View File

@ -47,7 +47,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{issuerDBSAMLRule} ) );
unless ($rule) {
$self->error( "Bad SAML rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error( "Bad SAML activation rule -> $error" );
return 0;
}
$self->{rule} = $rule;

View File

@ -31,8 +31,11 @@ sub restCall {
unless ( $resp->is_success ) {
die $resp->status_line;
}
my $res = eval { from_json( $resp->content, { allow_nonref => 1 } ) };
my $res = eval { from_json( $resp->content ) };
die "Bad REST response: $@" if ($@);
if ( ref($res) ne "HASH" ) {
die "Bad REST response: expecting a JSON HASH, got " . ref($res);
}
return $res;
}

View File

@ -124,8 +124,20 @@ sub _verify {
. $req->sessionInfo->{ $self->conf->{whatToTrace} } );
if ( my $l = $self->conf->{ $self->prefix . '2fAuthnLevel' } ) {
$self->p->updateSession( $req, { authenticationLevel => $l } );
$self->logger->debug("Update sessionInfo with new authenticationLevel: $l");
$req->sessionInfo->{authenticationLevel} = $l;
delete $req->sessionInfo->{groups};
# Compute groups & macros again with new authenticationLevel
$req->steps( [ $self->p->groupsAndMacros, 'setLocalGroups'] );
if ( my $error = $self->p->process($req) ) {
$self->logger->debug("SFA: Process returned error: $error");
$req->error($error);
return $self->p->do( $req, [ sub { $error } ] );
}
$self->p->updateSession( $req, $req->sessionInfo );
}
$req->authResult(PE_SENDRESPONSE);
return $self->p->do(
$req,

View File

@ -54,8 +54,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{checkUserIdRule} ) );
unless ($rule) {
$self->error(
"Bad checkUser identities rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad checkUser identities rule -> $error");
return 0;
}
$self->idRule($rule);
@ -368,6 +368,7 @@ sub _urlFormat {
sub _userData {
my ( $self, $req ) = @_;
my $realAuthLevel = $req->userData->{authenticationLevel};
# Compute session
my $steps = [
@ -405,6 +406,16 @@ sub _userData {
return $req->error(PE_BADCREDENTIALS);
}
# Compute groups & macros again with real authenticationLevel
$req->sessionInfo->{authenticationLevel} = $realAuthLevel;
delete $req->sessionInfo->{groups};
$req->steps( [ $self->p->groupsAndMacros, 'setLocalGroups' ] );
if ( my $error = $self->p->process($req) ) {
$self->logger->debug(
"ContextSwitching: Process returned error: $error");
return $req->error($error);
}
$self->logger->debug("Return \"$req->{user}\" sessionInfo");
return $req->{sessionInfo};
}

View File

@ -40,7 +40,7 @@ has idRule => ( is => 'rw', default => sub { 1 } );
sub init {
my ($self) = @_;
my $hd = $self->p->HANDLER;
$self->addAuthRoute( switchcontext => 'run', ['POST'] )
$self->addAuthRoute( switchcontext => 'run', ['POST'] )
->addAuthRoute( switchcontext => 'display', ['GET'] );
# Parse activation rule
@ -49,8 +49,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{contextSwitchingRule} ) );
unless ($rule) {
$self->error(
'Bad contextSwitching rule -> ' . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad contextSwitching rule -> $error");
return 0;
}
$self->rule($rule);
@ -61,8 +61,8 @@ sub init {
$rule =
$hd->buildSub( $hd->substitute( $self->conf->{contextSwitchingIdRule} ) );
unless ($rule) {
$self->error( "Bad contextSwitching identities rule -> "
. $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad contextSwitching identities rule -> $error");
return 0;
}
$self->idRule($rule);
@ -197,6 +197,7 @@ sub run {
sub _switchContext {
my ( $self, $req, $spoofId ) = @_;
my $realSessionId = $req->userData->{_session_id};
my $realAuthLevel = $req->userData->{authenticationLevel};
my $realId = $req->{user};
my $raz = 0;
$req->{user} = $spoofId;
@ -234,13 +235,28 @@ sub _switchContext {
$req->sessionInfo->{"$self->{conf}->{impersonationPrefix}_session_id"} =
$realSessionId;
$self->userLogger->notice(
"Start ContextSwitching: $realId becomes $spoofId ")
unless $raz;
return $raz
? $self->_abortImpersonation( $req, $spoofId, $realId, 1 )
: $req;
if ($raz) {
return $self->_abortImpersonation( $req, $spoofId, $realId, 1 );
}
else {
$self->logger->debug(
"Update sessionInfo with real authenticationLevel: $realAuthLevel");
$req->sessionInfo->{authenticationLevel} = $realAuthLevel;
delete $req->sessionInfo->{groups};
# Compute groups & macros again with real authenticationLevel
$req->steps( [ $self->p->groupsAndMacros, 'setLocalGroups' ] );
if ( my $error = $self->p->process($req) ) {
$self->logger->debug(
"ContextSwitching: Process returned error: $error");
$req->error($error);
}
$self->userLogger->notice(
"Start ContextSwitching: $realId becomes $spoofId ");
return $req;
}
}
sub _abortImpersonation {

View File

@ -40,7 +40,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{decryptValueRule} ) );
unless ($rule) {
$self->error( 'Bad decryptValue rule -> ' . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad decryptValue rule -> $error");
return 0;
}
$self->rule($rule);

View File

@ -45,7 +45,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{globalLogoutRule} ) );
unless ($rule) {
$self->error( "Bad globalLogout rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad globalLogout rule -> $error");
return 0;
}
$self->rule($rule);

View File

@ -27,7 +27,8 @@ sub init {
$hd->buildSub(
$hd->substitute( $self->conf->{grantSessionRules}->{$_} ) );
unless ($rule) {
$self->error( "Bad grantSession rule " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad grantSession rule -> $error");
return 0;
}
$self->rules->{$_} = $rule;
@ -66,7 +67,8 @@ sub run {
my $hd = $self->p->HANDLER;
my $msg = $hd->substitute($1);
unless ( $msg = $hd->buildSub($msg) ) {
$self->error( "Bad message " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad message -> $error");
return PE_OK;
}
$msg = $msg->( $req, $req->sessionInfo );

View File

@ -31,7 +31,8 @@ sub init {
my $rule =
$hd->buildSub( $hd->substitute( $self->conf->{impersonationRule} ) );
unless ($rule) {
$self->error( "Bad impersonation rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad impersonation rule -> $error");
return 0;
}
$self->rule($rule);
@ -42,8 +43,8 @@ sub init {
$rule =
$hd->buildSub( $hd->substitute( $self->conf->{impersonationIdRule} ) );
unless ($rule) {
$self->error(
"Bad impersonation identities rule -> " . $hd->tsv->{jail}->error );
my $error = $hd->tsv->{jail}->error || '???';
$self->error("Bad impersonation identities rule -> $error");
return 0;
}
$self->idRule($rule);

View File

@ -89,11 +89,11 @@ sub setSessionInfo {
# @return Lemonldap::NG::Portal constant
sub setGroups {
my ( $self, $req ) = @_;
my $user = $req->user || $req->sessionInfo->{ $self->conf->{whatToTrace} };
my $groups = $req->sessionInfo->{groups} || '';
my $hGroups = $req->sessionInfo->{hGroups} || {};
for my $grp ( keys %demoGroups ) {
if ( grep { $_ eq $req->user } @{ $demoGroups{$grp} } ) {
if ( grep { $_ eq $user } @{ $demoGroups{$grp} } ) {
$hGroups->{$grp} = {};
$groups =
($groups)

View File

@ -116,8 +116,8 @@ ok(
'POST checkuser'
);
my %attributes = map /<td scope="row">(.+)?<\/td>/g, $res->[2]->[0];
ok( scalar keys %attributes == 17, 'Found 17 attributes' )
or print STDERR "Missing attributes -> " . scalar keys %attributes;
ok( scalar keys %attributes == 18, 'Found 18 attributes' )
or print STDERR "Wrong number of attributes -> " . scalar keys %attributes;
ok( $attributes{'_updateTime'} =~ /^\d{14}$/, 'Timestamp found' )
or print STDERR Dumper( \%attributes );
count(3);
@ -184,8 +184,8 @@ ok(
'POST checkuser'
);
my %attributes2 = map /<td scope="row">(.+)?<\/td>/g, $res->[2]->[0];
ok( scalar keys %attributes2 == 17, 'Found 17 attributes' )
or print STDERR "Missing attributes -> " . scalar keys %attributes2;
ok( scalar keys %attributes2 == 18, 'Found 18 attributes' )
or print STDERR "Wrong nunber of attributes -> " . scalar keys %attributes2;
ok( $attributes2{'_updateTime'} =~ /^\d{14}$/, 'Timestamp found' )
or print STDERR Dumper( \%attributes2 );
count(3);

View File

@ -16,8 +16,8 @@ my $client = LLNG::Manager::Test->new( {
userDB => 'Same',
loginHistoryEnabled => 0,
brutForceProtection => 0,
checkUser => 1,
requireToken => 0,
checkUser => 1,
checkUserIdRule => '$uid ne "msmith"',
checkUserSearchAttributes => 'employee_nbr test1 _user test2 mail',
checkUserDisplayPersistentInfo => 1,
@ -26,6 +26,7 @@ my $client = LLNG::Manager::Test->new( {
totp2fSelfRegistration => 1,
totp2fActivation => 1,
totp2fDigits => 6,
totp2fAuthnLevel => 8,
impersonationRule => 1,
#hiddenAttributes => 'test',
@ -173,7 +174,6 @@ ok(
my ( $host, $url, $query ) = expectForm( $res, undef, '/totp2fcheck', 'token' );
# Generate TOTP with LLNG
my $totp = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 );
$query =~ s/code=/code=$code/;
@ -189,7 +189,6 @@ $id = expectCookie($res);
# CheckUser form -> granted
# ------------------------
ok(
$res = $client->_get(
'/checkuser',
@ -210,7 +209,17 @@ ok( $res->[2]->[0] =~ m%<td scope="row">dwho</td>%, 'Found value dwho' )
or explain( $res->[2]->[0], 'Value dwho' );
ok( $res->[2]->[0] !~ m%_2fDevices</td>%, '_2fDevices NOT Found!' )
or explain( $res->[2]->[0], 'Value _2fDevices' );
count(4);
ok( $res->[2]->[0] =~ m%<td scope="row">authMode</td>%, 'Found macro authMode' )
or explain( $res->[2]->[0], 'Macro Key authMode' );
ok( $res->[2]->[0] =~ m%<td scope="row">DEMO</td>%, 'Found DEMO' )
or explain( $res->[2]->[0], 'Macro Value DEMO' );
ok( $res->[2]->[0] =~ m%<td scope="row">real_authMode</td>%,
'Found macro real_authMode' )
or explain( $res->[2]->[0], 'Macro Key real_authMode' );
ok( $res->[2]->[0] =~ m%<td scope="row">TOTP</td>%, 'Found TOTP' )
or explain( $res->[2]->[0], 'Macro Value TOTP' );
count(8);
$query =~ s/url=/url=http%3A%2F%2Ftest1.example.com/;
ok(
@ -345,7 +354,7 @@ m%<div class="alert alert-danger"><div class="text-center"><b><span trspan="forb
) or explain( $res->[2]->[0], 'trspan="forbidden"' );
count(2);
# Request with allowed URL proteced by extended function
# Request with allowed URL protected by extended function
$query =~
s#url=http%3A%2F%2Ftest1.example.com%2Ftest-restricted_uri%2Frtyler#url=http%3A%2F%2Ftest1.example.com/test-restricted_uri/rtyler/#;
ok(

View File

@ -32,7 +32,9 @@ my $client = LLNG::Manager::Test->new( {
contextSwitchingIdRule => 1,
totp2fSelfRegistration => 1,
totp2fActivation => 1,
totp2fAuthnLevel => 8,
contextSwitchingStopWithLogout => 0,
checkUser => 1,
notification => 1,
notificationStorage => 'File',
notificationStorageOptions => { dirName => $main::tmpDir },
@ -147,15 +149,14 @@ ok(
eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' );
my ( $key, $token );
ok( $key = $res->{secret}, 'Found secret' );
my $keyR;
ok( $keyR = $res->{secret}, 'Found secret' );
ok( $token = $res->{token}, 'Found token' );
$key = Convert::Base32::decode_base32($key);
$keyR = Convert::Base32::decode_base32($keyR);
count(4);
# Post code
my $code;
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $keyR, 0, 30, 6 ),
'Code' );
ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
my $s = "code=$code&token=$token";
@ -220,6 +221,26 @@ ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' );
count(6);
# CheckUser form
ok(
$res = $client->_get(
'/checkuser',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'CheckUser form',
);
( $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%<td scope="row">authMode</td>%, 'Found macro authMode' )
or explain( $res->[2]->[0], 'Macro Key authMode' );
ok( $res->[2]->[0] =~ m%<td scope="row">DEMO</td>%, 'Found DEMO' )
or explain( $res->[2]->[0], 'Macro Value DEMO' );
count(4);
# Stop ContextSwitching
# ------------------------
ok(
@ -336,10 +357,90 @@ ok(
),
'Auth query'
);
ok( $res->[2]->[0] =~ m%<span trspan="enterTotpCode">%,
'TOTP code required' )
ok( $res->[2]->[0] =~ m%<span trspan="enterTotpCode">%, 'TOTP code required' )
or explain( $res->[2]->[0], 'trspan="enterTotpCode"' );
count(2);
( $host, $url, $query ) = expectForm( $res, undef, '/totp2fcheck', 'token' );
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
'LLNG Code' );
$query =~ s/code=/code=$code/;
ok(
$res = $client->_post(
'/totp2fcheck',
IO::String->new($query),
length => length($query),
),
'Post code'
);
count(2);
$id = expectCookie($res);
# CheckUser form
ok(
$res = $client->_get(
'/checkuser',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'CheckUser form',
);
( $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%<td scope="row">authMode</td>%, 'Found macro authMode' )
or explain( $res->[2]->[0], 'Macro Key authMode' );
ok( $res->[2]->[0] =~ m%<td scope="row">TOTP</td>%, 'Found TOTP' )
or explain( $res->[2]->[0], 'Macro Value TOTP' );
count(4);
# Request not connected user
$query =~ s/user=dwho/user=davros/;
ok(
$res = $client->_post(
'/checkuser',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST checkuser'
);
( $host, $url, $query ) =
expectForm( $res, undef, '/checkuser', 'user', 'url' );
ok( $res->[2]->[0] =~ m%<span trspan="checkUserComputeSession">%, 'Found trspan="checkUserComputeSession"' )
or explain( $res->[2]->[0], 'trspan="checkUserComputeSession"' );
ok( $res->[2]->[0] =~ m%<td scope="row">authMode</td>%, 'Found macro authMode' )
or explain( $res->[2]->[0], 'Macro Key authMode' );
ok( $res->[2]->[0] =~ m%<td scope="row">TOTP</td>%, 'Found TOTP' )
or explain( $res->[2]->[0], 'Macro Value TOTP' );
count(4);
# Request connected user
$query =~ s/user=davros/user=msmith/;
ok(
$res = $client->_post(
'/checkuser',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST checkuser'
);
( $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%<td scope="row">authMode</td>%, 'Found macro authMode' )
or explain( $res->[2]->[0], 'Macro Key authMode' );
ok( $res->[2]->[0] =~ m%<td scope="row">DEMO</td>%, 'Found DEMO' )
or explain( $res->[2]->[0], 'Macro Value DEMO' );
count(4);
clean_sessions();

View File

@ -5,20 +5,22 @@ use IO::String;
use LWP::UserAgent;
use LWP::Protocol::PSGI;
use Plack::Request;
use JSON qw/from_json/;
require 't/test-lib.pm';
my $maintests = 6;
my $maintests = 7;
LWP::Protocol::PSGI->register(
sub {
my $req = Plack::Request->new(@_);
if ( $req->path_info eq '/init' ) {
ok( $req->content eq '{"name":"dwho"}', ' Init req gives dwho' )
or explain( $req->content, '{"name":"dwho"}' );
my $json = from_json( $req->content );
is( $json->{name}, "dwho", ' Init req gives dwho' );
}
elsif ( $req->path_info eq '/vrfy' ) {
ok( $req->content eq '{"code":"1234"}', ' Code is 1234' )
or explain( $req->content, '{"code":"1234"}' );
my $json = from_json( $req->content );
is( $json->{name}, "dwho", ' Verify req contains name' );
is( $json->{code}, "1234", ' Verify req contains code' );
}
else {
fail( ' Bad REST call ' . $req->path_info );
@ -38,7 +40,7 @@ my $client = LLNG::Manager::Test->new( {
rest2fInitUrl => 'http://auth.example.com/init',
rest2fInitArgs => { name => 'uid' },
rest2fVerifyUrl => 'http://auth.example.com/vrfy',
rest2fVerifyArgs => { code => 'code' },
rest2fVerifyArgs => { name => 'uid', code => 'code' },
loginHistoryEnabled => 1,
authentication => 'Demo',
userDB => 'Same',

View File

@ -107,7 +107,8 @@
},
"macros": {
"_whatToTrace": "$_auth eq 'SAML' ? \"$_user\\@$_idpConfKey\" : \"$_user\"",
"array": "$uid eq 'french' ? 'doctor; who' : ''"
"array": "$uid eq 'french' ? 'doctor; who' : ''",
"authMode": "$authenticationLevel == 8 ? TOTP : 'DEMO'"
},
"notifications": 0,
"passwordDB": "Null",