lemonldap-ng/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm

263 lines
6.8 KiB
Perl
Raw Normal View History

2016-03-30 21:51:12 +02:00
##@class Lemonldap::NG::Portal::Main::Run
# Serve request part of Lemonldap::NG portal
#
2016-04-03 08:33:50 +02:00
# Parts of this file:
# - response handler
# - main entry points
# - running methods
# - utilities
2016-03-31 07:27:59 +02:00
#
2016-03-29 23:09:55 +02:00
package Lemonldap::NG::Portal::Main::Run;
2016-04-07 23:31:56 +02:00
our $VERSION = '2.0.0';
2016-03-29 23:09:55 +02:00
2016-04-07 23:31:56 +02:00
package Lemonldap::NG::Portal::Main;
2016-04-03 18:27:13 +02:00
2016-04-07 23:31:56 +02:00
use strict;
2016-03-30 21:51:12 +02:00
2016-04-03 08:33:50 +02:00
# List constants
sub authProcess { qw(extractFormInfo getUser authenticate) }
sub sessionDatas {
qw(setSessionInfo setMacros setGroups setPersistentSessionInfo
setLocalGroups store buildCookie);
}
# RESPONSE HANDLER
# ----------------
#
# - check if conf has changed
# - replace Lemonldap::NG::Common::PSGI::Request request by
# Lemonldap::NG::Portal::Main::Request
# - launch Lemonldap::NG::Common::PSGI::Request::handler()
2016-03-30 21:51:12 +02:00
sub handler {
2016-04-03 18:51:23 +02:00
my ( $self, $req ) = @_;
2016-03-30 21:51:15 +02:00
bless $req, 'Lemonldap::NG::Portal::Main::Request';
2016-04-03 18:51:23 +02:00
return $self->Lemonldap::NG::Common::PSGI::Router::handler($req);
2016-03-30 21:51:12 +02:00
}
2016-04-03 08:33:50 +02:00
# MAIN ENTRY POINTS (declared in Lemonldap::NG::Portal::Main::Init)
# -----------------
#
# Entry points:
# - "/test": - authenticated() for already authenticated users
# - pleaseAuth() for others
# - "/": - login() ~first access
# - postLogin(), same for POST requests
# - authenticatedRequest() for authenticated users
2016-03-31 07:27:59 +02:00
sub authenticated {
my ( $self, $req ) = @_;
return $self->sendJSONresponse( $req, { status => 1 } );
}
sub pleaseAuth {
my ( $self, $req ) = @_;
return $self->sendJSONresponse( $req, { status => 0 } );
}
sub login {
my ( $self, $req ) = @_;
2016-04-03 18:27:22 +02:00
return $self->do(
2016-04-01 07:24:27 +02:00
$req,
2016-03-31 22:08:43 +02:00
[
2016-04-02 22:17:39 +02:00
'controlUrl', @{ $self->beforeAuth },
&authProcess, @{ $self->betweenAuthAndDatas },
2016-04-03 18:27:22 +02:00
&sessionDatas, @{ $self->afterDatas },
2016-03-31 22:08:43 +02:00
]
2016-03-31 07:27:59 +02:00
);
}
sub postLogin {
my ( $self, $req ) = @_;
2016-04-03 18:27:22 +02:00
return $self->do(
2016-04-01 07:24:27 +02:00
$req,
2016-03-31 22:08:43 +02:00
[
2016-04-03 08:33:50 +02:00
'restoreArgs', 'controlUrl',
@{ $self->beforeAuth }, &authProcess,
@{ $self->betweenAuthAndDatas }, &sessionDatas,
2016-04-04 07:08:26 +02:00
@{ $self->afterDatas },
2016-03-31 22:08:43 +02:00
]
2016-03-31 07:27:59 +02:00
);
}
sub authenticatedRequest {
2016-03-31 22:08:43 +02:00
my ( $self, $req ) = @_;
2016-04-04 07:08:26 +02:00
return $self->do( $req, [ 'controlUrl', @{ $self->forAuthUser } ] );
2016-03-31 22:08:43 +02:00
}
2016-04-03 08:33:50 +02:00
# RUNNING METHODS
# ---------------
2016-03-31 22:08:43 +02:00
sub do {
2016-04-01 07:24:27 +02:00
my ( $self, $req, $steps ) = @_;
2016-03-31 22:08:43 +02:00
$req->steps($steps);
2016-04-11 07:00:34 +02:00
my $err = $req->error( $self->process($req) );
2016-04-01 07:24:27 +02:00
2016-03-31 22:08:43 +02:00
# TODO: updateStatus
2016-04-01 07:24:27 +02:00
if ( !$self->conf->{noAjaxHook} and $req->wantJSON ) {
2016-03-31 22:08:43 +02:00
if ( $err > 0 ) {
2016-04-01 07:24:27 +02:00
return [
401,
[
'WWW-Authenticate' => "SSO " . $self->conf->{portal},
'Access-Control-Allow-Origin' => '*'
],
[]
];
2016-03-31 22:08:43 +02:00
}
else {
2016-04-06 14:01:53 +02:00
return $self->sendJSONresponse( $req,
{ result => 1, message => 'Authenticated' } );
2016-03-31 22:08:43 +02:00
}
}
else {
2016-04-01 07:24:27 +02:00
if ($err) {
my ( $tpl, $prms ) = $self->display($req);
return $self->sendHtml( $req, $tpl, params => $prms );
2016-03-31 22:08:43 +02:00
}
else {
return $self->autoRedirect($req);
}
}
}
2016-04-03 08:33:50 +02:00
# Utilities
# ---------
sub getModule {
my ( $self, $req, $type ) = @_;
if (
my $mod = {
auth => '_authentication',
user => '_userDB',
password => '_passwordDB'
}->{$type}
)
{
if ( $self->$mod->can('name') ) {
return $self->$mod->can('name');
}
else {
return ref( $self->$mod );
}
}
elsif ( $type eq 'issuer' ) {
return $req->{_activeIssuerDB};
}
else {
die "Unknown type $type";
2016-03-31 22:08:43 +02:00
}
2016-03-31 07:27:59 +02:00
}
2016-04-03 10:44:58 +02:00
sub autoRedirect {
my ( $self, $req ) = @_;
# Set redirection URL if needed
$req->datas->{urldc} ||= $self->conf->{portal} if ( $req->mustRedirect );
# Redirection should be made if urldc defined
if ( $req->datas->{urldc} ) {
2016-04-04 22:39:22 +02:00
return [
302, [ Location => $req->datas->{urldc}, @{ $req->respHeaders } ],
[]
];
2016-04-03 10:44:58 +02:00
}
else {
my ( $tpl, $prms ) = $self->display($req);
return $self->sendHtml( $req, $tpl, params => $prms );
2016-04-03 10:44:58 +02:00
}
}
2016-04-04 22:39:22 +02:00
# Try to recover the session corresponding to id and return session datas.
# If $id is set to undef or if $force is true, return a new session.
# @param id session reference
# @param noInfo do not set Apache REMOTE_USER
# @param force Force session creation if it does not exist
# return Lemonldap::NG::Common::Session object
sub getApacheSession {
my ( $self, $id, $noInfo, $force ) = @_;
my $as = Lemonldap::NG::Common::Session->new(
{
storageModule => $self->conf->{globalStorage},
storageModuleOptions => $self->conf->{globalStorageOptions},
cacheModule => $self->conf->{localSessionStorage},
cacheModuleOptions => $self->conf->{localSessionStorageOptions},
id => $id,
force => $force,
kind => "SSO",
}
);
if ( $as->error ) {
$self->lmLog( $as->error, 'debug' );
return;
}
if ( $id and !$force and !$as->data ) {
$self->lmLog( "Session $id not found", 'debug' );
return;
}
unless ($noInfo) {
$self->setApacheUser( $as->data->{ $self->{whatToTrace} } )
if ($id);
$self->{id} = $as->id;
}
return $as;
}
# Try to recover the persistent session corresponding to uid and return session datas.
sub getPersistentSession {
my ( $self, $uid ) = @_;
return unless defined $uid;
# Compute persistent identifier
my $pid = $self->_md5hash($uid);
my $ps = Lemonldap::NG::Common::Session->new(
{
2016-04-05 22:46:11 +02:00
storageModule => $self->conf->{persistentStorage},
storageModuleOptions => $self->conf->{persistentStorageOptions},
cacheModule => $self->conf->{localSessionStorage},
cacheModuleOptions => $self->conf->{localSessionStorageOptions},
2016-04-04 22:39:22 +02:00
id => $pid,
force => 1,
kind => "Persistent",
}
);
if ( $ps->error ) {
$self->lmLog( $ps->error, 'debug' );
}
# Set _session_uid if not already present
unless ( defined $ps->data->{_session_uid} ) {
$ps->update( { '_session_uid' => $uid } );
}
# Set _utime if not already present
unless ( defined $ps->data->{_utime} ) {
$ps->update( { '_utime' => time } );
}
return $ps;
}
# Return md5(s)
sub _md5hash {
my ( $self, $s ) = @_;
return substr( Digest::MD5::md5_hex($s), 0, 32 );
}
2016-04-03 10:44:58 +02:00
# Check if an URL's domain name is declared in LL::NG config or is declared as
# trusted domain
sub isTrustedUrl {
my ( $self, $url ) = @_;
return $url =~ $self->trustedDomains ? 1 : 0;
}
2016-03-29 23:09:55 +02:00
1;