2017-02-05 14:11:14 +01:00
|
|
|
package Lemonldap::NG::Portal::Auth::Combination;
|
2017-02-05 13:24:26 +01:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use Mouse;
|
|
|
|
use Lemonldap::NG::Common::Combination::Parser;
|
|
|
|
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_ERROR);
|
|
|
|
|
|
|
|
# TODO: See Lib::Wrapper
|
|
|
|
extends 'Lemonldap::NG::Portal::Auth::Base';
|
|
|
|
|
|
|
|
# PROPERTIES
|
|
|
|
|
|
|
|
has stackSub => ( is => 'rw' );
|
|
|
|
|
|
|
|
# INITIALIZATION
|
|
|
|
|
|
|
|
sub init {
|
|
|
|
my ($self) = @_;
|
2017-02-05 14:11:14 +01:00
|
|
|
unless ( $self->conf->{combination} ) {
|
2017-02-05 13:24:26 +01:00
|
|
|
$self->error('No combination found');
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
my %mods;
|
|
|
|
foreach my $mod ( @{ $self->conf->{combModules} } ) {
|
|
|
|
my @tmp = ( undef, undef );
|
|
|
|
|
|
|
|
# TODO: override params
|
|
|
|
if ( $mod->{for} < 2 ) {
|
|
|
|
$tmp[0] = $self->p->loadPlugin("::Auth::$mod->{type}");
|
|
|
|
unless ( $tmp[0] ) {
|
|
|
|
$self->error("Unable to load Auth::$mod->{type}");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unless ( $mod->{for} == 1 ) {
|
|
|
|
$tmp[1] = $self->p->loadPlugin("::UserDB::$mod->{type}");
|
|
|
|
unless ( $tmp[1] ) {
|
|
|
|
$self->error("Unable to load UserDB::$mod->{type}");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$mods{ $mod->{name} } = \@tmp;
|
|
|
|
}
|
|
|
|
eval {
|
|
|
|
$self->stackSub(
|
|
|
|
Lemonldap::NG::Common::Combination::Parser->parse(
|
2017-02-05 14:11:14 +01:00
|
|
|
\%mods, $self->conf->{combination}
|
2017-02-05 13:24:26 +01:00
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
|
|
|
if ($@) {
|
|
|
|
$self->error("Bad combination: $@");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-02-05 18:05:33 +01:00
|
|
|
sub name {
|
|
|
|
my ( $self, $req, $type ) = @_;
|
|
|
|
return $req->sessionInfo->{ ( $type eq 'auth' ? '_auth' : '_userDB' ) }
|
|
|
|
|| 'Combination';
|
|
|
|
}
|
|
|
|
|
2017-02-05 13:24:26 +01:00
|
|
|
sub extractFormInfo {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
|
|
|
|
# Get available authentication schemes for this user
|
2017-02-05 18:05:33 +01:00
|
|
|
$self->getStack( $req, 'extractFormInfo' ) or return PE_ERROR;
|
|
|
|
return $self->try( 0, 'extractFormInfo', $req );
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub getUser {
|
2017-02-05 18:05:33 +01:00
|
|
|
return $_[0]->try( 1, 'getUser', $_[1] );
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub authenticate {
|
2017-02-05 18:05:33 +01:00
|
|
|
return $_[0]->try( 0, 'authenticate', $_[1] );
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub setAuthSessionInfo {
|
2017-02-05 18:05:33 +01:00
|
|
|
return $_[0]->try( 0, 'setAuthSessionInfo', $_[1] );
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub setSessionInfo {
|
2017-02-05 18:05:33 +01:00
|
|
|
return $_[0]->try( 1, 'setSessionInfo', $_[1] );
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub setGroups {
|
2017-02-05 18:05:33 +01:00
|
|
|
return $_[0]->try( 1, 'setGroups', $_[1] );
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub getDisplayType {
|
2017-02-05 18:05:33 +01:00
|
|
|
return $_[0]->try( 0, 'getDisplayType', {} );
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# TODO: authLogout
|
|
|
|
|
|
|
|
sub getStack {
|
2017-02-05 18:05:33 +01:00
|
|
|
my ( $self, $req, @steps ) = @_;
|
|
|
|
return $req->datas->{multiStack} if ( $req->datas->{multiStack} );
|
2017-02-05 22:12:06 +01:00
|
|
|
my $stack = $req->datas->{multiStack} = $self->stackSub->($req->env);
|
2017-02-05 13:24:26 +01:00
|
|
|
unless ($stack) {
|
|
|
|
$self->lmLog( 'No authentication scheme for this user', 'error' );
|
|
|
|
}
|
2017-02-05 18:05:33 +01:00
|
|
|
@{ $req->datas->{multiSteps} } = ( @steps, @{ $req->steps } );
|
2017-02-05 13:24:26 +01:00
|
|
|
$req->datas->{multiTry} = 0;
|
|
|
|
return $stack;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub try {
|
|
|
|
my ( $self, $type, $subname, $req ) = @_;
|
|
|
|
my ( $nb, $stack ) = ( $req->datas->{multiTry}, $req->datas->{multiStack} );
|
|
|
|
|
|
|
|
# If more than 1 scheme is available
|
2017-02-05 18:05:33 +01:00
|
|
|
my ( $res, $name );
|
2017-02-05 22:12:06 +01:00
|
|
|
if ( $nb < @$stack - 1 ) {
|
2017-02-05 13:24:26 +01:00
|
|
|
|
|
|
|
# TODO: change logLevel for userLog()
|
2017-02-05 18:05:33 +01:00
|
|
|
( $res, $name ) = $stack->[$nb]->[$type]->( $subname, $req );
|
2017-02-05 13:24:26 +01:00
|
|
|
|
|
|
|
# On error, restart authentication with next scheme
|
|
|
|
if ( $res > PE_OK ) {
|
2017-02-05 18:05:33 +01:00
|
|
|
$self->lmLog( qq'Scheme "$name" has return $res, trying next',
|
|
|
|
'info' );
|
2017-02-05 13:24:26 +01:00
|
|
|
$req->datas->{multiTry}++;
|
|
|
|
$req->steps( [ @{ $req->datas->{multiSteps} } ] );
|
|
|
|
return PE_OK;
|
|
|
|
}
|
|
|
|
}
|
2017-02-05 18:05:33 +01:00
|
|
|
else {
|
2017-02-05 22:12:06 +01:00
|
|
|
( $res, $name ) = $stack->[$nb]->[$type]->( $subname, $req );
|
2017-02-05 18:05:33 +01:00
|
|
|
}
|
|
|
|
$req->sessionInfo->{ [ '_auth', '_userDB' ]->[$type] } = $name;
|
|
|
|
return $res;
|
2017-02-05 13:24:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
1;
|