Commit f2e481d6 authored by Christophe Maudoux's avatar Christophe Maudoux

Display delete button only if allowed (#1622)

parent f2fcdaf3
......@@ -13,11 +13,11 @@ use strict;
use Mouse;
use JSON qw(from_json to_json);
use Lemonldap::NG::Portal::Main::Constants qw(
PE_ERROR
PE_NOTOKEN
PE_OK
PE_SENDRESPONSE
PE_TOKENEXPIRED
PE_ERROR
PE_NOTOKEN
PE_OK
PE_SENDRESPONSE
PE_TOKENEXPIRED
);
our $VERSION = '2.0.1';
......@@ -36,8 +36,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;
}
......@@ -55,7 +55,7 @@ sub init {
? 'available2FSelfRegistration'
: 'available2F'
}
)
)
{
my $prefix = lc($_);
$prefix =~ s/2f$//i;
......@@ -67,9 +67,10 @@ sub init {
# Unless $rule, skip loading
if ( $self->conf->{$ap} ) {
$self->logger->debug("Trying to load $_ 2F");
my $m =
$self->p->loadPlugin( $i ? "::2F::Register::$_" : "::2F::$_" )
or return 0;
my $m
= $self->p->loadPlugin(
$i ? "::2F::Register::$_" : "::2F::$_" )
or return 0;
# Rule and prefix may be modified by 2F module, reread them
my $rule = $self->conf->{$ap};
......@@ -79,13 +80,13 @@ sub init {
$rule = $self->p->HANDLER->substitute($rule);
unless ( $rule = $self->p->HANDLER->buildSub($rule) ) {
$self->error( 'External 2F rule error: '
. $self->p->HANDLER->tsv->{jail}->error );
. $self->p->HANDLER->tsv->{jail}->error );
return 0;
}
# Store module
push @{ $self->{ $i ? 'sfRModules' : 'sfModules' } },
{ p => $prefix, m => $m, r => $rule };
{ p => $prefix, m => $m, r => $rule };
}
else {
$self->logger->debug(' -> not enabled');
......@@ -99,10 +100,10 @@ sub init {
$self->p->HANDLER->substitute( $self->conf->{sfRequired} )
)
)
)
)
{
$self->error( 'Error in sfRequired rule'
. $self->p->HANDLER->tsv->{jail}->error );
. $self->p->HANDLER->tsv->{jail}->error );
return 0;
}
......@@ -163,13 +164,12 @@ sub run {
if ( $self->sfReq->( $req, $req->sessionInfo ) ) {
$self->logger->debug("2F is required...");
$self->logger->debug(" -> Register 2F");
$req->pdata->{sfRegToken} =
$self->ott->createToken( $req->sessionInfo );
$req->pdata->{sfRegToken}
= $self->ott->createToken( $req->sessionInfo );
$self->logger->debug("Just one 2F is enabled");
$self->logger->debug(" -> Redirect to 2fregisters/");
$req->response(
[
302,
[ 302,
[ Location => $self->conf->{portal} . '2fregisters/' ], []
]
);
......@@ -181,7 +181,7 @@ sub run {
}
$self->userLogger->info( 'Second factor required for '
. $req->sessionInfo->{ $self->conf->{whatToTrace} } );
. $req->sessionInfo->{ $self->conf->{whatToTrace} } );
# Store user data in a token
$req->sessionInfo->{_2fRealSession} = $req->id;
......@@ -206,7 +206,8 @@ sub run {
MAIN_LOGO => $self->conf->{portalMainLogo},
SKIN => $self->conf->{portalSkin},
TOKEN => $token,
MODULES => [ map { { CODE => $_->prefix, LOGO => $_->logo } } @am ],
MODULES =>
[ map { { CODE => $_->prefix, LOGO => $_->logo } } @am ],
CHECKLOGINS => $checkLogins
}
);
......@@ -232,15 +233,16 @@ sub _choice {
# Restore session
unless ( $token = $req->param('token') ) {
$self->userLogger->error( $self->prefix . ' 2F access without token' );
$self->userLogger->error(
$self->prefix . ' 2F access without token' );
$req->mustRedirect(1);
return $self->p->do( $req, [ sub { PE_NOTOKEN } ] );
return $self->p->do( $req, [ sub {PE_NOTOKEN} ] );
}
my $session;
unless ( $session = $self->ott->getToken($token) ) {
$self->userLogger->info('Token expired');
return $self->p->do( $req, [ sub { PE_TOKENEXPIRED } ] );
return $self->p->do( $req, [ sub {PE_TOKENEXPIRED} ] );
}
$req->sessionInfo($session);
......@@ -255,8 +257,7 @@ sub _choice {
$req->authResult($res);
return $self->p->do(
$req,
[
sub { $res }, 'controlUrl',
[ sub {$res}, 'controlUrl',
'buildCookie', @{ $self->p->endAuth },
]
);
......@@ -271,10 +272,7 @@ sub _redirect {
my $arg = $req->env->{QUERY_STRING};
$self->logger->debug('Call sfEngine _redirect method');
return [
302,
[
Location => $self->conf->{portal} . ( $arg ? "?$arg" : '' )
],
302, [ Location => $self->conf->{portal} . ( $arg ? "?$arg" : '' ) ],
[]
];
}
......@@ -286,8 +284,8 @@ sub _displayRegister {
# - display template if $tpl
# - else display choice template
if ($tpl) {
my ($m) =
grep { $_->{m}->prefix eq $tpl } @{ $self->sfRModules };
my ($m)
= grep { $_->{m}->prefix eq $tpl } @{ $self->sfRModules };
unless ($m) {
return $self->p->sendError( $req,
'Inexistent register module', 400 );
......@@ -307,34 +305,56 @@ sub _displayRegister {
'Looking if ' . $m->{m}->prefix . '2F register is available' );
if ( $m->{r}->( $req, $req->userData ) ) {
push @am,
{
{
CODE => $m->{m}->prefix,
URL => '/2fregisters/' . $m->{m}->prefix,
LOGO => $m->{m}->logo,
};
};
}
}
if (
@am == 1
if (@am == 1
and not( $req->userData->{_2fDevices}
or $req->data->{sfRegRequired} )
)
)
{
return [ 302, [ Location => $self->conf->{portal} . $am[0]->{URL} ],
[] ];
}
my $_2fDevices =
$req->userData->{_2fDevices}
? eval { from_json( $req->userData->{_2fDevices},
{ allow_nonref => 1 } ); }
: undef;
# Retrieve user all second factors
my $_2fDevices = $req->userData->{_2fDevices}
? eval {
from_json( $req->userData->{_2fDevices}, { allow_nonref => 1 } );
}
: undef;
unless ($_2fDevices) {
$self->logger->debug("No 2F Device found");
$_2fDevices = [];
}
# Parse second factors to display delete button if allowed
foreach (@$_2fDevices) {
if ( $_->{type} eq 'U2F' ) {
$_->{delAllowed}
= $self->conf->{u2fActivation}
&& $self->conf->{u2fUserCanRemoveKey}
&& $self->conf->{u2fSelfRegistration};
}
if ( $_->{type} eq 'TOTP' ) {
$_->{delAllowed}
= $self->conf->{totp2fActivation}
&& $self->conf->{totp2fUserCanRemoveKey}
&& $self->conf->{totp2fSelfRegistration};
}
if ( $_->{type} eq 'UBK' ) {
$_->{delAllowed}
= $self->conf->{yubikey2fActivation}
&& $self->conf->{yubikey2fUserCanRemoveKey}
&& $self->conf->{yubikey2fSelfRegistration};
}
}
# Display template
return $self->p->sendHtml(
$req,
'2fregisters',
......@@ -356,8 +376,8 @@ sub register {
# - call register run method if $tpl
# - else give JSON list of available registers for this user
if ($tpl) {
my ($m) =
grep { $_->{m}->prefix eq $tpl } @{ $self->sfRModules };
my ($m)
= grep { $_->{m}->prefix eq $tpl } @{ $self->sfRModules };
unless ($m) {
return $self->p->sendError( $req,
'Inexistent register module', 400 );
......@@ -376,11 +396,11 @@ sub register {
$self->logger->debug(' -> OK');
my $name = $m->{m}->prefix;
push @am,
{
{
name => $name,
logo => $m->{m}->logo,
url => "/2fregisters/$name"
};
};
}
}
return $self->p->sendJSONresponse( $req, \@am );
......@@ -389,12 +409,12 @@ sub register {
sub restoreSession {
my ( $self, $req, @path ) = @_;
my $token = $req->pdata->{sfRegToken}
or return [ 302, [ Location => $self->conf->{portal} ], [] ];
or return [ 302, [ Location => $self->conf->{portal} ], [] ];
$req->userData( $self->ott->getToken( $token, 1 ) );
$req->data->{sfRegRequired} = 1;
return $req->method eq 'POST'
? $self->register( $req, @path )
: $self->_displayRegister( $req, @path );
? $self->register( $req, @path )
: $self->_displayRegister( $req, @path );
}
1;
......@@ -27,11 +27,13 @@
<td class="align-middle"><TMPL_VAR NAME="name"></td>
<td class="data-epoch"><TMPL_VAR NAME="epoch"></td>
<td>
<span device='<TMPL_VAR NAME="type">' epoch='<TMPL_VAR NAME="epoch">' class="btn btn-danger" role="button">
<span class="fa fa-minus-circle"></span>
<span trspan="unregister">Unregister</span>
</span>
</td>
<TMPL_IF NAME="delAllowed">
<span device='<TMPL_VAR NAME="type">' epoch='<TMPL_VAR NAME="epoch">' class="btn btn-danger" role="button">
<span class="fa fa-minus-circle"></span>
<span trspan="unregister">Unregister</span>
</span>
</TMPL_IF>
</td>
</tr>
</TMPL_LOOP>
</tbody>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment