2018-02-23 09:11:19 +01:00
|
|
|
package Lemonldap::NG::Portal::2F::REST;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use Mouse;
|
|
|
|
use Lemonldap::NG::Portal::Main::Constants qw(
|
|
|
|
PE_BADCREDENTIALS
|
|
|
|
PE_ERROR
|
|
|
|
PE_FORMEMPTY
|
|
|
|
PE_OK
|
|
|
|
PE_SENDRESPONSE
|
|
|
|
);
|
|
|
|
|
|
|
|
our $VERSION = '2.0.0';
|
|
|
|
|
|
|
|
extends 'Lemonldap::NG::Portal::Main::SecondFactor',
|
|
|
|
'Lemonldap::NG::Portal::Lib::REST';
|
|
|
|
|
|
|
|
# INITIALIZATION
|
|
|
|
|
2018-03-19 17:21:50 +01:00
|
|
|
has prefix => ( is => 'ro', default => 'rest' );
|
2018-02-23 09:11:19 +01:00
|
|
|
|
2018-03-19 16:58:26 +01:00
|
|
|
has initAttrs => ( is => 'rw', default => sub { {} } );
|
2018-02-23 09:11:19 +01:00
|
|
|
|
2018-03-19 16:58:26 +01:00
|
|
|
has vrfyAttrs => ( is => 'rw', default => sub { {} } );
|
2018-02-23 09:11:19 +01:00
|
|
|
|
|
|
|
sub init {
|
|
|
|
my ($self) = @_;
|
|
|
|
unless ( $self->conf->{rest2fVerifyUrl} ) {
|
|
|
|
$self->logger->error('Missing REST verification URL');
|
|
|
|
return 0;
|
|
|
|
}
|
2018-03-15 22:22:20 +01:00
|
|
|
$self->logo( $self->conf->{rest2fLogo} ) if ( $self->conf->{rest2fLogo} );
|
2018-02-23 09:11:19 +01:00
|
|
|
foreach my $k ( keys %{ $self->conf->{rest2fInitArgs} } ) {
|
|
|
|
my $attr = $self->conf->{rest2fInitArgs}->{$k};
|
|
|
|
$attr =~ s/^$//;
|
|
|
|
unless ( $attr =~ /^\w+$/ ) {
|
|
|
|
$self->logger->error(
|
|
|
|
"2F REST: $k key must point to a single attribute or macro");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
$self->initAttrs->{$k} = $attr;
|
|
|
|
}
|
|
|
|
foreach my $k ( keys %{ $self->conf->{rest2fVerifyArgs} } ) {
|
|
|
|
my $attr = $self->conf->{rest2fVerifyArgs}->{$k};
|
|
|
|
$attr =~ s/^$//;
|
|
|
|
unless ( $attr =~ /^\w+$/ ) {
|
|
|
|
$self->logger->error(
|
|
|
|
"2F REST: $k key must point to a single attribute or macro");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
$self->vrfyAttrs->{$k} = $attr;
|
|
|
|
}
|
2018-03-19 17:34:21 +01:00
|
|
|
return $self->SUPER::init();
|
2018-02-23 09:11:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub run {
|
|
|
|
my ( $self, $req, $token ) = @_;
|
|
|
|
|
|
|
|
if ( $self->conf->{rest2fInitUrl} ) {
|
|
|
|
|
|
|
|
# Prepare args
|
2018-03-19 16:58:26 +01:00
|
|
|
my $args = {};
|
2018-02-23 09:11:19 +01:00
|
|
|
foreach my $k ( keys %{ $self->{initAttrs} } ) {
|
|
|
|
$args->{$k} = $req->sessionInfo->{ $self->{initAttrs}->{$k} };
|
|
|
|
}
|
|
|
|
|
|
|
|
# Launch REST request
|
|
|
|
$self->logger->debug('Call REST init URL');
|
|
|
|
my $res =
|
|
|
|
eval { $self->restCall( $self->conf->{rest2fInitUrl}, $args ); };
|
|
|
|
if ($@) {
|
|
|
|
$self->logger->error("REST 2F error: $@");
|
|
|
|
return PE_ERROR;
|
|
|
|
}
|
|
|
|
unless ( $res->{result} ) {
|
|
|
|
$self->logger->error("REST 2F initialization has failed");
|
|
|
|
return PE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$self->logger->debug('No init URL, skipping initialization');
|
|
|
|
}
|
|
|
|
|
|
|
|
# Prepare form
|
|
|
|
my $tmp = $self->p->sendHtml(
|
|
|
|
$req,
|
|
|
|
'ext2fcheck',
|
|
|
|
params => {
|
2018-03-19 17:34:21 +01:00
|
|
|
SKIN => $self->conf->{portalSkin},
|
|
|
|
TOKEN => $token,
|
2018-03-19 17:21:50 +01:00
|
|
|
TARGET => '/rest2fcheck',
|
2018-02-23 09:11:19 +01:00
|
|
|
}
|
|
|
|
);
|
|
|
|
$self->logger->debug("Prepare external REST verification");
|
|
|
|
|
|
|
|
$req->response($tmp);
|
|
|
|
return PE_SENDRESPONSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub verify {
|
|
|
|
my ( $self, $req, $session ) = @_;
|
|
|
|
my $code;
|
|
|
|
unless ( $code = $req->param('code') ) {
|
|
|
|
$self->userLogger->error('External REST 2F: no code');
|
|
|
|
return PE_FORMEMPTY;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Prepare args
|
2018-03-19 16:58:26 +01:00
|
|
|
my $args = {};
|
2018-02-23 09:11:19 +01:00
|
|
|
foreach my $k ( keys %{ $self->{vrfyAttrs} } ) {
|
2018-03-13 07:14:01 +01:00
|
|
|
$args->{$k} = (
|
|
|
|
$k eq 'code'
|
2018-02-23 09:51:14 +01:00
|
|
|
? $code
|
2018-03-13 07:14:01 +01:00
|
|
|
: $req->sessionInfo->{ $self->{vrfyAttrs}->{$k} }
|
|
|
|
);
|
2018-02-23 09:11:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Launch REST request
|
|
|
|
$self->logger->debug('Call REST vrfy URL');
|
|
|
|
my $res =
|
2018-02-23 09:38:33 +01:00
|
|
|
eval { $self->restCall( $self->conf->{rest2fVerifyUrl}, $args ); };
|
2018-02-23 09:11:19 +01:00
|
|
|
if ($@) {
|
|
|
|
$self->logger->error("REST 2F error: $@");
|
|
|
|
return PE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Result
|
|
|
|
unless ( $res->{result} ) {
|
|
|
|
$self->userLogger->warn( 'REST Second factor failed for '
|
|
|
|
. $session->{ $self->conf->{whatToTrace} } );
|
|
|
|
return PE_BADCREDENTIALS;
|
|
|
|
}
|
|
|
|
PE_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|