diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Jail.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Jail.pm index f037a0adc..fe5660f80 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Jail.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Jail.pm @@ -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\::$_"; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm index 9d350a559..0fde7a70e 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Main/Reload.pm @@ -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"); } diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm index f317439e0..ad8fabf65 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm @@ -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 { diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm index 146f4520a..e6bb5adbf 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm @@ -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?" }; diff --git a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm index 389ad6347..f54ae0d1f 100644 --- a/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm +++ b/lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Parser.pm @@ -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 ) { diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/REST.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/REST.pm index 5b8c7a10a..a5507e058 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/REST.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/REST.pm @@ -122,7 +122,7 @@ sub verify { $args->{$k} = ( $k eq 'code' ? $code - : $req->sessionInfo->{ $self->{vrfyAttrs}->{$k} } + : $session->{ $self->{vrfyAttrs}->{$k} } ); } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/TOTP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/TOTP.pm index e58204255..1dfe8414c 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/TOTP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/TOTP.pm @@ -112,8 +112,7 @@ sub verify { } else { $self->userLogger->notice( 'Invalid TOTP for ' - . $session->{ $self->conf->{whatToTrace} } - . ')' ); + . $session->{ $self->conf->{whatToTrace} } ); return PE_BADOTP; } } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/CAS.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/CAS.pm index 9ea2dbb7c..492c075d7 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/CAS.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/CAS.pm @@ -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; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/Get.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/Get.pm index a50fdc21b..d28b3c208 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/Get.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/Get.pm @@ -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; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenID.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenID.pm index dec13d9ce..93ade4c82 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenID.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenID.pm @@ -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; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenIDConnect.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenIDConnect.pm index 76d6a8fd3..323dbc3bb 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenIDConnect.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/OpenIDConnect.pm @@ -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 = { diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/SAML.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/SAML.pm index 431dffcd0..e1df3c059 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/SAML.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Issuer/SAML.pm @@ -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; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/REST.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/REST.pm index eb1803a9d..211f9848e 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/REST.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/REST.pm @@ -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; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm index c1235a335..37c3421c4 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/SecondFactor.pm @@ -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, diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CheckUser.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CheckUser.pm index a313d6aa7..a0c4d44e9 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CheckUser.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CheckUser.pm @@ -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}; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ContextSwitching.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ContextSwitching.pm index 790ac673b..6cb2f9670 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ContextSwitching.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/ContextSwitching.pm @@ -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 { diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/DecryptValue.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/DecryptValue.pm index cc587355e..a24b68683 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/DecryptValue.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/DecryptValue.pm @@ -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); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GlobalLogout.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GlobalLogout.pm index 744372e1c..ccab36a1b 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GlobalLogout.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GlobalLogout.pm @@ -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); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm index 996d4e08a..aac910de4 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm @@ -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 ); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Impersonation.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Impersonation.pm index 2375e8920..f79d9ae31 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Impersonation.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Impersonation.pm @@ -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); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm index 3d9963d1b..cf3a28aec 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/Demo.pm @@ -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) diff --git a/lemonldap-ng-portal/t/59-Double-cookies-Refresh-and-Logout.t b/lemonldap-ng-portal/t/59-Double-cookies-Refresh-and-Logout.t index 99317ba86..83a52343a 100644 --- a/lemonldap-ng-portal/t/59-Double-cookies-Refresh-and-Logout.t +++ b/lemonldap-ng-portal/t/59-Double-cookies-Refresh-and-Logout.t @@ -116,8 +116,8 @@ ok( 'POST checkuser' ); my %attributes = map /(.+)?<\/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>/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); diff --git a/lemonldap-ng-portal/t/67-CheckUser.t b/lemonldap-ng-portal/t/67-CheckUser.t index 66466b8b9..f9ea333df 100644 --- a/lemonldap-ng-portal/t/67-CheckUser.t +++ b/lemonldap-ng-portal/t/67-CheckUser.t @@ -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%dwho%, 'Found value dwho' ) or explain( $res->[2]->[0], 'Value dwho' ); ok( $res->[2]->[0] !~ m%_2fDevices%, '_2fDevices NOT Found!' ) or explain( $res->[2]->[0], 'Value _2fDevices' ); -count(4); + +ok( $res->[2]->[0] =~ m%authMode%, 'Found macro authMode' ) + or explain( $res->[2]->[0], 'Macro Key authMode' ); +ok( $res->[2]->[0] =~ m%DEMO%, 'Found DEMO' ) + or explain( $res->[2]->[0], 'Macro Value DEMO' ); +ok( $res->[2]->[0] =~ m%real_authMode%, + 'Found macro real_authMode' ) + or explain( $res->[2]->[0], 'Macro Key real_authMode' ); +ok( $res->[2]->[0] =~ m%TOTP%, '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%
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%%, 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%%, 'Found trspan="checkUser"' ) + or explain( $res->[2]->[0], 'trspan="checkUser"' ); +ok( $res->[2]->[0] =~ m%authMode%, 'Found macro authMode' ) + or explain( $res->[2]->[0], 'Macro Key authMode' ); +ok( $res->[2]->[0] =~ m%DEMO%, '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%%, - 'TOTP code required' ) + +ok( $res->[2]->[0] =~ m%%, '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%%, 'Found trspan="checkUser"' ) + or explain( $res->[2]->[0], 'trspan="checkUser"' ); +ok( $res->[2]->[0] =~ m%authMode%, 'Found macro authMode' ) + or explain( $res->[2]->[0], 'Macro Key authMode' ); +ok( $res->[2]->[0] =~ m%TOTP%, '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%%, 'Found trspan="checkUserComputeSession"' ) + or explain( $res->[2]->[0], 'trspan="checkUserComputeSession"' ); +ok( $res->[2]->[0] =~ m%authMode%, 'Found macro authMode' ) + or explain( $res->[2]->[0], 'Macro Key authMode' ); +ok( $res->[2]->[0] =~ m%TOTP%, '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%%, 'Found trspan="checkUser"' ) + or explain( $res->[2]->[0], 'trspan="checkUser"' ); +ok( $res->[2]->[0] =~ m%authMode%, 'Found macro authMode' ) + or explain( $res->[2]->[0], 'Macro Key authMode' ); +ok( $res->[2]->[0] =~ m%DEMO%, 'Found DEMO' ) + or explain( $res->[2]->[0], 'Macro Value DEMO' ); +count(4); clean_sessions(); diff --git a/lemonldap-ng-portal/t/72-2F-REST-with-History.t b/lemonldap-ng-portal/t/72-2F-REST-with-History.t index ff0b13e47..e85bd69cf 100644 --- a/lemonldap-ng-portal/t/72-2F-REST-with-History.t +++ b/lemonldap-ng-portal/t/72-2F-REST-with-History.t @@ -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', diff --git a/lemonldap-ng-portal/t/lmConf-1.json b/lemonldap-ng-portal/t/lmConf-1.json index d4fd2d0a9..716daf346 100644 --- a/lemonldap-ng-portal/t/lmConf-1.json +++ b/lemonldap-ng-portal/t/lmConf-1.json @@ -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",