diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm index 8e0791e0e..b22592864 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Engines/Default.pm @@ -359,11 +359,14 @@ sub run { $req, '2fchoice', params => { - MAIN_LOGO => $self->conf->{portalMainLogo}, - SKIN => $self->p->getSkin($req), - LANGS => $self->conf->{showLanguages}, - TOKEN => $token, - MODULES => [ + MAIN_LOGO => $self->conf->{portalMainLogo}, + SKIN => $self->p->getSkin($req), + LANGS => $self->conf->{showLanguages}, + CHECKLOGINS => $checkLogins, + TOKEN => $token, + MSG => $self->canUpdateSfa($req) || 'choose2f', + ALERT => ( $self->canUpdateSfa($req) ? 'warning' : 'positive' ), + MODULES => [ map { { CODE => $_->prefix, LOGO => $_->logo, @@ -371,7 +374,6 @@ sub run { } } @am ], - CHECKLOGINS => $checkLogins } ); $req->response($tpl); @@ -458,6 +460,8 @@ sub _displayRegister { params => { MAIN_LOGO => $self->conf->{portalMainLogo}, LANGS => $self->conf->{showLanguages}, + MSG => $self->canUpdateSfa($req) || $m->{m}->welcome, + ALERT => ( $self->canUpdateSfa($req) ? 'warning' : 'positive' ), } ); } @@ -486,7 +490,7 @@ sub _displayRegister { # Retrieve user all second factors my $_2fDevices = []; - if ( $self->allowedUpdateSfa($req) ) { + unless ( $self->canUpdateSfa($req) ) { $_2fDevices = $req->userData->{_2fDevices} ? eval { from_json( $req->userData->{_2fDevices}, { allow_nonref => 1 } ); @@ -543,6 +547,8 @@ sub _displayRegister { ACTION => $action, REG_REQUIRED => $req->data->{sfRegRequired}, DISPLAY_UPG => $displayUpgBtn, + MSG => $self->canUpdateSfa($req) || 'choose2f', + ALERT => ( $self->canUpdateSfa($req) ? 'warning' : 'positive' ), SFREGISTERS_URL => encode_base64( "$self->{conf}->{portal}2fregisters", '' ) } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm index 9692917fa..2510bdb99 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm @@ -13,6 +13,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin', 'Lemonldap::NG::Common::TOTP'; has prefix => ( is => 'rw', default => 'totp' ); has template => ( is => 'ro', default => 'totp2fregister' ); +has welcome => ( is => 'ro', default => 'yourNewTotpKey' ); has logo => ( is => 'rw', default => 'totp.png' ); has ott => ( is => 'rw', @@ -37,8 +38,8 @@ sub run { unless $user; # Check if TOTP can be updated - return $self->p->sendError( $req, 'notAuthorizedAuthLevel', 400 ) - unless $self->allowedUpdateSfa( $req, $action ); + my $msg = $self->canUpdateSfa( $req, $action ); + return $self->p->sendError( $req, $msg, 400 ) if $msg; # Verification that user has a valid TOTP app if ( $action eq 'verify' ) { diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm index 33a6039c7..0b93f290e 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm @@ -14,6 +14,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin', has prefix => ( is => 'rw', default => 'u' ); has template => ( is => 'ro', default => 'u2fregister' ); +has welcome => ( is => 'ro', default => 'u2fWelcome' ); has logo => ( is => 'rw', default => 'u2f.png' ); sub init { @@ -34,8 +35,8 @@ sub run { unless $user; # Check if U2F key can be updated - return $self->p->sendError( $req, 'notAuthorizedAuthLevel', 400 ) - unless $self->allowedUpdateSfa( $req, $action ); + my $msg = $self->canUpdateSfa( $req, $action ); + return $self->p->sendError( $req, $msg, 400 ) if $msg; if ( $action eq 'register' ) { diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm index d37602cb6..ec7a58443 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm @@ -17,6 +17,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin'; has prefix => ( is => 'rw', default => 'yubikey' ); has template => ( is => 'ro', default => 'yubikey2fregister' ); +has welcome => ( is => 'ro', default => 'clickOnYubikey' ); has logo => ( is => 'rw', default => 'yubikey.png' ); sub init { @@ -35,6 +36,7 @@ sub run { unless $user; # Check if UBK key can be updated + my $msg = $self->canUpdateSfa( $req, $action ); return $self->p->sendHtml( $req, 'error', params => { @@ -42,7 +44,7 @@ sub run { RAW_ERROR => 'notAuthorizedAuthLevel', AUTH_ERROR_TYPE => 'warning', } - ) unless $self->allowedUpdateSfa( $req, $action ); + ) if $msg; if ( $action eq 'register' ) { my $otp = $req->param('otp'); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm index b3744615c..b20ad9ffe 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm @@ -104,10 +104,10 @@ sub createNotification { } } -sub allowedUpdateSfa { +sub canUpdateSfa { my ( $self, $req, $action ) = @_; my $user = $req->userData->{ $self->conf->{whatToTrace} }; - my $res = 1; + my $msg = undef; # Test action if ( $action && $action eq 'delete' ) { @@ -125,12 +125,12 @@ sub allowedUpdateSfa { $self->logger->debug( "authLevel: $req->{userData}->{authenticationLevel} < requiredLevel: " . $self->{conf}->{"${module}2fAuthnLevel"} ); - undef $res; + $msg = 'notAuthorizedAuthLevel'; } } # Test if impersonation is in progress - if ( $res && $self->conf->{impersonationRule} ) { + if ( !$msg && $self->conf->{impersonationRule} ) { $self->logger->debug('Impersonation plugin is enabled'); if ( $req->userData->{"$self->{conf}->{impersonationPrefix}_user"} && $req->userData->{"$self->{conf}->{impersonationPrefix}_user"} ne @@ -139,12 +139,12 @@ sub allowedUpdateSfa { $self->userLogger->warn( "Impersonation in progress! $user is not allowed to update 2FA." ); - undef $res; + $msg = 'notAuthorized'; } } # Test if contextSwitching is in progress - if ( $res && $self->conf->{contextSwitchingRule} ) { + if ( !$msg && $self->conf->{contextSwitchingRule} ) { $self->logger->debug('ContextSwitching plugin is enabled'); if ( $req->userData->{ @@ -154,11 +154,11 @@ sub allowedUpdateSfa { $self->userLogger->warn( "ContextSwitching in progress! $user is not allowed to update 2FA." ); - undef $res; + $msg = 'notAuthorized'; } } - $self->userLogger->info("$user is allowed to update 2FA") if $res; - return $res; + $self->userLogger->info("$user is allowed to update 2FA") unless $msg; + return $msg; } 1; diff --git a/lemonldap-ng-portal/site/templates/bootstrap/2fchoice.tpl b/lemonldap-ng-portal/site/templates/bootstrap/2fchoice.tpl index bf590f93c..98e04c1e2 100644 --- a/lemonldap-ng-portal/site/templates/bootstrap/2fchoice.tpl +++ b/lemonldap-ng-portal/site/templates/bootstrap/2fchoice.tpl @@ -1,7 +1,7 @@
-
+
alert" trspan="">
" /> diff --git a/lemonldap-ng-portal/site/templates/bootstrap/2fregisters.tpl b/lemonldap-ng-portal/site/templates/bootstrap/2fregisters.tpl index c4908f87b..1aa0f4558 100644 --- a/lemonldap-ng-portal/site/templates/bootstrap/2fregisters.tpl +++ b/lemonldap-ng-portal/site/templates/bootstrap/2fregisters.tpl @@ -1,11 +1,11 @@
-
+
alert"> - + ">
diff --git a/lemonldap-ng-portal/site/templates/bootstrap/totp2fregister.tpl b/lemonldap-ng-portal/site/templates/bootstrap/totp2fregister.tpl index 226e0a7f8..3f2ab2966 100644 --- a/lemonldap-ng-portal/site/templates/bootstrap/totp2fregister.tpl +++ b/lemonldap-ng-portal/site/templates/bootstrap/totp2fregister.tpl @@ -2,7 +2,7 @@
-
+
alert">">
diff --git a/lemonldap-ng-portal/site/templates/bootstrap/u2fregister.tpl b/lemonldap-ng-portal/site/templates/bootstrap/u2fregister.tpl index 9093e5054..08f162161 100644 --- a/lemonldap-ng-portal/site/templates/bootstrap/u2fregister.tpl +++ b/lemonldap-ng-portal/site/templates/bootstrap/u2fregister.tpl @@ -2,7 +2,7 @@
-
+
alert">">
diff --git a/lemonldap-ng-portal/site/templates/bootstrap/yubikey2fregister.tpl b/lemonldap-ng-portal/site/templates/bootstrap/yubikey2fregister.tpl index ddb837a38..cc9734105 100644 --- a/lemonldap-ng-portal/site/templates/bootstrap/yubikey2fregister.tpl +++ b/lemonldap-ng-portal/site/templates/bootstrap/yubikey2fregister.tpl @@ -2,7 +2,7 @@
-
+
alert">">
diff --git a/lemonldap-ng-portal/t/68-ContextSwitching-with-2F.t b/lemonldap-ng-portal/t/68-ContextSwitching-with-2F.t index 5b41adc3c..ed15ab871 100644 --- a/lemonldap-ng-portal/t/68-ContextSwitching-with-2F.t +++ b/lemonldap-ng-portal/t/68-ContextSwitching-with-2F.t @@ -332,7 +332,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ), 'Form 2fregisters' ); - ok( $res->[2]->[0] =~ //, + ok( $res->[2]->[0] =~ //, 'Found choose 2F' ) or print STDERR Dumper( $res->[2]->[0] ); ok( $res->[2]->[0] !~ m%[2]->[0] ) }; ok( not($@), 'Content is JSON' ) or explain( $res->[2]->[0], 'JSON content' ); - ok( $res->{error} eq 'notAuthorizedAuthLevel', 'Not authorized to register a TOTP' ) + ok( $res->{error} eq 'notAuthorized', 'Not authorized to register a TOTP' ) or explain( $res, 'Bad result' ); # Try to unregister TOTP @@ -386,7 +386,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); ok( - $data->{error} eq 'notAuthorizedAuthLevel', + $data->{error} eq 'notAuthorized', 'Not authorized to unregister a TOTP' ) or explain( $data, 'Bad result' ); @@ -404,7 +404,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== eval { $data = JSON::from_json( $res->[2]->[0] ) }; ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); - ok( $data->{error} eq 'notAuthorizedAuthLevel', 'Not authorized to verify a TOTP' ) + ok( $data->{error} eq 'notAuthorized', 'Not authorized to verify a TOTP' ) or explain( $data, 'Bad result' ); ## Try to register an U2F key @@ -437,7 +437,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); ok( - $data->{error} eq 'notAuthorizedAuthLevel', + $data->{error} eq 'notAuthorized', 'Not authorized to register an U2F key' ) or explain( $data, 'Bad result' ); @@ -455,7 +455,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); ok( - $data->{error} eq 'notAuthorizedAuthLevel', + $data->{error} eq 'notAuthorized', 'Not authorized to unregister an U2F key' ) or explain( $data, 'Bad result' ); diff --git a/lemonldap-ng-portal/t/68-Impersonation-with-2F.t b/lemonldap-ng-portal/t/68-Impersonation-with-2F.t index 5aeb6b3ab..99c2cafbc 100644 --- a/lemonldap-ng-portal/t/68-Impersonation-with-2F.t +++ b/lemonldap-ng-portal/t/68-Impersonation-with-2F.t @@ -272,7 +272,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ), 'Form 2fregisters' ); - ok( $res->[2]->[0] =~ //, + ok( $res->[2]->[0] =~ //, 'Found choose 2F' ) or print STDERR Dumper( $res->[2]->[0] ); ok( $res->[2]->[0] !~ m%[2]->[0] ) }; ok( not($@), 'Content is JSON' ) or explain( $res->[2]->[0], 'JSON content' ); - ok( $res->{error} eq 'notAuthorizedAuthLevel', 'Not authorized to register a TOTP' ) + ok( $res->{error} eq 'notAuthorized', 'Not authorized to register a TOTP' ) or explain( $res, 'Bad result' ); # Try to unregister TOTP @@ -326,7 +326,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); ok( - $data->{error} eq 'notAuthorizedAuthLevel', + $data->{error} eq 'notAuthorized', 'Not authorized to unregister a TOTP' ) or explain( $data, 'Bad result' ); @@ -344,7 +344,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== eval { $data = JSON::from_json( $res->[2]->[0] ) }; ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); - ok( $data->{error} eq 'notAuthorizedAuthLevel', 'Not authorized to verify a TOTP' ) + ok( $data->{error} eq 'notAuthorized', 'Not authorized to verify a TOTP' ) or explain( $data, 'Bad result' ); ## Try to register an U2F key @@ -377,7 +377,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); ok( - $data->{error} eq 'notAuthorizedAuthLevel', + $data->{error} eq 'notAuthorized', 'Not authorized to register an U2F key' ) or explain( $data, 'Bad result' ); @@ -395,7 +395,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ== ok( not($@), ' Content is JSON' ) or explain( [ $@, $res->[2] ], 'JSON content' ); ok( - $data->{error} eq 'notAuthorizedAuthLevel', + $data->{error} eq 'notAuthorized', 'Not authorized to unregister an U2F key' ) or explain( $data, 'Bad result' );