Start handler reorganization (#1160)
This commit is contained in:
parent
554cd5e77f
commit
820691df33
|
@ -209,7 +209,7 @@ sub virtualHosts {
|
||||||
}
|
}
|
||||||
return $self->sendJSONresponse( $req, $resp );
|
return $self->sendJSONresponse( $req, $resp );
|
||||||
}
|
}
|
||||||
elsif ( $query =~ /^vhost(?:(?:Aliase|Http)s|Maintenance|Port)$/ ) {
|
elsif ( $query =~ /^vhost(?:(?:Aliase|Http)s|Maintenance|Port|Type)$/ ) {
|
||||||
$self->lmLog( "Query for $vh/$query key", 'debug' );
|
$self->lmLog( "Query for $vh/$query key", 'debug' );
|
||||||
|
|
||||||
# TODO: verify how this is done actually
|
# TODO: verify how this is done actually
|
||||||
|
|
|
@ -26,7 +26,7 @@ our $oidcOPMetaDataNodeKeys = 'oidcOPMetaData(?:Options(?:C(?:lient(?:Secret|ID)
|
||||||
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:I(?:DToken(?:Expiration|SignAlg)|con)|(?:RedirectUri|ExtraClaim)s|AccessTokenExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|UserIDAttr)|ExportedVars)';
|
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:I(?:DToken(?:Expiration|SignAlg)|con)|(?:RedirectUri|ExtraClaim)s|AccessTokenExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|UserIDAttr)|ExportedVars)';
|
||||||
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Re(?:questedAuthnContext|solutionRule|layStateURL)|S(?:ignS[LS]OMessage|toreSAMLToken|[LS]OBinding)|Force(?:Authn|UTF8)|NameIDFormat)|ExportedAttributes|XML)';
|
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Re(?:questedAuthnContext|solutionRule|layStateURL)|S(?:ignS[LS]OMessage|toreSAMLToken|[LS]OBinding)|Force(?:Authn|UTF8)|NameIDFormat)|ExportedAttributes|XML)';
|
||||||
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|S(?:essionNotOnOrAfterTimeout|ignS[LS]OMessage)|(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|En(?:ableIDPInitiatedURL|cryptionMode)|ForceUTF8)|ExportedAttributes|XML)';
|
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|S(?:essionNotOnOrAfterTimeout|ignS[LS]OMessage)|(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|En(?:ableIDPInitiatedURL|cryptionMode)|ForceUTF8)|ExportedAttributes|XML)';
|
||||||
our $virtualHostKeys = '(?:vhost(?:(?:Aliase|Http)s|Maintenance|Port)|(?:exportedHeader|locationRule)s|post)';
|
our $virtualHostKeys = '(?:vhost(?:(?:Maintenanc|Typ)e|(?:Aliase|Http)s|Port)|(?:exportedHeader|locationRule)s|post)';
|
||||||
|
|
||||||
our $authParameters = {
|
our $authParameters = {
|
||||||
adParams => [qw(ADPwdMaxAge ADPwdExpireWarning)],
|
adParams => [qw(ADPwdMaxAge ADPwdExpireWarning)],
|
||||||
|
|
|
@ -5,8 +5,9 @@ example/scripts/purgeLocalCache
|
||||||
example/scripts/purgeLocalCache.cron.d
|
example/scripts/purgeLocalCache.cron.d
|
||||||
lib/Lemonldap/NG/Handler.pm
|
lib/Lemonldap/NG/Handler.pm
|
||||||
lib/Lemonldap/NG/Handler/ApacheMP2.pm
|
lib/Lemonldap/NG/Handler/ApacheMP2.pm
|
||||||
|
lib/Lemonldap/NG/Handler/ApacheMP2/AuthBasic.pm
|
||||||
|
lib/Lemonldap/NG/Handler/ApacheMP2/Main.pm
|
||||||
lib/Lemonldap/NG/Handler/API/ExperimentalNginx.pm
|
lib/Lemonldap/NG/Handler/API/ExperimentalNginx.pm
|
||||||
lib/Lemonldap/NG/Handler/AuthBasic.pm
|
|
||||||
lib/Lemonldap/NG/Handler/Lib/AuthBasic.pm
|
lib/Lemonldap/NG/Handler/Lib/AuthBasic.pm
|
||||||
lib/Lemonldap/NG/Handler/Main.pm
|
lib/Lemonldap/NG/Handler/Main.pm
|
||||||
lib/Lemonldap/NG/Handler/Main/Init.pm
|
lib/Lemonldap/NG/Handler/Main/Init.pm
|
||||||
|
@ -37,7 +38,6 @@ t/12-Lemonldap-NG-Handler-Jail.t
|
||||||
t/13-Lemonldap-NG-Handler-Fake-Safe.t
|
t/13-Lemonldap-NG-Handler-Fake-Safe.t
|
||||||
t/50-Lemonldap-NG-Handler-SecureToken.t
|
t/50-Lemonldap-NG-Handler-SecureToken.t
|
||||||
t/51-Lemonldap-NG-Handler-Zimbra.t
|
t/51-Lemonldap-NG-Handler-Zimbra.t
|
||||||
t/52-Lemonldap-NG-Handler-AuthBasic.t
|
|
||||||
t/60-Lemonldap-NG-Handler-PSGI.t
|
t/60-Lemonldap-NG-Handler-PSGI.t
|
||||||
t/61-Lemonldap-NG-Handler-PSGI-Server.t
|
t/61-Lemonldap-NG-Handler-PSGI-Server.t
|
||||||
t/62-Lemonldap-NG-Handler-Nginx.t
|
t/62-Lemonldap-NG-Handler-Nginx.t
|
||||||
|
|
|
@ -1,358 +1,21 @@
|
||||||
package Lemonldap::NG::Handler::ApacheMP2;
|
package Lemonldap::NG::Handler::ApacheMP2;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use AutoLoader 'AUTOLOAD';
|
|
||||||
use Apache2::RequestUtil;
|
|
||||||
use Apache2::RequestRec;
|
|
||||||
use Apache2::Log;
|
|
||||||
use Apache2::ServerUtil;
|
|
||||||
use Apache2::Connection;
|
|
||||||
use Apache2::RequestIO;
|
|
||||||
use Apache2::Const;
|
|
||||||
use Apache2::Filter;
|
|
||||||
use APR::Table;
|
|
||||||
use Apache2::Const -compile =>
|
|
||||||
qw(FORBIDDEN HTTP_UNAUTHORIZED REDIRECT OK DECLINED DONE SERVER_ERROR AUTH_REQUIRED HTTP_SERVICE_UNAVAILABLE);
|
|
||||||
use Lemonldap::NG::Handler::Main;
|
|
||||||
|
|
||||||
use constant FORBIDDEN => Apache2::Const::FORBIDDEN;
|
use Lemonldap::NG::Handler::ApacheMP2::Main;
|
||||||
use constant HTTP_UNAUTHORIZED => Apache2::Const::HTTP_UNAUTHORIZED;
|
|
||||||
use constant REDIRECT => Apache2::Const::REDIRECT;
|
|
||||||
use constant OK => Apache2::Const::OK;
|
|
||||||
use constant DECLINED => Apache2::Const::DECLINED;
|
|
||||||
use constant DONE => Apache2::Const::DONE;
|
|
||||||
use constant SERVER_ERROR => Apache2::Const::SERVER_ERROR;
|
|
||||||
use constant AUTH_REQUIRED => Apache2::Const::AUTH_REQUIRED;
|
|
||||||
use constant MAINTENANCE => Apache2::Const::HTTP_SERVICE_UNAVAILABLE;
|
|
||||||
use constant BUFF_LEN => 8192;
|
|
||||||
|
|
||||||
eval { require threads::shared; };
|
|
||||||
print STDERR
|
|
||||||
"You probably would have better perfs by enabling threads::shared\n"
|
|
||||||
if ($@);
|
|
||||||
|
|
||||||
our @ISA = qw(Lemonldap::NG::Handler::Main);
|
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
our $request; # Apache2::RequestRec object for current request
|
|
||||||
|
|
||||||
# PUBLIC METHODS
|
# PUBLIC METHODS
|
||||||
|
|
||||||
sub handler {
|
sub handler {
|
||||||
my $class;
|
shift if($#_);
|
||||||
$class = $#_ ? shift : __PACKAGE__;
|
my $type = Lemonldap::NG::Handler::ApacheMP2::Main->checkType(@_);
|
||||||
|
my $class = "Lemonldap::NG::Handler::ApacheMP2::$type";
|
||||||
|
eval "require $class";
|
||||||
|
die $@ if($@);
|
||||||
my ($res) = $class->run(@_);
|
my ($res) = $class->run(@_);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
## @rmethod protected int redirectFilter(string url, Apache2::Filter f)
|
|
||||||
# Launch the current HTTP request then redirects the user to $url.
|
|
||||||
# Used by logout_app and logout_app_sso targets
|
|
||||||
# @param $url URL to redirect the user
|
|
||||||
# @param $f Current Apache2::Filter object
|
|
||||||
# @return Constant $class->OK
|
|
||||||
sub redirectFilter {
|
|
||||||
my $class = shift;
|
|
||||||
my $url = shift;
|
|
||||||
my $f = shift;
|
|
||||||
unless ( $f->ctx ) {
|
|
||||||
|
|
||||||
# Here, we can use Apache2 functions instead of set_header_out
|
|
||||||
# since this function is used only with Apache2.
|
|
||||||
$f->r->status( $class->REDIRECT );
|
|
||||||
$f->r->status_line("303 See Other");
|
|
||||||
$f->r->headers_out->unset('Location');
|
|
||||||
$f->r->err_headers_out->set( 'Location' => $url );
|
|
||||||
$f->ctx(1);
|
|
||||||
}
|
|
||||||
while ( $f->read( my $buffer, 1024 ) ) {
|
|
||||||
}
|
|
||||||
$class->updateStatus( $f->r, '$class->REDIRECT',
|
|
||||||
$class->datas->{ $class->tsv->{whatToTrace} }, 'filter' );
|
|
||||||
return $class->OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
__PACKAGE__->init();
|
|
||||||
|
|
||||||
# INTERNAL METHODS
|
|
||||||
|
|
||||||
## @method void thread_share(string $variable)
|
|
||||||
# try to share $variable between threads
|
|
||||||
# note: eval is needed,
|
|
||||||
# else it fails to compile if threads::shared is not loaded
|
|
||||||
# @param $variable the name of the variable to share
|
|
||||||
sub thread_share {
|
|
||||||
my ( $class, $variable ) = @_;
|
|
||||||
eval "threads::shared::share(\$variable);";
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void setServerSignature(string sign)
|
|
||||||
# modifies web server signature
|
|
||||||
# @param $sign String to add to server signature
|
|
||||||
sub setServerSignature {
|
|
||||||
my ( $class, $sign ) = @_;
|
|
||||||
eval {
|
|
||||||
Apache2::ServerUtil->server->push_handlers(
|
|
||||||
PerlPostConfigHandler => sub {
|
|
||||||
my ( $c, $l, $t, $s ) = @_;
|
|
||||||
$s->add_version_component($sign);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
sub newRequest {
|
|
||||||
my ( $class, $r ) = @_;
|
|
||||||
$request = $r;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void _lmLog(string $msg, string $level)
|
|
||||||
# logs message $msg to Apache logs with loglevel $level
|
|
||||||
# @param $msg string message to log
|
|
||||||
# @param $level string loglevel
|
|
||||||
sub _lmLog {
|
|
||||||
my ( $class, $msg, $level ) = @_;
|
|
||||||
|
|
||||||
# TODO: remove the useless tag 'ApacheMP2.pm(70):' in debug logs
|
|
||||||
Apache2::ServerRec->log->$level($msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void set_user(string user)
|
|
||||||
# sets remote_user
|
|
||||||
# @param user string username
|
|
||||||
sub set_user {
|
|
||||||
my ( $class, $user ) = @_;
|
|
||||||
$request->user($user);
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string header_in(string header)
|
|
||||||
# returns request header value
|
|
||||||
# @param header string request header
|
|
||||||
# @return request header value
|
|
||||||
sub header_in {
|
|
||||||
my ( $class, $header ) = @_;
|
|
||||||
$header ||= $class; # to use header_in as a method or as a function
|
|
||||||
return $request->headers_in->{$header};
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void set_header_in(hash headers)
|
|
||||||
# sets or modifies request headers
|
|
||||||
# @param headers hash containing header names => header value
|
|
||||||
sub set_header_in {
|
|
||||||
my ( $class, %headers ) = @_;
|
|
||||||
while ( my ( $h, $v ) = each %headers ) {
|
|
||||||
$request->headers_in->set( $h => $v );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void unset_header_in(array headers)
|
|
||||||
# removes request headers
|
|
||||||
# This function looks a bit heavy: it is to ensure that if a request
|
|
||||||
# header 'Auth-User' is removed, 'Auth_User' be removed also
|
|
||||||
# @param headers array with header names to remove
|
|
||||||
sub unset_header_in {
|
|
||||||
my ( $class, @headers ) = @_;
|
|
||||||
foreach my $h1 (@headers) {
|
|
||||||
$h1 = lc $h1;
|
|
||||||
$h1 =~ s/-/_/g;
|
|
||||||
$request->headers_in->do(
|
|
||||||
sub {
|
|
||||||
my $h = shift;
|
|
||||||
my $h2 = lc $h;
|
|
||||||
$h2 =~ s/-/_/g;
|
|
||||||
$request->headers_in->unset($h) if ( $h1 eq $h2 );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void set_header_out(hash headers)
|
|
||||||
# sets response headers
|
|
||||||
# @param headers hash containing header names => header value
|
|
||||||
sub set_header_out {
|
|
||||||
my ( $class, %headers ) = @_;
|
|
||||||
while ( my ( $h, $v ) = each %headers ) {
|
|
||||||
$request->err_headers_out->set( $h => $v );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string hostname()
|
|
||||||
# returns host, as set by full URI or Host header
|
|
||||||
# @return host string Host value
|
|
||||||
sub hostname {
|
|
||||||
my $class = shift;
|
|
||||||
return $request->hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string remote_ip
|
|
||||||
# returns client IP address
|
|
||||||
# @return IP_Addr string client IP
|
|
||||||
sub remote_ip {
|
|
||||||
my $class = shift;
|
|
||||||
my $remote_ip = (
|
|
||||||
$request->connection->can('remote_ip')
|
|
||||||
? $request->connection->remote_ip
|
|
||||||
: $request->connection->client_ip
|
|
||||||
);
|
|
||||||
return $remote_ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method boolean is_initial_req
|
|
||||||
# returns true unless the current request is a subrequest
|
|
||||||
# @return is_initial_req boolean
|
|
||||||
sub is_initial_req {
|
|
||||||
my $class = shift;
|
|
||||||
return $request->is_initial_req;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string args(string args)
|
|
||||||
# gets the query string
|
|
||||||
# @return args string Query string
|
|
||||||
sub args {
|
|
||||||
my $class = shift;
|
|
||||||
return $request->args();
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string uri
|
|
||||||
# returns the path portion of the URI, normalized, i.e. :
|
|
||||||
# * URL decoded (characters encoded as %XX are decoded,
|
|
||||||
# except ? in order not to merge path and query string)
|
|
||||||
# * references to relative path components "." and ".." are resolved
|
|
||||||
# * two or more adjacent slashes are merged into a single slash
|
|
||||||
# @return path portion of the URI, normalized
|
|
||||||
sub uri {
|
|
||||||
my $class = shift;
|
|
||||||
my $uri = $request->uri;
|
|
||||||
$uri =~ s#//+#/#g;
|
|
||||||
$uri =~ s#\?#%3F#g;
|
|
||||||
return $uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string uri_with_args
|
|
||||||
# returns the URI, with arguments and with path portion normalized
|
|
||||||
# @return URI with normalized path portion
|
|
||||||
sub uri_with_args {
|
|
||||||
my $class = shift;
|
|
||||||
return uri . ( $request->args ? "?" . $request->args : "" );
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string unparsed_uri
|
|
||||||
# returns the full original request URI, with arguments
|
|
||||||
# @return full original request URI, with arguments
|
|
||||||
sub unparsed_uri {
|
|
||||||
my $class = shift;
|
|
||||||
return $request->unparsed_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string get_server_port
|
|
||||||
# returns the port the server is receiving the current request on
|
|
||||||
# @return port string server port
|
|
||||||
sub get_server_port {
|
|
||||||
my $class = shift;
|
|
||||||
return $request->get_server_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method string method
|
|
||||||
# returns the port the server is receiving the current request on
|
|
||||||
# @return port string server port
|
|
||||||
sub method {
|
|
||||||
my $class = shift;
|
|
||||||
return $request->method;
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void print(string data)
|
|
||||||
# write data in HTTP response body
|
|
||||||
# @param data Text to add in response body
|
|
||||||
sub print {
|
|
||||||
my ( $class, $data ) = @_;
|
|
||||||
$request->print($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
__END__
|
|
||||||
|
|
||||||
## @method void addToHtmlHead(string data)
|
|
||||||
# add data at end of html head
|
|
||||||
# @param data Text to add in html head
|
|
||||||
sub addToHtmlHead {
|
|
||||||
use APR::Bucket ();
|
|
||||||
use APR::Brigade ();
|
|
||||||
my ( $class, $data ) = @_;
|
|
||||||
$request->add_output_filter(
|
|
||||||
sub {
|
|
||||||
my $f = shift;
|
|
||||||
my $bb = shift;
|
|
||||||
my $ctx = $f->ctx;
|
|
||||||
|
|
||||||
#unless ($ctx) {
|
|
||||||
# $f->r->headers_out->unset('Content-Length');
|
|
||||||
#}
|
|
||||||
my $done = 0;
|
|
||||||
my $buffer = $ctx->{data} ? $ctx->{data} : '';
|
|
||||||
my ( $bdata, $seen_eos ) = flatten_bb($bb);
|
|
||||||
unless ($done) {
|
|
||||||
$done = 1
|
|
||||||
if ( $bdata =~ s/(<\/head>)/$data$1/si
|
|
||||||
or $bdata =~ s/(<body>)/$1$data/si );
|
|
||||||
}
|
|
||||||
$buffer .= $bdata if ($bdata);
|
|
||||||
if ($seen_eos) {
|
|
||||||
my $len = length $buffer;
|
|
||||||
$f->r->headers_out->set( 'Content-Length', $len );
|
|
||||||
$f->print($buffer) if ($buffer);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$ctx->{data} = $buffer;
|
|
||||||
$f->ctx($ctx);
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub flatten_bb {
|
|
||||||
my ($bb) = shift;
|
|
||||||
|
|
||||||
my $seen_eos = 0;
|
|
||||||
|
|
||||||
my @data;
|
|
||||||
for ( my $b = $bb->first ; $b ; $b = $bb->next($b) ) {
|
|
||||||
$seen_eos++, last if $b->is_eos;
|
|
||||||
$b->read( my $bdata );
|
|
||||||
push @data, $bdata;
|
|
||||||
}
|
|
||||||
return ( join( '', @data ), $seen_eos );
|
|
||||||
}
|
|
||||||
|
|
||||||
## @method void setPostParams(hashref $params)
|
|
||||||
# add or modify parameters in POST request body
|
|
||||||
# @param $params hashref containing name => value
|
|
||||||
sub setPostParams {
|
|
||||||
my ( $class, $params ) = @_;
|
|
||||||
$request->add_input_filter(
|
|
||||||
sub {
|
|
||||||
my $f = shift;
|
|
||||||
my $buffer;
|
|
||||||
|
|
||||||
# Filter only POST request body
|
|
||||||
if ( $f->r->method eq "POST" ) {
|
|
||||||
my $body;
|
|
||||||
while ( $f->read($buffer) ) { $body .= $buffer; }
|
|
||||||
while ( my ( $name, $value ) = each(%$params) ) {
|
|
||||||
$body =~ s/((^|&))$name=[^\&]*/$1$name=$value/
|
|
||||||
or $body .= "&$name=$value";
|
|
||||||
}
|
|
||||||
$body =~ s/^&//;
|
|
||||||
$f->print($body);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$f->print($buffer) while ( $f->read($buffer) );
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Auth-basic authentication with Lemonldap::NG rights management
|
||||||
|
|
||||||
|
# This specific handler is intended to be called directly by Apache
|
||||||
|
|
||||||
|
package Lemonldap::NG::Handler::ApacheMP2::AuthBasic;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
use base 'Lemonldap::NG::Handler::Lib::AuthBasic',
|
||||||
|
'Lemonldap::NG::Handler::ApacheMP2::Main';
|
||||||
|
|
||||||
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
|
1;
|
344
lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ApacheMP2/Main.pm
Normal file
344
lemonldap-ng-handler/lib/Lemonldap/NG/Handler/ApacheMP2/Main.pm
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
package Lemonldap::NG::Handler::ApacheMP2::Main;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use AutoLoader 'AUTOLOAD';
|
||||||
|
use Apache2::RequestUtil;
|
||||||
|
use Apache2::RequestRec;
|
||||||
|
use Apache2::Log;
|
||||||
|
use Apache2::ServerUtil;
|
||||||
|
use Apache2::Connection;
|
||||||
|
use Apache2::RequestIO;
|
||||||
|
use Apache2::Const;
|
||||||
|
use Apache2::Filter;
|
||||||
|
use APR::Table;
|
||||||
|
use Apache2::Const -compile =>
|
||||||
|
qw(FORBIDDEN HTTP_UNAUTHORIZED REDIRECT OK DECLINED DONE SERVER_ERROR AUTH_REQUIRED HTTP_SERVICE_UNAVAILABLE);
|
||||||
|
use base 'Lemonldap::NG::Handler::Main';
|
||||||
|
|
||||||
|
use constant FORBIDDEN => Apache2::Const::FORBIDDEN;
|
||||||
|
use constant HTTP_UNAUTHORIZED => Apache2::Const::HTTP_UNAUTHORIZED;
|
||||||
|
use constant REDIRECT => Apache2::Const::REDIRECT;
|
||||||
|
use constant OK => Apache2::Const::OK;
|
||||||
|
use constant DECLINED => Apache2::Const::DECLINED;
|
||||||
|
use constant DONE => Apache2::Const::DONE;
|
||||||
|
use constant SERVER_ERROR => Apache2::Const::SERVER_ERROR;
|
||||||
|
use constant AUTH_REQUIRED => Apache2::Const::AUTH_REQUIRED;
|
||||||
|
use constant MAINTENANCE => Apache2::Const::HTTP_SERVICE_UNAVAILABLE;
|
||||||
|
use constant BUFF_LEN => 8192;
|
||||||
|
|
||||||
|
eval { require threads::shared; };
|
||||||
|
|
||||||
|
our $request; # Apache2::RequestRec object for current request
|
||||||
|
|
||||||
|
#*run = \&Lemonldap::NG::Handler::Main::run;
|
||||||
|
|
||||||
|
## @rmethod protected int redirectFilter(string url, Apache2::Filter f)
|
||||||
|
# Launch the current HTTP request then redirects the user to $url.
|
||||||
|
# Used by logout_app and logout_app_sso targets
|
||||||
|
# @param $url URL to redirect the user
|
||||||
|
# @param $f Current Apache2::Filter object
|
||||||
|
# @return Constant $class->OK
|
||||||
|
sub redirectFilter {
|
||||||
|
my $class = shift;
|
||||||
|
my $url = shift;
|
||||||
|
my $f = shift;
|
||||||
|
unless ( $f->ctx ) {
|
||||||
|
|
||||||
|
# Here, we can use Apache2 functions instead of set_header_out
|
||||||
|
# since this function is used only with Apache2.
|
||||||
|
$f->r->status( $class->REDIRECT );
|
||||||
|
$f->r->status_line("303 See Other");
|
||||||
|
$f->r->headers_out->unset('Location');
|
||||||
|
$f->r->err_headers_out->set( 'Location' => $url );
|
||||||
|
$f->ctx(1);
|
||||||
|
}
|
||||||
|
while ( $f->read( my $buffer, 1024 ) ) {
|
||||||
|
}
|
||||||
|
$class->updateStatus( $f->r, '$class->REDIRECT',
|
||||||
|
$class->datas->{ $class->tsv->{whatToTrace} }, 'filter' );
|
||||||
|
return $class->OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
__PACKAGE__->init();
|
||||||
|
|
||||||
|
# INTERNAL METHODS
|
||||||
|
|
||||||
|
## @method void thread_share(string $variable)
|
||||||
|
# try to share $variable between threads
|
||||||
|
# note: eval is needed,
|
||||||
|
# else it fails to compile if threads::shared is not loaded
|
||||||
|
# @param $variable the name of the variable to share
|
||||||
|
sub thread_share {
|
||||||
|
my ( $class, $variable ) = @_;
|
||||||
|
eval "threads::shared::share(\$variable);";
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void setServerSignature(string sign)
|
||||||
|
# modifies web server signature
|
||||||
|
# @param $sign String to add to server signature
|
||||||
|
sub setServerSignature {
|
||||||
|
my ( $class, $sign ) = @_;
|
||||||
|
eval {
|
||||||
|
Apache2::ServerUtil->server->push_handlers(
|
||||||
|
PerlPostConfigHandler => sub {
|
||||||
|
my ( $c, $l, $t, $s ) = @_;
|
||||||
|
$s->add_version_component($sign);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub newRequest {
|
||||||
|
my ( $class, $r ) = @_;
|
||||||
|
$request = $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void _lmLog(string $msg, string $level)
|
||||||
|
# logs message $msg to Apache logs with loglevel $level
|
||||||
|
# @param $msg string message to log
|
||||||
|
# @param $level string loglevel
|
||||||
|
sub _lmLog {
|
||||||
|
my ( $class, $msg, $level ) = @_;
|
||||||
|
|
||||||
|
# TODO: remove the useless tag 'ApacheMP2.pm(70):' in debug logs
|
||||||
|
Apache2::ServerRec->log->$level($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void set_user(string user)
|
||||||
|
# sets remote_user
|
||||||
|
# @param user string username
|
||||||
|
sub set_user {
|
||||||
|
my ( $class, $user ) = @_;
|
||||||
|
$request->user($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string header_in(string header)
|
||||||
|
# returns request header value
|
||||||
|
# @param header string request header
|
||||||
|
# @return request header value
|
||||||
|
sub header_in {
|
||||||
|
my ( $class, $header ) = @_;
|
||||||
|
$header ||= $class; # to use header_in as a method or as a function
|
||||||
|
return $request->headers_in->{$header};
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void set_header_in(hash headers)
|
||||||
|
# sets or modifies request headers
|
||||||
|
# @param headers hash containing header names => header value
|
||||||
|
sub set_header_in {
|
||||||
|
my ( $class, %headers ) = @_;
|
||||||
|
while ( my ( $h, $v ) = each %headers ) {
|
||||||
|
$request->headers_in->set( $h => $v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void unset_header_in(array headers)
|
||||||
|
# removes request headers
|
||||||
|
# This function looks a bit heavy: it is to ensure that if a request
|
||||||
|
# header 'Auth-User' is removed, 'Auth_User' be removed also
|
||||||
|
# @param headers array with header names to remove
|
||||||
|
sub unset_header_in {
|
||||||
|
my ( $class, @headers ) = @_;
|
||||||
|
foreach my $h1 (@headers) {
|
||||||
|
$h1 = lc $h1;
|
||||||
|
$h1 =~ s/-/_/g;
|
||||||
|
$request->headers_in->do(
|
||||||
|
sub {
|
||||||
|
my $h = shift;
|
||||||
|
my $h2 = lc $h;
|
||||||
|
$h2 =~ s/-/_/g;
|
||||||
|
$request->headers_in->unset($h) if ( $h1 eq $h2 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void set_header_out(hash headers)
|
||||||
|
# sets response headers
|
||||||
|
# @param headers hash containing header names => header value
|
||||||
|
sub set_header_out {
|
||||||
|
my ( $class, %headers ) = @_;
|
||||||
|
while ( my ( $h, $v ) = each %headers ) {
|
||||||
|
$request->err_headers_out->set( $h => $v );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string hostname()
|
||||||
|
# returns host, as set by full URI or Host header
|
||||||
|
# @return host string Host value
|
||||||
|
sub hostname {
|
||||||
|
my $class = shift;
|
||||||
|
return $request->hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string remote_ip
|
||||||
|
# returns client IP address
|
||||||
|
# @return IP_Addr string client IP
|
||||||
|
sub remote_ip {
|
||||||
|
my $class = shift;
|
||||||
|
my $remote_ip = (
|
||||||
|
$request->connection->can('remote_ip')
|
||||||
|
? $request->connection->remote_ip
|
||||||
|
: $request->connection->client_ip
|
||||||
|
);
|
||||||
|
return $remote_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method boolean is_initial_req
|
||||||
|
# returns true unless the current request is a subrequest
|
||||||
|
# @return is_initial_req boolean
|
||||||
|
sub is_initial_req {
|
||||||
|
my $class = shift;
|
||||||
|
return $request->is_initial_req;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string args(string args)
|
||||||
|
# gets the query string
|
||||||
|
# @return args string Query string
|
||||||
|
sub args {
|
||||||
|
my $class = shift;
|
||||||
|
return $request->args();
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string uri
|
||||||
|
# returns the path portion of the URI, normalized, i.e. :
|
||||||
|
# * URL decoded (characters encoded as %XX are decoded,
|
||||||
|
# except ? in order not to merge path and query string)
|
||||||
|
# * references to relative path components "." and ".." are resolved
|
||||||
|
# * two or more adjacent slashes are merged into a single slash
|
||||||
|
# @return path portion of the URI, normalized
|
||||||
|
sub uri {
|
||||||
|
my $class = shift;
|
||||||
|
my $uri = $request->uri;
|
||||||
|
$uri =~ s#//+#/#g;
|
||||||
|
$uri =~ s#\?#%3F#g;
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string uri_with_args
|
||||||
|
# returns the URI, with arguments and with path portion normalized
|
||||||
|
# @return URI with normalized path portion
|
||||||
|
sub uri_with_args {
|
||||||
|
my $class = shift;
|
||||||
|
return uri . ( $request->args ? "?" . $request->args : "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string unparsed_uri
|
||||||
|
# returns the full original request URI, with arguments
|
||||||
|
# @return full original request URI, with arguments
|
||||||
|
sub unparsed_uri {
|
||||||
|
my $class = shift;
|
||||||
|
return $request->unparsed_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string get_server_port
|
||||||
|
# returns the port the server is receiving the current request on
|
||||||
|
# @return port string server port
|
||||||
|
sub get_server_port {
|
||||||
|
my $class = shift;
|
||||||
|
return $request->get_server_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method string method
|
||||||
|
# returns the port the server is receiving the current request on
|
||||||
|
# @return port string server port
|
||||||
|
sub method {
|
||||||
|
my $class = shift;
|
||||||
|
return $request->method;
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void print(string data)
|
||||||
|
# write data in HTTP response body
|
||||||
|
# @param data Text to add in response body
|
||||||
|
sub print {
|
||||||
|
my ( $class, $data ) = @_;
|
||||||
|
$request->print($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
## @method void addToHtmlHead(string data)
|
||||||
|
# add data at end of html head
|
||||||
|
# @param data Text to add in html head
|
||||||
|
sub addToHtmlHead {
|
||||||
|
use APR::Bucket ();
|
||||||
|
use APR::Brigade ();
|
||||||
|
my ( $class, $data ) = @_;
|
||||||
|
$request->add_output_filter(
|
||||||
|
sub {
|
||||||
|
my $f = shift;
|
||||||
|
my $bb = shift;
|
||||||
|
my $ctx = $f->ctx;
|
||||||
|
|
||||||
|
#unless ($ctx) {
|
||||||
|
# $f->r->headers_out->unset('Content-Length');
|
||||||
|
#}
|
||||||
|
my $done = 0;
|
||||||
|
my $buffer = $ctx->{data} ? $ctx->{data} : '';
|
||||||
|
my ( $bdata, $seen_eos ) = flatten_bb($bb);
|
||||||
|
unless ($done) {
|
||||||
|
$done = 1
|
||||||
|
if ( $bdata =~ s/(<\/head>)/$data$1/si
|
||||||
|
or $bdata =~ s/(<body>)/$1$data/si );
|
||||||
|
}
|
||||||
|
$buffer .= $bdata if ($bdata);
|
||||||
|
if ($seen_eos) {
|
||||||
|
my $len = length $buffer;
|
||||||
|
$f->r->headers_out->set( 'Content-Length', $len );
|
||||||
|
$f->print($buffer) if ($buffer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ctx->{data} = $buffer;
|
||||||
|
$f->ctx($ctx);
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub flatten_bb {
|
||||||
|
my ($bb) = shift;
|
||||||
|
|
||||||
|
my $seen_eos = 0;
|
||||||
|
|
||||||
|
my @data;
|
||||||
|
for ( my $b = $bb->first ; $b ; $b = $bb->next($b) ) {
|
||||||
|
$seen_eos++, last if $b->is_eos;
|
||||||
|
$b->read( my $bdata );
|
||||||
|
push @data, $bdata;
|
||||||
|
}
|
||||||
|
return ( join( '', @data ), $seen_eos );
|
||||||
|
}
|
||||||
|
|
||||||
|
## @method void setPostParams(hashref $params)
|
||||||
|
# add or modify parameters in POST request body
|
||||||
|
# @param $params hashref containing name => value
|
||||||
|
sub setPostParams {
|
||||||
|
my ( $class, $params ) = @_;
|
||||||
|
$request->add_input_filter(
|
||||||
|
sub {
|
||||||
|
my $f = shift;
|
||||||
|
my $buffer;
|
||||||
|
|
||||||
|
# Filter only POST request body
|
||||||
|
if ( $f->r->method eq "POST" ) {
|
||||||
|
my $body;
|
||||||
|
while ( $f->read($buffer) ) { $body .= $buffer; }
|
||||||
|
while ( my ( $name, $value ) = each(%$params) ) {
|
||||||
|
$body =~ s/((^|&))$name=[^\&]*/$1$name=$value/
|
||||||
|
or $body .= "&$name=$value";
|
||||||
|
}
|
||||||
|
$body =~ s/^&//;
|
||||||
|
$f->print($body);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$f->print($buffer) while ( $f->read($buffer) );
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
# Auth-basic authentication with Lemonldap::NG rights management
|
|
||||||
|
|
||||||
# This specific handler is intended to be called directly by Apache
|
|
||||||
|
|
||||||
package Lemonldap::NG::Handler::AuthBasic;
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use Lemonldap::NG::Handler::ApacheMP2;
|
|
||||||
use Lemonldap::NG::Handler::Lib::AuthBasic;
|
|
||||||
|
|
||||||
BEGIN {
|
|
||||||
our @ISA = ('Lemonldap::NG::Handler::Main');
|
|
||||||
}
|
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
|
||||||
|
|
||||||
# PUBLIC METHODS
|
|
||||||
|
|
||||||
sub handler {
|
|
||||||
my $class;
|
|
||||||
$class = $#_ ? shift : __PACKAGE__;
|
|
||||||
my ($res) = $class->run(@_);
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
# For an obscur reason, inheritance isn't possible with ApacheMP2.pm.
|
|
||||||
|
|
||||||
*FORBIDDEN = *Lemonldap::NG::Handler::ApacheMP2::FORBIDDEN;
|
|
||||||
*HTTP_UNAUTHORIZED = *Lemonldap::NG::Handler::ApacheMP2::HTTP_UNAUTHORIZED;
|
|
||||||
*REDIRECT = *Lemonldap::NG::Handler::ApacheMP2::REDIRECT;
|
|
||||||
*OK = *Lemonldap::NG::Handler::ApacheMP2::OK;
|
|
||||||
*DECLINED = *Lemonldap::NG::Handler::ApacheMP2::DECLINED;
|
|
||||||
*DONE = *Lemonldap::NG::Handler::ApacheMP2::DONE;
|
|
||||||
*SERVER_ERROR = *Lemonldap::NG::Handler::ApacheMP2::SERVER_ERROR;
|
|
||||||
*AUTH_REQUIRED = *Lemonldap::NG::Handler::ApacheMP2::AUTH_REQUIRED;
|
|
||||||
*MAINTENANCE = *Lemonldap::NG::Handler::ApacheMP2::MAINTENANCE;
|
|
||||||
|
|
||||||
*_lmLog = *Lemonldap::NG::Handler::ApacheMP2::_lmLog;
|
|
||||||
*addToHtmlHead = *Lemonldap::NG::Handler::ApacheMP2::addToHtmlHead;
|
|
||||||
*args = *Lemonldap::NG::Handler::ApacheMP2::args;
|
|
||||||
*flatten_bb = *Lemonldap::NG::Handler::ApacheMP2::flatten_bb;
|
|
||||||
*get_server_port = *Lemonldap::NG::Handler::ApacheMP2::get_server_port;
|
|
||||||
*header_in = *Lemonldap::NG::Handler::ApacheMP2::header_in;
|
|
||||||
*hostname = *Lemonldap::NG::Handler::ApacheMP2::hostname;
|
|
||||||
*is_initial_req = *Lemonldap::NG::Handler::ApacheMP2::is_initial_req;
|
|
||||||
*method = *Lemonldap::NG::Handler::ApacheMP2::method;
|
|
||||||
*newRequest = *Lemonldap::NG::Handler::ApacheMP2::newRequest;
|
|
||||||
*print = *Lemonldap::NG::Handler::ApacheMP2::print;
|
|
||||||
*redirectFilter = *Lemonldap::NG::Handler::ApacheMP2::redirectFilter;
|
|
||||||
*remote_ip = *Lemonldap::NG::Handler::ApacheMP2::remote_ip;
|
|
||||||
*set_header_in = *Lemonldap::NG::Handler::ApacheMP2::set_header_in;
|
|
||||||
*set_header_out = *Lemonldap::NG::Handler::ApacheMP2::set_header_out;
|
|
||||||
*set_user = *Lemonldap::NG::Handler::ApacheMP2::set_user;
|
|
||||||
*setPostParams = *Lemonldap::NG::Handler::ApacheMP2::setPostParams;
|
|
||||||
*setServerSignature = *Lemonldap::NG::Handler::ApacheMP2::setServerSignature;
|
|
||||||
*thread_share = *Lemonldap::NG::Handler::ApacheMP2::thread_share;
|
|
||||||
*unparsed_uri = *Lemonldap::NG::Handler::ApacheMP2::unparsed_uri;
|
|
||||||
*unset_header_in = *Lemonldap::NG::Handler::ApacheMP2::unset_header_in;
|
|
||||||
*uri = *Lemonldap::NG::Handler::ApacheMP2::uri;
|
|
||||||
*uri_with_args = *Lemonldap::NG::Handler::ApacheMP2::uri_with_args;
|
|
||||||
*unparsed_uri = *Lemonldap::NG::Handler::ApacheMP2::unparsed_uri;
|
|
||||||
|
|
||||||
__PACKAGE__->init();
|
|
||||||
|
|
||||||
1;
|
|
|
@ -42,11 +42,11 @@ sub retrieveSession {
|
||||||
|
|
||||||
# First check if session already exists
|
# First check if session already exists
|
||||||
return 1
|
return 1
|
||||||
if ( $class->Lemonldap::NG::Handler::Main::Run::retrieveSession($id) );
|
if ( $class->Lemonldap::NG::Handler::Main::retrieveSession($id) );
|
||||||
|
|
||||||
# Then ask portal to create it
|
# Then ask portal to create it
|
||||||
if ( $class->createSession($id) ) {
|
if ( $class->createSession($id) ) {
|
||||||
return $class->Lemonldap::NG::Handler::Main::Run::retrieveSession($id);
|
return $class->Lemonldap::NG::Handler::Main::retrieveSession($id);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -65,15 +65,16 @@ sub createSession {
|
||||||
$xheader .= $class->remote_ip;
|
$xheader .= $class->remote_ip;
|
||||||
my $soapHeaders = HTTP::Headers->new( "X-Forwarded-For" => $xheader );
|
my $soapHeaders = HTTP::Headers->new( "X-Forwarded-For" => $xheader );
|
||||||
|
|
||||||
my $soapClient = SOAP::Lite->proxy( $class->tsv->{portal}->(),
|
# TODO: use adminSession or sessions
|
||||||
default_headers => $soapHeaders )
|
my $soapClient = SOAP::Lite->proxy(
|
||||||
->uri('urn:Lemonldap/NG/Common/PSGI/SOAPService');
|
$class->tsv->{portal}->() . '/sessions',
|
||||||
|
default_headers => $soapHeaders
|
||||||
|
)->uri('urn:Lemonldap/NG/Common/PSGI/SOAPService');
|
||||||
|
|
||||||
my $creds = $class->header_in('Authorization');
|
my $creds = $class->header_in('Authorization');
|
||||||
$creds =~ s/^Basic\s+//;
|
$creds =~ s/^Basic\s+//;
|
||||||
my ( $user, $pwd ) = ( decode_base64($creds) =~ /^(.*?):(.*)$/ );
|
my ( $user, $pwd ) = ( decode_base64($creds) =~ /^(.*?):(.*)$/ );
|
||||||
$class->lmLog( "AuthBasic authentication for user: $user", 'debug' );
|
$class->lmLog( "AuthBasic authentication for user: $user", 'debug' );
|
||||||
die 'Replace this by REST call';
|
|
||||||
my $soapRequest = $soapClient->getCookies( $user, $pwd, $id );
|
my $soapRequest = $soapClient->getCookies( $user, $pwd, $id );
|
||||||
|
|
||||||
# Catch SOAP errors
|
# Catch SOAP errors
|
||||||
|
@ -116,8 +117,7 @@ sub hideCookie {
|
||||||
sub goToPortal {
|
sub goToPortal {
|
||||||
my ( $class, $url, $arg ) = @_;
|
my ( $class, $url, $arg ) = @_;
|
||||||
if ($arg) {
|
if ($arg) {
|
||||||
return $class->Lemonldap::NG::Handler::Main::Run::goToPortal( $url,
|
return $class->Lemonldap::NG::Handler::Main::goToPortal( $url, $arg );
|
||||||
$arg );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$class->set_header_out(
|
$class->set_header_out(
|
||||||
|
|
|
@ -6,13 +6,6 @@ use Lemonldap::NG::Handler::Main::Reload;
|
||||||
use Lemonldap::NG::Handler::Main::Run;
|
use Lemonldap::NG::Handler::Main::Run;
|
||||||
use Lemonldap::NG::Handler::Main::SharedVariables;
|
use Lemonldap::NG::Handler::Main::SharedVariables;
|
||||||
|
|
||||||
our @ISA = qw(
|
|
||||||
Lemonldap::NG::Handler::Main::Init
|
|
||||||
Lemonldap::NG::Handler::Main::SharedVariables
|
|
||||||
Lemonldap::NG::Handler::Main::Reload
|
|
||||||
Lemonldap::NG::Handler::Main::Run
|
|
||||||
);
|
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package Lemonldap::NG::Handler::Main::Init;
|
package Lemonldap::NG::Handler::Main::Init;
|
||||||
|
|
||||||
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
|
package Lemonldap::NG::Handler::Main;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Lemonldap::NG::Common::Conf;
|
use Lemonldap::NG::Common::Conf;
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
|
||||||
|
|
||||||
## @imethod void init(hashRef args)
|
## @imethod void init(hashRef args)
|
||||||
# Read parameters and build the Lemonldap::NG::Common::Conf object.
|
# Read parameters and build the Lemonldap::NG::Common::Conf object.
|
||||||
# @param $args hash containing parameters
|
# @param $args hash containing parameters
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package Lemonldap::NG::Handler::Main::Reload;
|
package Lemonldap::NG::Handler::Main::Reload;
|
||||||
|
|
||||||
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
|
package Lemonldap::NG::Handler::Main;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
use Lemonldap::NG::Common::Conf::Constants; #inherits
|
||||||
use Lemonldap::NG::Common::Crypto;
|
use Lemonldap::NG::Common::Crypto;
|
||||||
|
@ -10,8 +14,6 @@ use Scalar::Util qw(weaken);
|
||||||
use constant UNPROTECT => 1;
|
use constant UNPROTECT => 1;
|
||||||
use constant SKIP => 2;
|
use constant SKIP => 2;
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
|
||||||
|
|
||||||
our @_onReload;
|
our @_onReload;
|
||||||
|
|
||||||
sub onReload {
|
sub onReload {
|
||||||
|
@ -215,6 +217,12 @@ sub defaultValuesInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( $conf->{vhostOptions} ) {
|
||||||
|
foreach my $vhost ( keys %{ $conf->{vhostOptions} } ) {
|
||||||
|
$class->tsv->{type}->{$vhost} =
|
||||||
|
$conf->{vhostOptions}->{$vhost}->{vhostType};
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package Lemonldap::NG::Handler::Main::Run;
|
package Lemonldap::NG::Handler::Main::Run;
|
||||||
|
|
||||||
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
|
package Lemonldap::NG::Handler::Main;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
#use AutoLoader 'AUTOLOAD';
|
#use AutoLoader 'AUTOLOAD';
|
||||||
use MIME::Base64;
|
use MIME::Base64;
|
||||||
use URI::Escape;
|
use URI::Escape;
|
||||||
use Lemonldap::NG::Common::Session;
|
use Lemonldap::NG::Common::Session;
|
||||||
our $VERSION = '2.0.0';
|
|
||||||
|
|
||||||
# PUBLIC METHODS
|
# PUBLIC METHODS
|
||||||
|
|
||||||
|
@ -45,6 +48,21 @@ sub status {
|
||||||
return $class->OK;
|
return $class->OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub checkType {
|
||||||
|
my ( $class, $req ) = @_;
|
||||||
|
|
||||||
|
$class->newRequest($req);
|
||||||
|
if ( time() - $class->lastCheck > $class->checkTime ) {
|
||||||
|
die("$class: No configuration found")
|
||||||
|
unless ( $class->checkConf );
|
||||||
|
}
|
||||||
|
my $vhost = $class->resolveAlias;
|
||||||
|
return
|
||||||
|
( defined $class->tsv->{type}->{$vhost} )
|
||||||
|
? $class->tsv->{type}->{$vhost}
|
||||||
|
: 'Main';
|
||||||
|
}
|
||||||
|
|
||||||
## @rmethod int run
|
## @rmethod int run
|
||||||
# Check configuration and launch Lemonldap::NG::Handler::Main::run().
|
# Check configuration and launch Lemonldap::NG::Handler::Main::run().
|
||||||
# Each $checkTime, the Apache child verify if its configuration is the same
|
# Each $checkTime, the Apache child verify if its configuration is the same
|
||||||
|
@ -56,11 +74,6 @@ sub run {
|
||||||
my ( $class, $req, $rule, $protection ) = @_;
|
my ( $class, $req, $rule, $protection ) = @_;
|
||||||
my ( $id, $session );
|
my ( $id, $session );
|
||||||
|
|
||||||
$class->newRequest($req);
|
|
||||||
if ( time() - $class->lastCheck > $class->checkTime ) {
|
|
||||||
die("$class: No configuration found")
|
|
||||||
unless ( $class->checkConf );
|
|
||||||
}
|
|
||||||
return $class->DECLINED unless ( $class->is_initial_req );
|
return $class->DECLINED unless ( $class->is_initial_req );
|
||||||
|
|
||||||
# Direct return if maintenance mode is active
|
# Direct return if maintenance mode is active
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package Lemonldap::NG::Handler::Main::SharedVariables;
|
package Lemonldap::NG::Handler::Main::SharedVariables;
|
||||||
|
|
||||||
|
our $VERSION = '2.0.0';
|
||||||
|
|
||||||
# Since handler has no instances but only static classes, this module provides
|
# Since handler has no instances but only static classes, this module provides
|
||||||
# classes properties with accessors
|
# classes properties with accessors
|
||||||
|
|
||||||
use strict;
|
package Lemonldap::NG::Handler::Main;
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
use strict;
|
||||||
|
|
||||||
# Thread shared properties (if threads are available: needs to be loaded elsewhere)
|
# Thread shared properties (if threads are available: needs to be loaded elsewhere)
|
||||||
our $_tshv = {
|
our $_tshv = {
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
package Lemonldap::NG::Handler::Menu;
|
package Lemonldap::NG::Handler::Menu;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Lemonldap::NG::Handler::ApacheMP2 qw(:all);
|
use Lemonldap::NG::Handler::ApacheMP2::Main qw(:all);
|
||||||
use base qw(Lemonldap::NG::Handler::ApacheMP2);
|
use base qw(Lemonldap::NG::Handler::ApacheMP2::Main);
|
||||||
use Apache2::Filter ();
|
use Apache2::Filter ();
|
||||||
use constant BUFF_LEN => 8192;
|
use constant BUFF_LEN => 8192;
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,9 @@ sub reload {
|
||||||
# response is 200.
|
# response is 200.
|
||||||
sub _authAndTrace {
|
sub _authAndTrace {
|
||||||
my ( $self, $req, $noCall ) = @_;
|
my ( $self, $req, $noCall ) = @_;
|
||||||
|
|
||||||
|
# TODO: handle types
|
||||||
|
my $type = $self->api->checkType($req);
|
||||||
my ( $res, $session ) = $self->api->run( $req, $self->{rule} );
|
my ( $res, $session ) = $self->api->run( $req, $self->{rule} );
|
||||||
$self->portal( $self->api->tsv->{portal}->() );
|
$self->portal( $self->api->tsv->{portal}->() );
|
||||||
$req->userData($session) if ($session);
|
$req->userData($session) if ($session);
|
||||||
|
|
|
@ -12,7 +12,7 @@ package Lemonldap::NG::Handler::Specific::ZimbraPreAuth;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Lemonldap::NG::Handler::ApacheMP2 qw(:all);
|
use Lemonldap::NG::Handler::ApacheMP2 qw(:all);
|
||||||
use base qw(Lemonldap::NG::Handler::ApacheMP2);
|
use base qw(Lemonldap::NG::Handler::ApacheMP2::Main);
|
||||||
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);
|
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);
|
||||||
|
|
||||||
our $VERSION = '2.0.0';
|
our $VERSION = '2.0.0';
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# change 'tests => 1' to 'tests => last_test_to_print';
|
# change 'tests => 1' to 'tests => last_test_to_print';
|
||||||
|
|
||||||
use Test::More tests => 5;
|
use Test::More tests => 6;
|
||||||
use Cwd 'abs_path';
|
use Cwd 'abs_path';
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use File::Temp;
|
use File::Temp;
|
||||||
|
@ -55,6 +55,8 @@ my $h = 'Lemonldap::NG::Handler::Test';
|
||||||
|
|
||||||
ok( $h->init(), 'Initialize handler' );
|
ok( $h->init(), 'Initialize handler' );
|
||||||
|
|
||||||
|
ok( $h->checkType($apacheRequest) eq 'Main', 'Get Main type');
|
||||||
|
|
||||||
ok( $ret = $h->run($apacheRequest),
|
ok( $ret = $h->run($apacheRequest),
|
||||||
'run Handler with basic configuration and no cookie' );
|
'run Handler with basic configuration and no cookie' );
|
||||||
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
# Before `make install' is performed this script should be runnable with
|
|
||||||
# `make test'. After `make install' it should work as `perl Lemonldap-NG-Handler-Proxy.t'
|
|
||||||
|
|
||||||
#########################
|
|
||||||
|
|
||||||
# change 'tests => 1' to 'tests => last_test_to_print';
|
|
||||||
|
|
||||||
use Test::More tests => 1;
|
|
||||||
use Cwd 'abs_path';
|
|
||||||
use File::Basename;
|
|
||||||
use File::Temp;
|
|
||||||
|
|
||||||
my $ini = File::Temp->new();
|
|
||||||
my $dir = dirname( abs_path($0) );
|
|
||||||
|
|
||||||
print $ini "[all]
|
|
||||||
|
|
||||||
[configuration]
|
|
||||||
type=File
|
|
||||||
dirName=$dir
|
|
||||||
";
|
|
||||||
|
|
||||||
$ini->flush();
|
|
||||||
|
|
||||||
use Env qw(LLNG_DEFAULTCONFFILE);
|
|
||||||
$LLNG_DEFAULTCONFFILE = $ini->filename;
|
|
||||||
|
|
||||||
open STDERR, '>/dev/null';
|
|
||||||
|
|
||||||
#########################
|
|
||||||
|
|
||||||
# Insert your test code below, the Test::More module is use()ed here so read
|
|
||||||
# its man page ( perldoc Test::More ) for help writing this test script.
|
|
||||||
use_ok('Lemonldap::NG::Handler::AuthBasic');
|
|
||||||
|
|
||||||
$LLNG_DEFAULTCONFFILE = undef;
|
|
|
@ -2983,6 +2983,28 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
|
||||||
'default' => -1,
|
'default' => -1,
|
||||||
'type' => 'int'
|
'type' => 'int'
|
||||||
},
|
},
|
||||||
|
'vhostType' => {
|
||||||
|
'default' => 'Main',
|
||||||
|
'select' => [
|
||||||
|
{
|
||||||
|
'k' => 'Main',
|
||||||
|
'v' => 'Main'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'k' => 'Zimbra',
|
||||||
|
'v' => 'ZimbraPreAuth'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'k' => 'AuthBasic',
|
||||||
|
'v' => 'AuthBasic'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'k' => 'SecureToken',
|
||||||
|
'v' => 'SecureToken'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'type' => 'select'
|
||||||
|
},
|
||||||
'virtualHosts' => {
|
'virtualHosts' => {
|
||||||
'type' => 'virtualHostContainer'
|
'type' => 'virtualHostContainer'
|
||||||
},
|
},
|
||||||
|
|
|
@ -1131,6 +1131,17 @@ sub attributes {
|
||||||
vhostAliases => {
|
vhostAliases => {
|
||||||
type => 'text',
|
type => 'text',
|
||||||
},
|
},
|
||||||
|
vhostType => {
|
||||||
|
type => 'select',
|
||||||
|
select => [
|
||||||
|
{ k => 'Main', v => 'Main' },
|
||||||
|
{ k => 'Zimbra', v => 'ZimbraPreAuth' },
|
||||||
|
{ k => 'AuthBasic', v => 'AuthBasic' },
|
||||||
|
{ k => 'SecureToken', v => 'SecureToken' },
|
||||||
|
],
|
||||||
|
default => 'Main',
|
||||||
|
documentation => 'Handler type',
|
||||||
|
},
|
||||||
|
|
||||||
# CAS IDP
|
# CAS IDP
|
||||||
casAttr => { type => 'text', },
|
casAttr => { type => 'text', },
|
||||||
|
@ -2277,19 +2288,19 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
||||||
keyTest => qr/^\w+$/,
|
keyTest => qr/^\w+$/,
|
||||||
test => sub { 1 },
|
test => sub { 1 },
|
||||||
documentation => 'Combination module description',
|
documentation => 'Combination module description',
|
||||||
select => [
|
select => [
|
||||||
{ k => 'Apache', v => 'Apache' },
|
{ k => 'Apache', v => 'Apache' },
|
||||||
{ k => 'AD', v => 'Active Directory' },
|
{ k => 'AD', v => 'Active Directory' },
|
||||||
{ k => 'DBI', v => 'Database (DBI)' },
|
{ k => 'DBI', v => 'Database (DBI)' },
|
||||||
{ k => 'Facebook', v => 'Facebook' },
|
{ k => 'Facebook', v => 'Facebook' },
|
||||||
{ k => 'Google', v => 'Google' },
|
{ k => 'Google', v => 'Google' },
|
||||||
{ k => 'LDAP', v => 'LDAP' },
|
{ k => 'LDAP', v => 'LDAP' },
|
||||||
{ k => 'Radius', v => 'Radius' },
|
{ k => 'Radius', v => 'Radius' },
|
||||||
{ k => 'SSL', v => 'SSL' },
|
{ k => 'SSL', v => 'SSL' },
|
||||||
{ k => 'Twitter', v => 'Twitter' },
|
{ k => 'Twitter', v => 'Twitter' },
|
||||||
{ k => 'WebID', v => 'WebID' },
|
{ k => 'WebID', v => 'WebID' },
|
||||||
{ k => 'Yubikey', v => 'Yubikey' },
|
{ k => 'Yubikey', v => 'Yubikey' },
|
||||||
{ k => 'Demo', v => 'Demonstration' },
|
{ k => 'Demo', v => 'Demonstration' },
|
||||||
{ k => 'CAS', v => 'Central Authentication Service (CAS)' },
|
{ k => 'CAS', v => 'Central Authentication Service (CAS)' },
|
||||||
{ k => 'OpenID', v => 'OpenID' },
|
{ k => 'OpenID', v => 'OpenID' },
|
||||||
{ k => 'OpenIDConnect', v => 'OpenID Connect' },
|
{ k => 'OpenIDConnect', v => 'OpenID Connect' },
|
||||||
|
|
|
@ -25,7 +25,7 @@ sub cTrees {
|
||||||
help => 'configvhost.html#options',
|
help => 'configvhost.html#options',
|
||||||
nodes => [
|
nodes => [
|
||||||
'vhostPort', 'vhostHttps',
|
'vhostPort', 'vhostHttps',
|
||||||
'vhostMaintenance', 'vhostAliases'
|
'vhostMaintenance', 'vhostAliases', 'vhostType',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -915,6 +915,31 @@ function templates(tpl,key) {
|
||||||
"get" : tpl+"s/"+key+"/"+"vhostAliases",
|
"get" : tpl+"s/"+key+"/"+"vhostAliases",
|
||||||
"id" : tpl+"s/"+key+"/"+"vhostAliases",
|
"id" : tpl+"s/"+key+"/"+"vhostAliases",
|
||||||
"title" : "vhostAliases"
|
"title" : "vhostAliases"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default" : "Main",
|
||||||
|
"get" : tpl+"s/"+key+"/"+"vhostType",
|
||||||
|
"id" : tpl+"s/"+key+"/"+"vhostType",
|
||||||
|
"select" : [
|
||||||
|
{
|
||||||
|
"k" : "Main",
|
||||||
|
"v" : "Main"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"k" : "Zimbra",
|
||||||
|
"v" : "ZimbraPreAuth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"k" : "AuthBasic",
|
||||||
|
"v" : "AuthBasic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"k" : "SecureToken",
|
||||||
|
"v" : "SecureToken"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title" : "vhostType",
|
||||||
|
"type" : "select"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"help" : "configvhost.html#options",
|
"help" : "configvhost.html#options",
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -671,6 +671,7 @@
|
||||||
"vhostMaintenance": "Maintenance mode",
|
"vhostMaintenance": "Maintenance mode",
|
||||||
"vhostOptions": "Options",
|
"vhostOptions": "Options",
|
||||||
"vhostPort": "Port",
|
"vhostPort": "Port",
|
||||||
|
"vhostType": "Type",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
"virtualHost": "Virtual Host",
|
"virtualHost": "Virtual Host",
|
||||||
"virtualHostName": "Virtual host hostname",
|
"virtualHostName": "Virtual host hostname",
|
||||||
|
|
|
@ -671,6 +671,7 @@
|
||||||
"vhostMaintenance": "Mode maintenance",
|
"vhostMaintenance": "Mode maintenance",
|
||||||
"vhostOptions": "Options",
|
"vhostOptions": "Options",
|
||||||
"vhostPort": "Port",
|
"vhostPort": "Port",
|
||||||
|
"vhostType": "Type",
|
||||||
"view": "Aperçu",
|
"view": "Aperçu",
|
||||||
"virtualHost": "Hôte virtuel",
|
"virtualHost": "Hôte virtuel",
|
||||||
"virtualHostName": "Nom de l'hôte virtuel",
|
"virtualHostName": "Nom de l'hôte virtuel",
|
||||||
|
|
|
@ -307,6 +307,8 @@ site/templates/dark/password.tpl
|
||||||
site/templates/dark/redirect.tpl
|
site/templates/dark/redirect.tpl
|
||||||
site/templates/dark/register.tpl
|
site/templates/dark/register.tpl
|
||||||
site/templates/dark/standardform.tpl
|
site/templates/dark/standardform.tpl
|
||||||
|
site/templates/dark/u2fcheck.tpl
|
||||||
|
site/templates/dark/u2fregister.tpl
|
||||||
site/templates/dark/yubikeyform.tpl
|
site/templates/dark/yubikeyform.tpl
|
||||||
site/templates/impact/authmessage.tpl
|
site/templates/impact/authmessage.tpl
|
||||||
site/templates/impact/confirm.tpl
|
site/templates/impact/confirm.tpl
|
||||||
|
@ -327,6 +329,8 @@ site/templates/impact/password.tpl
|
||||||
site/templates/impact/redirect.tpl
|
site/templates/impact/redirect.tpl
|
||||||
site/templates/impact/register.tpl
|
site/templates/impact/register.tpl
|
||||||
site/templates/impact/standardform.tpl
|
site/templates/impact/standardform.tpl
|
||||||
|
site/templates/impact/u2fcheck.tpl
|
||||||
|
site/templates/impact/u2fregister.tpl
|
||||||
site/templates/impact/yubikeyform.tpl
|
site/templates/impact/yubikeyform.tpl
|
||||||
site/templates/pastel/confirm.tpl
|
site/templates/pastel/confirm.tpl
|
||||||
site/templates/pastel/customfooter.tpl
|
site/templates/pastel/customfooter.tpl
|
||||||
|
@ -346,6 +350,8 @@ site/templates/pastel/password.tpl
|
||||||
site/templates/pastel/redirect.tpl
|
site/templates/pastel/redirect.tpl
|
||||||
site/templates/pastel/register.tpl
|
site/templates/pastel/register.tpl
|
||||||
site/templates/pastel/standardform.tpl
|
site/templates/pastel/standardform.tpl
|
||||||
|
site/templates/pastel/u2fcheck.tpl
|
||||||
|
site/templates/pastel/u2fregister.tpl
|
||||||
site/templates/pastel/yubikeyform.tpl
|
site/templates/pastel/yubikeyform.tpl
|
||||||
t/01-AuthDemo.t
|
t/01-AuthDemo.t
|
||||||
t/02-Password-Demo.t
|
t/02-Password-Demo.t
|
||||||
|
|
|
@ -92,7 +92,7 @@ sub init {
|
||||||
|
|
||||||
# Purge loaded module list
|
# Purge loaded module list
|
||||||
$self->loadedModules( {} );
|
$self->loadedModules( {} );
|
||||||
Lemonldap::NG::Handler::Main::Reload->onReload( $self, 'reloadConf' );
|
Lemonldap::NG::Handler::Main->onReload( $self, 'reloadConf' );
|
||||||
return 0 unless ( $self->SUPER::init($args) );
|
return 0 unless ( $self->SUPER::init($args) );
|
||||||
return 0 if ( $self->error );
|
return 0 if ( $self->error );
|
||||||
|
|
||||||
|
|
|
@ -418,7 +418,7 @@ sub store {
|
||||||
|
|
||||||
# Main session
|
# Main session
|
||||||
my $session =
|
my $session =
|
||||||
$self->getApacheSession( $req->{id}, force => $self->{force} );
|
$self->getApacheSession( $req->{id}, force => $req->{force} );
|
||||||
return PE_APACHESESSIONERROR unless ($session);
|
return PE_APACHESESSIONERROR unless ($session);
|
||||||
$req->id( $session->{id} );
|
$req->id( $session->{id} );
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,11 @@ SKIP: {
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple authentication on IdP
|
# Simple authentication on IdP
|
||||||
switch ('issuer');
|
switch ('issuer');
|
||||||
|
@ -168,7 +168,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ SKIP: {
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
my $res;
|
my $res;
|
||||||
|
@ -218,7 +218,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ SKIP: {
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
ok( $res = $issuer->_get('/saml/metadata'), 'Get metadata');
|
ok( $res = $issuer->_get('/saml/metadata'), 'Get metadata');
|
||||||
ok( $res->[2]->[0] =~ m#^<\?xml version="1.0"\?>#s, 'Metadata is XML');
|
ok( $res->[2]->[0] =~ m#^<\?xml version="1.0"\?>#s, 'Metadata is XML');
|
||||||
|
|
|
@ -20,11 +20,11 @@ SKIP: {
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple authentication on IdP
|
# Simple authentication on IdP
|
||||||
switch ('issuer');
|
switch ('issuer');
|
||||||
|
@ -194,7 +194,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ SKIP: {
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
my $res;
|
my $res;
|
||||||
|
@ -212,7 +212,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ SKIP: {
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple authentication on IdP
|
# Simple authentication on IdP
|
||||||
switch ('issuer');
|
switch ('issuer');
|
||||||
|
@ -174,7 +174,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ SKIP: {
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
my $res;
|
my $res;
|
||||||
|
@ -226,7 +226,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,11 @@ SKIP: {
|
||||||
*AuthCAS::get_https2 = *mygethttps2;
|
*AuthCAS::get_https2 = *mygethttps2;
|
||||||
|
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
my $res;
|
my $res;
|
||||||
|
@ -168,7 +168,7 @@ sub mygethttps2 {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
pass( '==> Switching to ' . uc($type) . ' <==' );
|
pass( '==> Switching to ' . uc($type) . ' <==' );
|
||||||
count(1);
|
count(1);
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
pass( '==> Switching to ' . uc($type) . ' <==' );
|
pass( '==> Switching to ' . uc($type) . ' <==' );
|
||||||
count(1);
|
count(1);
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
pass( '==> Switching to ' . uc($type) . ' <==' );
|
pass( '==> Switching to ' . uc($type) . ' <==' );
|
||||||
count(1);
|
count(1);
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@ SKIP: {
|
||||||
skip 'Net::OpenID::* notfound', $maintests;
|
skip 'Net::OpenID::* notfound', $maintests;
|
||||||
}
|
}
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
my $res;
|
my $res;
|
||||||
|
@ -99,7 +99,7 @@ done_testing( count() );
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,11 @@ my ( $issuer, $sp, $res, $spId, $idpId );
|
||||||
my %handlerOR = ( issuer => [], sp => [] );
|
my %handlerOR = ( issuer => [], sp => [] );
|
||||||
|
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
count(2);
|
count(2);
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
|
@ -234,7 +234,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@ SKIP: {
|
||||||
}
|
}
|
||||||
|
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
my $res;
|
my $res;
|
||||||
|
@ -138,7 +138,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,11 @@ my ( $issuer, $sp, $res, $spId );
|
||||||
my %handlerOR = ( issuer => [], sp => [] );
|
my %handlerOR = ( issuer => [], sp => [] );
|
||||||
|
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
count(2);
|
count(2);
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
|
@ -147,7 +147,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@ SKIP: {
|
||||||
}
|
}
|
||||||
|
|
||||||
ok( $issuer = issuer(), 'Issuer portal' );
|
ok( $issuer = issuer(), 'Issuer portal' );
|
||||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
switch ('sp');
|
switch ('sp');
|
||||||
|
|
||||||
ok( $sp = sp(), 'SP portal' );
|
ok( $sp = sp(), 'SP portal' );
|
||||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::_onReload;
|
||||||
|
|
||||||
# Simple SP access
|
# Simple SP access
|
||||||
my $res;
|
my $res;
|
||||||
|
@ -120,7 +120,7 @@ sub LWP::UserAgent::request {
|
||||||
|
|
||||||
sub switch {
|
sub switch {
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
@Lemonldap::NG::Handler::Main::_onReload = @{
|
||||||
$handlerOR{$type};
|
$handlerOR{$type};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user