2016-06-29 21:34:36 +02:00
|
|
|
package Lemonldap::NG::Portal::Lib::Choice;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use Mouse;
|
|
|
|
|
|
|
|
extends 'Lemonldap::NG::Portal::Lib::Wrapper';
|
|
|
|
|
|
|
|
our $VERSION = '2.0.0';
|
|
|
|
|
|
|
|
has modules => ( is => 'rw', default => sub { {} } );
|
|
|
|
|
2016-07-02 21:09:45 +02:00
|
|
|
has type => ( is => 'rw' );
|
|
|
|
|
2016-06-29 21:34:36 +02:00
|
|
|
# INITIALIZATION
|
|
|
|
|
|
|
|
# init() must be called by module::init() with a number:
|
|
|
|
# - 0 for auth
|
|
|
|
# - 1 for userDB
|
|
|
|
# - 2 for passwordDB ?
|
|
|
|
sub init {
|
|
|
|
my ( $self, $type ) = @_;
|
2016-07-02 21:09:45 +02:00
|
|
|
$self->type($type);
|
2016-06-29 21:34:36 +02:00
|
|
|
|
2016-12-26 10:23:35 +01:00
|
|
|
unless ( $self->conf->{authChoiceModules}
|
|
|
|
and %{ $self->conf->{authChoiceModules} } )
|
|
|
|
{
|
2016-07-07 22:55:27 +02:00
|
|
|
$self->error("'authChoiceModules' is empty");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-29 21:34:36 +02:00
|
|
|
foreach my $name ( keys %{ $self->conf->{authChoiceModules} } ) {
|
|
|
|
my @mods =
|
|
|
|
split( /[;\|]/, $self->conf->{authChoiceModules}->{$name} );
|
|
|
|
my $module =
|
2016-07-01 17:56:16 +02:00
|
|
|
'::'
|
|
|
|
. [ 'Auth', 'UserDB', 'Password' ]->[$type] . '::'
|
|
|
|
. $mods[$type];
|
|
|
|
if ( $module = $self->loadPlugin( $name, $module ) ) {
|
2016-06-29 21:34:36 +02:00
|
|
|
$self->modules->{$name} = $module;
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug(
|
2016-06-29 21:34:36 +02:00
|
|
|
[qw(Authentication User Password)]->[$type]
|
2017-02-15 07:41:50 +01:00
|
|
|
. " module $name selected" );
|
2016-06-29 21:34:36 +02:00
|
|
|
}
|
|
|
|
else {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error(
|
|
|
|
"Choice: unable to load $name, disabling it: " . $self->error );
|
2016-07-02 10:51:00 +02:00
|
|
|
$self->error('');
|
2016-06-29 21:34:36 +02:00
|
|
|
}
|
|
|
|
}
|
2016-07-02 21:09:45 +02:00
|
|
|
unless ( keys %{ $self->modules } ) {
|
2016-07-02 10:51:00 +02:00
|
|
|
$self->error('Choice: no available modules found, aborting');
|
|
|
|
return 0;
|
|
|
|
}
|
2016-06-30 22:42:50 +02:00
|
|
|
return 1;
|
2016-06-29 21:34:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub checkChoice {
|
|
|
|
my ( $self, $req ) = @_;
|
2016-07-02 21:09:45 +02:00
|
|
|
my $name =
|
2017-12-18 10:40:07 +01:00
|
|
|
$req->userData->{_choice}
|
|
|
|
|| $req->sessionInfo->{_choice}
|
2016-07-02 21:09:45 +02:00
|
|
|
|| $req->param( $self->conf->{authChoiceParam} )
|
|
|
|
or return 0;
|
|
|
|
return $name if ( $req->datas->{ "enabledMods" . $self->type } );
|
2016-07-01 17:56:16 +02:00
|
|
|
unless ( defined $self->modules->{$name} ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error("Unknown choice '$name'");
|
2016-07-01 17:56:16 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
$req->sessionInfo->{_choice} = $name;
|
2016-07-02 21:09:45 +02:00
|
|
|
$req->datas->{ "enabledMods" . $self->type } = [ $self->modules->{$name} ];
|
2016-06-30 22:42:50 +02:00
|
|
|
$self->p->_authentication->authnLevel("${name}AuthnLevel");
|
2016-07-02 10:51:00 +02:00
|
|
|
return $name;
|
2016-06-29 21:34:36 +02:00
|
|
|
}
|
|
|
|
|
2016-07-01 18:59:59 +02:00
|
|
|
sub name {
|
|
|
|
my ( $self, $req, $type ) = @_;
|
2016-07-02 21:09:45 +02:00
|
|
|
unless ($req) {
|
2016-07-02 10:51:00 +02:00
|
|
|
return 'Choice';
|
|
|
|
}
|
2017-12-21 21:44:13 +01:00
|
|
|
my $n = ref( $req->datas->{ "enabledMods" . $self->type }->[0] );
|
2016-07-01 18:59:59 +02:00
|
|
|
$n =~ s/^Lemonldap::NG::Portal::(?:(?:UserDB|Auth)::)?//;
|
|
|
|
return $n;
|
|
|
|
}
|
|
|
|
|
2016-07-02 21:09:45 +02:00
|
|
|
package Lemonldap::NG::Portal::Main;
|
2016-06-29 21:34:36 +02:00
|
|
|
|
|
|
|
# Build authentication loop displayed in template
|
2016-07-01 17:56:16 +02:00
|
|
|
# Return authLoop array reference
|
2016-06-29 21:34:36 +02:00
|
|
|
sub _buildAuthLoop {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
my @authLoop;
|
|
|
|
|
|
|
|
# Test authentication choices
|
|
|
|
unless ( ref $self->conf->{authChoiceModules} eq 'HASH' ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn("No authentication choices defined");
|
2016-06-29 21:34:36 +02:00
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ( sort keys %{ $self->conf->{authChoiceModules} } ) {
|
|
|
|
|
|
|
|
my $name = $_;
|
|
|
|
|
|
|
|
# Ignore 'forcedSAML'
|
|
|
|
next if $name eq 'forcedSAML';
|
|
|
|
|
|
|
|
# Name can have a digit as first character
|
|
|
|
# for sorting purpose
|
|
|
|
# Remove it in displayed name
|
|
|
|
$name =~ s/^(\d*)?(\s*)?//;
|
|
|
|
|
|
|
|
# Replace also _ by space for a nice display
|
|
|
|
$name =~ s/\_/ /g;
|
|
|
|
|
|
|
|
# Find modules associated to authChoice
|
|
|
|
my ( $auth, $userDB, $passwordDB, $url ) =
|
|
|
|
split( /[;\|]/, $self->conf->{authChoiceModules}->{$_} );
|
|
|
|
|
|
|
|
if ( $auth and $userDB and $passwordDB ) {
|
|
|
|
|
|
|
|
# Default URL
|
2018-03-09 16:27:33 +01:00
|
|
|
if ( defined $url
|
|
|
|
and not $self->p->checkXSSAttack( 'URI',
|
|
|
|
$req->env->{'REQUEST_URI'} ) )
|
|
|
|
{
|
|
|
|
$url .= $req->env->{'REQUEST_URI'};
|
|
|
|
}
|
|
|
|
else {
|
2018-03-09 16:50:44 +01:00
|
|
|
$url .= '#';
|
2018-03-09 16:27:33 +01:00
|
|
|
}
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("Use URL $url");
|
2016-06-29 21:34:36 +02:00
|
|
|
|
|
|
|
# Options to store in the loop
|
|
|
|
my $optionsLoop =
|
|
|
|
{ name => $name, key => $_, module => $auth, url => $url };
|
|
|
|
|
|
|
|
# Get displayType for this module
|
2016-07-02 21:09:45 +02:00
|
|
|
no strict 'refs';
|
|
|
|
my $displayType = "Lemonldap::NG::Portal::Auth::${auth}"
|
|
|
|
->can('getDisplayType')->( undef, $req );
|
2016-06-29 21:34:36 +02:00
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("Display type $displayType for module $auth");
|
2016-06-29 21:34:36 +02:00
|
|
|
$optionsLoop->{$displayType} = 1;
|
|
|
|
|
2016-07-02 21:09:45 +02:00
|
|
|
# If displayType is logo, check if key.png is available
|
|
|
|
# TODO:
|
|
|
|
#if (
|
|
|
|
# -e $self->getApacheHtdocsPath . "/skins/common/" . $_ . ".png" )
|
|
|
|
#{
|
|
|
|
# $optionsLoop->{logoFile} = $_ . ".png";
|
|
|
|
#}
|
|
|
|
#else {
|
|
|
|
$optionsLoop->{logoFile} = $auth . ".png";
|
|
|
|
|
|
|
|
#}
|
2016-06-29 21:34:36 +02:00
|
|
|
|
|
|
|
# Register item in loop
|
|
|
|
push @authLoop, $optionsLoop;
|
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
"Authentication choice $name will be displayed");
|
2016-06-29 21:34:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
$req->error("Authentication choice $_ value is invalid");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return \@authLoop;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|
|
|
|
|