Add delete function to TOTP & Yubikey - TODO : Verify if user is authorized to delete (#1386)

This commit is contained in:
Christophe Maudoux 2018-04-03 00:01:01 +02:00
parent 6b27054603
commit 0637601d8b
3 changed files with 99 additions and 50 deletions

View File

@ -65,18 +65,16 @@ sub run {
# Now check TOTP code to verify that user has a valid TOTP app
my $code = $req->param('code');
my $TOTPName = $req->param('TOTPName');
unless ($code) {
$self->logger->userInfo('TOTP registration: empty validation form');
return $self->p->sendError( $req, 'missingCode', 200 );
}
#unless ( $code and $TOTPName ) {
#$self->logger->userInfo(
#'TOTP registration: empty code or name in validation form');
#return $self->p->sendError( $req, 'missingCode', 200 );
#$self->logger->userInfo(
#'TOTP registration: empty code or name in validation form');
#return $self->p->sendError( $req, 'missingCode', 200 );
#}
my $r = $self->verifyCode(
$self->conf->{totp2fInterval},
@ -111,13 +109,14 @@ sub run {
}
push @{$list2FDevices},
{
type => 'totp',
type => 'TOTP',
name => $TOTPName,
_secret => $token->{_totp2fSecret},
epoch => time()
};
#$self->logger->debug(
#"Append 2F Device : { type => 'totp', name => $TOTPName }");
#"Append 2F Device : { type => 'totp', name => $TOTPName }");
$self->p->updatePersistentSession( $req,
{ list2FDevices => to_json($list2FDevices) } );
@ -190,6 +189,33 @@ sub run {
}
}
elsif ( $action eq 'delete' ) {
my $epoch = $req->param('epoch');
my $list2FDevices = eval {
$self->logger->debug("Loading 2F Devices ...");
# Read existing 2FDevices
from_json( $req->userData->{list2FDevices}, { allow_nonref => 1 } );
};
my @keep = ();
while (@$list2FDevices) {
my $element = shift @$list2FDevices;
$self->logger->debug("Looking for 2F Device to delete ...");
push @keep, $element unless ( $element->{epoch} eq $epoch );
}
$self->logger->debug(
"Delete 2F Device : { type => 'TOTP', epoch => $epoch }");
$self->p->updatePersistentSession( $req,
{ list2FDevices => to_json( \@keep ) } );
$self->userLogger->notice('TOTP deletion succeed');
return [ 200, [ 'Content-Type' => 'application/json' ],
['{"result":1}'] ];
}
}
1;

View File

@ -66,42 +66,40 @@ sub run {
my $list2FDevices = eval {
$self->logger->debug("Looking for 2F Devices ...");
# Read existing 2FDevices
from_json( $req->userData->{list2FDevices},
{ allow_nonref => 1 } );
};
unless ($list2FDevices) {
$self->logger->debug("No 2F Device found");
# Set default value
$list2FDevices = [];
}
my $keyName = $req->param('keyName');
$self->logger->debug("Key name : $keyName");
# Select U2F Devices only
#my @listU2FKeys = map {
#( $_->{type} eq "U2F" ) ? return $_ : return ();
#} @{$list2FDevices};
#( $_->{type} eq "U2F" ) ? return $_ : return ();
#} @{$list2FDevices};
#$self->logger->debug("Select U2F Devices only ...");
# Search if U2F Key has been already registered
my $SameU2FKeyFound = 0;
foreach ( @$list2FDevices ) {
$self->logger->debug("Reading U2F Keys ...");
$SameU2FKeyFound ||= 1 if ( ( $_->{name} eq $keyName ) );
};
$self->logger->debug("Same 2F Device found ? $SameU2FKeyFound");
foreach (@$list2FDevices) {
$self->logger->debug("Reading U2F Keys ...");
$SameU2FKeyFound ||= 1 if ( ( $_->{name} eq $keyName ) );
}
$self->logger->debug("Same 2F Device found ? $SameU2FKeyFound");
if ($SameU2FKeyFound) {
$self->userLogger->error("U2F Key already registered !");
return $self->p->sendError( $req, 'Bad challenge', 400 );
}
$self->userLogger->error("U2F Key already registered !");
return $self->p->sendError( $req, 'Bad challenge', 400 );
}
push @{$list2FDevices},
{
type => 'U2F',
@ -218,33 +216,27 @@ sub run {
return $self->p->sendError( $req, $err, 200 );
}
elsif ( $action eq 'delete' ) {
my $epoch = $req->param('epoch');
my $list2FDevices = eval {
$self->logger->debug("Looking for 2F Devices ...");
my $epoch = $req->param('epoch');
my $list2FDevices = eval {
$self->logger->debug("Loading 2F Devices ...");
# Read existing 2FDevices
from_json( $req->userData->{list2FDevices},
{ allow_nonref => 1 } );
from_json( $req->userData->{list2FDevices}, { allow_nonref => 1 } );
};
my @keep = ();
while ( @$list2FDevices ) {
my $element = shift @$list2FDevices;
push @keep, $element unless ( $element->{epoch} eq $epoch );
}
$self->logger->debug(
"Delete 2F Device : { type => 'U2F', epoch => $epoch }");
my @keep = ();
while (@$list2FDevices) {
my $element = shift @$list2FDevices;
$self->logger->debug("Looking for 2F Device to delete ...");
push @keep, $element unless ( $element->{epoch} eq $epoch );
}
$self->logger->debug(
"Delete 2F Device : { type => 'U2F', epoch => $epoch }");
$self->p->updatePersistentSession( $req,
{ list2FDevices => to_json(\@keep) } );
{ list2FDevices => to_json( \@keep ) } );
$self->p->updatePersistentSession(
$req,
{

View File

@ -85,6 +85,37 @@ sub run {
);
}
}
elsif ( $action eq 'delete' ) {
my $epoch = $req->param('epoch');
my $list2FDevices = eval {
$self->logger->debug("Loading 2F Devices ...");
# Read existing 2FDevices
from_json( $req->userData->{list2FDevices}, { allow_nonref => 1 } );
};
my @keep = ();
while (@$list2FDevices) {
my $element = shift @$list2FDevices;
$self->logger->debug("Looking for 2F Device to delete ...");
push @keep, $element unless ( $element->{epoch} eq $epoch );
}
$self->logger->debug(
"Delete 2F Device : { type => 'UBK', epoch => $epoch }");
$self->p->updatePersistentSession( $req,
{ list2FDevices => to_json( \@keep ) } );
$self->userLogger->notice('Yubikey deletion succeed');
return [
200,
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
['{"result":1}']
];
}
else {
$self->userLogger->error("Unknown Yubikey action $action");
return $self->p->sendHtml(