First version of adaptative authentication level plugin (#2336)

This commit is contained in:
Clément OUDOT 2020-10-02 15:05:15 +02:00
parent 475eb1fe1e
commit 6cccea0e46
3 changed files with 101 additions and 3 deletions

View File

@ -101,6 +101,7 @@ lib/Lemonldap/NG/Portal/Password/Demo.pm
lib/Lemonldap/NG/Portal/Password/LDAP.pm
lib/Lemonldap/NG/Portal/Password/Null.pm
lib/Lemonldap/NG/Portal/Password/REST.pm
lib/Lemonldap/NG/Portal/Plugins/AdaptativeAuthenticationLevel.pm
lib/Lemonldap/NG/Portal/Plugins/AutoSignin.pm
lib/Lemonldap/NG/Portal/Plugins/BruteForceProtection.pm
lib/Lemonldap/NG/Portal/Plugins/CDA.pm

View File

@ -2,7 +2,7 @@
# into "plugins" list in lemonldap-ng.ini, section "portal"
package Lemonldap::NG::Portal::Main::Plugins;
our $VERSION = '2.0.8';
our $VERSION = '2.0.10';
package Lemonldap::NG::Portal::Main;
@ -31,8 +31,10 @@ our @pList = (
impersonationRule => '::Plugins::Impersonation',
contextSwitchingRule => '::Plugins::ContextSwitching',
decryptValueRule => '::Plugins::DecryptValue',
globalLogoutRule => '::Plugins::GlobalLogout',
refreshSessions => '::Plugins::Refresh',
adaptativeAuthenticationLevelRules =>
'::Plugins::AdaptativeAuthenticationLevel',
globalLogoutRule => '::Plugins::GlobalLogout',
refreshSessions => '::Plugins::Refresh',
);
##@method list enabledPlugins

View File

@ -0,0 +1,95 @@
package Lemonldap::NG::Portal::Plugins::AdaptativeAuthenticationLevel;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
);
our $VERSION = '2.0.10';
extends 'Lemonldap::NG::Portal::Main::Plugin';
use constant afterData => 'adaptAuthenticationLevel';
has rules => ( is => 'rw', default => sub { {} } );
sub init {
my ($self) = @_;
$self->logger->debug('Init AdaptativeAuthenticationLevel plugin');
my $hd = $self->p->HANDLER;
foreach (
keys %{ $self->conf->{adaptativeAuthenticationLevelRules} // {} } )
{
$self->logger->debug("adaptativeAuthenticationLevelRules key -> $_");
$self->logger->debug( "adaptativeAuthenticationLevelRules value -> "
. $self->conf->{adaptativeAuthenticationLevelRules}->{$_} );
my $rule = $hd->buildSub( $hd->substitute($_) );
unless ($rule) {
my $error = $hd->tsv->{jail}->error || '???';
$self->logger->error(
"Bad AdaptativeAuthenticationLevel rule -> $error");
$self->logger->debug(
"Skipping AdaptativeAuthenticationLevel rule \"$_\"");
next;
}
$self->rules->{$_} = $rule;
}
return 1;
}
sub adaptAuthenticationLevel {
my ( $self, $req ) = @_;
my $userid = $req->user;
$self->logger->debug("Check adaptative authentication rules for $userid");
my $authenticationLevel = $req->sessionInfo->{authenticationLevel};
$self->logger->debug(
"Current authentication level for $userid is $authenticationLevel");
my $updatedAuthenticationLevel = $authenticationLevel;
sub sortByComment {
my $A = ( $a =~ /^.*?##(.*)$/ )[0];
my $B = ( $b =~ /^.*?##(.*)$/ )[0];
return !$A ? 1 : !$B ? -1 : $A cmp $B;
}
foreach ( sort sortByComment keys %{ $self->rules } ) {
my $rule = $_;
$self->logger->debug(
"Check adaptativeAuthenticationLevelRules -> $rule");
if ( $self->rules->{$_}->( $req, $req->sessionInfo ) ) {
my $levelOperation =
$self->conf->{adaptativeAuthenticationLevelRules}->{$_};
$self->logger->debug(
"User $userid match rule, apply $levelOperation on authentication level"
);
my ( $op, $level ) = ( $levelOperation =~ /([=+-])?(\d+)/ );
$updatedAuthenticationLevel = $level if ( !$op or $op eq '=' );
$updatedAuthenticationLevel += $level if ( $op and $op eq '+' );
$updatedAuthenticationLevel -= $level if ( $op and $op eq '-' );
$self->logger->debug(
"Authentication level for $userid is now $updatedAuthenticationLevel"
);
}
}
if ( $authenticationLevel ne $updatedAuthenticationLevel ) {
$self->logger->debug(
"Authentication level has changed for $userid, update session");
$self->p->updateSession(
$req,
{
'authenticationLevel' => $updatedAuthenticationLevel
}
);
}
return PE_OK;
}
1;