New portal in progress (#595)

This commit is contained in:
Xavier Guimard 2016-03-29 21:09:55 +00:00
parent a11a5565ca
commit d6cd2512d8
5 changed files with 154 additions and 102 deletions

View File

@ -5,25 +5,10 @@ use Mouse;
our $VERSION = '2.0.0';
extends qw(Lemonldap::NG::Handler::PSGI::Try Lemonldap::NG::Portal::Main::Init);
has stack => ( is => 'rw' );
# ENTRY POINT METHODS
# -------------------
# All methods below have been declared as Lemonldap::NG::Common::PSGI::Router
# routes (see Lemonldap::NG::Portal::Main::Init)
sub issuerForAuthUser {
my ( $self, $type, $req ) = @_;
}
sub issuerForUnauthUser {
my ( $self, $type, $req ) = @_;
}
# TODO in run
# - mustRedirect
extends(
'Lemonldap::NG::Handler::PSGI::Try',
'Lemonldap::NG::Portal::Main::Init',
'Lemonldap::NG::Portal::Main::Run',
);
1;

View File

@ -1,14 +1,12 @@
##@file
# FastCGI package for Lemonldap::NG portal
#
##@class Lemonldap::NG::Portal::Main::Init
# FastCGI class for Lemonldap::NG portal
# Initialization part of Lemonldap::NG portal
package Lemonldap::NG::Portal::Main::Init;
use strict;
use Mouse;
use Lemonldap::NG::Common::Conf::Constants;
use Lemonldap::NG::Handler::Main::Reload qw/keepConf/;
use Lemonldap::NG::Portal::Main::Plugins;
our $VERSION = '2.0.0';
@ -21,15 +19,33 @@ has conf => ( is => 'rw', default => sub { {} } );
# Sub modules
has _authentication => ( is => 'rw' );
has _userDB => ( is => 'rw' );
has _passwordDB => ( is => 'rw' );
has _registerDB => ( is => 'rw' );
has _issuers => ( is => 'rw' );
# Lists to store plugins entry-points
has beforeAuthProcess => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] }
);
has addSessionData => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] }
);
has afterAuthProcess => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] }
);
has forAuthUser => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] }
);
sub init {
my ( $self, $args ) = @_;
$args ||= {};
return 0 unless ( $self->SUPER::init($args) );
return 0 unless ( $self->SUPER::init( { conf => $args } ) );
$self->localConfig(
{ %{ HANDLER->confAcc->getLocalConf('portal') }, %$args } );
return $self->checkConf($args);
@ -63,16 +79,6 @@ sub checkConf {
);
return 0;
}
foreach my $key (
qw(persistentStorage samlStorage casStorage captchaStorage oidcStorage)
)
{
unless ( $self->conf->{$key} ) {
$self->conf->{$key} = $self->conf->{globalStorage};
$self->conf->{ $key . 'Options' } =
$self->conf->{globalStorageOptions};
}
}
# Initialize cookie domain
unless ( $self->conf->{domain} ) {
@ -81,9 +87,9 @@ sub checkConf {
}
$self->conf->{domain} =~ s/^([^\.])/.$1/;
# Load authentication/userDB/passwordDB modules
# ---------------------------------------------
for my $type (qw(authentication userDB passwordDB registerDB)) {
# Load authentication/userDB
# --------------------------
for my $type (qw(authentication userDB)) {
unless ( $self->conf->{$type} ) {
$self->error("$type is not set");
return 0;
@ -97,56 +103,14 @@ sub checkConf {
# contains arguments (key1 = scalar_value; key2 = ...)
my ( $tmp, %h ) = split( /\s*[=;]\s*/, $self->conf->{$type} );
%{ $self->{conf} } = ( %h, %{ $self->{conf} } ) if (%h);
return 0 unless ( $self->loadModule( $module, "_$type" ) );
# Launch and initialize module
return 0
unless ( $self->{"_$type"} = $self->loadModule($module)
and $self->{"_$type"}->init );
}
# Load issuer modules
# -------------------
foreach my $issuerDBtype (qw(SAML OpenID CAS OpenIDConnect)) {
my $module = 'Lemonldap::NG::Portal::IssuerDB' . $issuerDBtype;
$self->lmLog(
"[IssuerDB activation] Try issuerDB module $issuerDBtype",
'debug' );
unless ( $self->conf->{"issuerDB${issuerDBtype}Activation"} ) {
$self->lmLog(
"[IssuerDB activation] Activation flag set to off, trying next",
'debug'
);
next;
}
#TODO: regexp ?
my $path = $self->conf->{"issuerDB${issuerDBtype}Path"};
unless ($path) {
$self->lmLog(
"[IssuerDB activation] no path found for ${issuerDBtype}. Skipping",
'notice'
);
next;
}
return 0 unless ( $self->loadModule( $module, 'tmp' ) );
$self->{issuers}->{$issuerDBtype} = $self->{tmp};
delete $self->{tmp};
$self->addAuthRoute(
$path,
sub {
my $self = shift;
return $self->issuerForAuthUser( $issuerDBtype, @_ );
},
[qw(GET POST PUT DELETE)]
);
$self->addUnauthRoute(
$path,
sub {
my $self = shift;
return $self->issuerForUnauthUser( $issuerDBtype, @_ );
},
[qw(GET POST PUT DELETE)]
);
# TODO "check the path"
}
# Initialize trusted domain list
$self->conf->{trustedDomains} ||= "";
$self->conf->{trustedDomains} = "*"
if ( $self->conf->{trustedDomains} =~ /(^|\s)\*(\s|$)/ );
@ -159,35 +123,49 @@ sub checkConf {
. ')';
$self->conf->{trustedDomains} =~ s/\./\\./g;
}
# Load plugins
foreach my $plugin ( $self->enabledPlugins ) {
$self->loadPlugin($plugin) or return 0;
}
}
1;
}
##@method boolean loadModule(string module, boolean ignoreError)
# Load a module into portal namespace
# @param module module name
# @param ignoreError set to 1 if error should not appear in logs
# @return boolean
sub loadModule {
my ( $self, $module, $keyname ) = @_;
sub loadPlugin {
my ( $self, $plugin ) = @_;
my $obj;
return 0
unless ( $obj =
$self->loadModule("Lemonldap::NG::Portal::Plugins::$plugin") );
foreach my $sub (
qw(beforeAuthProcess addSessionData afterAuthProcess forAuthUser))
{
if ( $obj->can($sub) ) {
push @{ $self->{$sub} }, $obj->$sub;
}
}
return $obj->init;
}
sub loadModule {
my ( $self, $module ) = @_;
my $obj;
# Load module test
eval "require $module";
if ($@) {
$self->error("$module load error: $@");
return 0;
}
eval {
$self->{$keyname} = $module->new( { p => $self, conf => $self->conf } );
$obj = $module->new( { p => $self, conf => $self->conf } );
$self->lmLog( "Module $module loaded", 'debug' );
};
if ($@) {
$self->error("Unable to build $module object: $@");
return 0;
}
return 0 unless ( $self->{$keyname} );
$self->lmLog( "Module $module loaded", 'debug' );
return 1;
return $obj;
}
1;

View File

@ -0,0 +1,21 @@
package Lemonldap::NG::Portal::Main::Module;
use strict;
use Mouse;
our $VERSION = '2.0.0';
has p => ( is => 'rw', weak_ref => 1 );
has conf => ( is => 'rw', weak_ref => 1 );
sub lmLog {
my $self = shift;
return $self->p->lmLog(@_);
}
sub error {
my $self = shift;
return $self->p->error(@_);
}
1;

View File

@ -0,0 +1,59 @@
# This module loads known enabled plugins. To add custom modules, just add them
# into "plugins" list in lemonldap-ng.ini, section "portal"
package Lemonldap::NG::Portal::Main::Plugins;
use strict;
use Mouse;
our $VERSION = '2.0.0';
##@method list enabledPlugins
#
#@return list of enabled plugins
sub enabledPlugins {
my ($self) = @_;
my @res;
# Search for IssuerDB* modules enabled
foreach my $key (qw(SAML OpenID CAS OpenIDConnect)) {
if ( $self->conf->{"issuerDB${key}Activation"} ) {
$self->lmlog( "IssuerDB${key} enabled", 'debug' );
push @res, "IssuerDB$key";
}
}
# Check if captcha is required
# TODO: verify if this list is OK
foreach my $key (
qw(captcha_login_enabled captcha_mail_enabled captcha_register_enabled))
{
if ( $self->conf->{$key} ) {
$self->lmLog( 'Captcha enabled', 'debug' );
push @res, 'Captcha';
last;
}
}
# Check if SOAP is enabled
# TODO: REST
push @res, 'SOAP' if ( $self->conf->{Soap} );
# Check if notification is enabled
push @res, 'Notifications' if ( $self->conf->{notification} );
foreach my $type (qw(password register)) {
my $tmp = $self->conf->{$type};
if ( $tmp and $tmp ne 'Null' ) {
$tmp = ucfirst($type) . "DB$tmp";
$self->lmLog("$tmp enabled");
push @res, $tmp;
}
}
# Check if custom plugins are required
if ( $self->conf->{plugins} ) {
$self->lmLog( 'Custom plugins: ' . $self->conf->{plugins}, 'debug' );
push @res, grep ( /\w/, split( /,\s*/, $self->conf->{plugins} ) );
}
}
1;

View File

@ -0,0 +1,9 @@
package Lemonldap::NG::Portal::Main::Run;
use strict;
use Mouse;
# TODO in run
# - mustRedirect
1;