Some big changes (#595)

Replace uri_escape by WWW::Form::UrlEncoded
Replace PSGI:Request by inheritance from Plack::Request
This commit is contained in:
Xavier Guimard 2017-01-04 16:36:54 +00:00
parent 3146feeb3e
commit a09d12031e
35 changed files with 223 additions and 316 deletions

View File

@ -125,8 +125,8 @@ sub sendError {
# SOAP responses # SOAP responses
if ( if (
$req->accept =~ m#(?:application|text)/xml# $req->accept =~ m#(?:application|text)/xml#
or ( $req->contentType or ( $req->content_type
and $req->contentType =~ m#(?:application|text)/xml# ) and $req->content_type =~ m#(?:application|text)/xml# )
) )
{ {
my $s = '<soapenv:Body> my $s = '<soapenv:Body>
@ -235,7 +235,7 @@ sub sendHtml {
my $sp = $self->staticPrefix; my $sp = $self->staticPrefix;
$sp =~ s/\/*$/\//; $sp =~ s/\/*$/\//;
$htpl->param( $htpl->param(
SCRIPT_NAME => $req->scriptname, SCRIPT_NAME => $req->script_name,
STATIC_PREFIX => $sp, STATIC_PREFIX => $sp,
AVAILABLE_LANGUAGES => $self->languages, AVAILABLE_LANGUAGES => $self->languages,
PORTAL => $self->portal, PORTAL => $self->portal,

View File

@ -3,10 +3,13 @@ package Lemonldap::NG::Common::PSGI::Request;
use strict; use strict;
use Mouse; use Mouse;
use JSON; use JSON;
use Plack::Request;
use URI::Escape; use URI::Escape;
our $VERSION = '2.0.0'; our $VERSION = '2.0.0';
our @ISA = ('Plack::Request');
# http :// server / path ? query # fragment # http :// server / path ? query # fragment
# m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|; # m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;
@ -17,125 +20,78 @@ sub BUILD {
} }
} }
has HTTP_ACCEPT => ( is => 'ro', reader => 'accept' ); sub new {
has HTTP_ACCEPT_ENCODING => ( is => 'ro', reader => 'encodings' ); my $self = Plack::Request::new(@_);
has HTTP_ACCEPT_LANGUAGE => ( is => 'ro', reader => 'languages' ); my $tmp = $self->script_name;
has HTTP_AUTHORIZATION => ( is => 'ro', reader => 'authorization' ); $self->env->{REQUEST_URI} = $self->env->{X_ORIGINAL_URI}
has HTTP_COOKIE => ( is => 'ro', reader => 'cookies' ); if ( $self->env->{X_ORIGINAL_URI} );
has HTTP_HOST => ( is => 'ro', reader => 'hostname' ); $self->env->{PATH_INFO} =~ s|^$tmp|/|;
has REFERER => ( is => 'ro', reader => 'referer' ); $self->env->{PATH_INFO} =~ s|//+|/|g;
has REMOTE_ADDR => ( is => 'ro', isa => 'Str', reader => 'remote_ip' ); $self->{uri} = uri_unescape( $self->env->{REQUEST_URI} );
has REMOTE_PORT => ( is => 'ro', isa => 'Int', reader => 'port' ); $self->{uri} =~ s|//+|/|g;
has REQUEST_METHOD => ( is => 'ro', isa => 'Str', reader => 'method' ); $self->{error} = 0;
has SCRIPT_NAME => ( is => 'ro', isa => 'Str', reader => 'scriptname' ); $self->{respHeaders} = [];
has SERVER_PORT => ( is => 'ro', isa => 'Int', reader => 'get_server_port' ); return $self;
has X_ORIGINAL_URI => ( is => 'ro', isa => 'Str' );
has PATH_INFO => (
is => 'ro',
reader => 'path',
lazy => 1,
default => '',
trigger => sub {
my $tmp = $_[0]->{SCRIPT_NAME};
$_[0]->{PATH_INFO} =~ s|^$tmp|/|;
$_[0]->{PATH_INFO} =~ s|//+|/|g;
},
);
has REQUEST_URI => (
is => 'ro',
reader => 'uri',
lazy => 1,
default => '/',
trigger => sub {
my $uri = $_[0]->{X_ORIGINAL_URI} || $_[0]->{REQUEST_URI};
$_[0]->{unparsed_uri} = $uri;
$_[0]->{REQUEST_URI} = uri_unescape($uri);
$_[0]->{REQUEST_URI} =~ s|//+|/|g;
},
);
has unparsed_uri => ( is => 'rw', isa => 'Str' );
has 'psgi.errors' => ( is => 'rw', reader => 'stderr' );
# Authentication
has REMOTE_USER => (
is => 'rw',
reader => 'user',
trigger => sub {
$_[0]->{userData} = { $Lemonldap::NG::Handler::Main::tsv->{whatTotrace}
|| _whatToTrace => $_[0]->{REMOTE_USER}, };
},
);
has userData => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
# Query parameters
has _params => ( is => 'rw', isa => 'HashRef', default => sub { {} } );
has QUERY_STRING => (
is => 'ro',
reader => 'query',
trigger => sub {
my $self = shift;
$self->_urlcode2params( $self->{QUERY_STRING} );
},
);
sub _urlcode2params {
my ( $self, $str ) = @_;
my @tmp = $str ? map { uri_unescape($_) } split( /&/, $str ) : ();
foreach my $s (@tmp) {
if ( $s =~ /^(.+?)=(.+)$/ ) { $self->{_params}->{$1} = $2; }
else { $self->{_params}->{$s} = 1; }
}
} }
*param = *params; sub uri { $_[0]->{uri} }
sub params { sub userData {
my ( $self, $key, $value ) = @_; my($self,$v)=@_;
return $self->_params unless ($key); return $_[0]->{userData} = $v if($v);
$self->_params->{$key} = $value if ( defined $value ); return $_[0]->{userData} || { _whatToTrace => $_[0]->user, };
return $self->_params->{$key};
} }
# POST management sub respHeaders {
# my ( $self, $respHeaders ) = @_;
# When CONTENT_LENGTH is set, store body in memory in `body` key $self->{respHeaders} = $respHeaders if ($respHeaders);
has 'psgix.input.buffered' => ( is => 'ro', reader => '_psgixBuffered', ); return $self->{respHeaders};
has 'psgi.input' => ( is => 'ro', reader => '_psgiInput', ); }
has body => ( is => 'rw', isa => 'Str', default => '' );
has CONTENT_TYPE => ( is => 'ro', isa => 'Str', reader => 'contentType', ); sub accept { $_[0]->env->{HTTP_ACCEPT} }
has CONTENT_LENGTH => ( sub encodings { $_[0]->env->{HTTP_ACCEPT_ENCODING} }
is => 'ro', sub languages { $_[0]->env->{HTTP_ACCEPT_LANGUAGE} }
reader => 'contentLength', sub authorization { $_[0]->env->{HTTP_AUTHORIZATION} }
lazy => 1, sub hostname { $_[0]->env->{HTTP_HOST} }
default => 0, sub referer { $_[0]->env->{REFERER} }
trigger => sub {
my $self = shift; sub error {
if ( $self->method eq 'GET' ) { $self->{body} = undef; } my ( $self, $err ) = @_;
elsif ( $self->method =~ /^(?:POST|PUT)$/ ) { $self->{error} = $err if ($err);
$self->{body} = ''; return $self->{error};
if ( $self->_psgixBuffered ) { }
my $length = $self->{CONTENT_LENGTH};
while ( $length > 0 ) { sub read_body {
my $buffer; my $self = shift;
$self->_psgiInput->read( $buffer, if ( $self->method eq 'GET' ) { return undef; }
( $length < 8192 ) ? $length : 8192 ); elsif ( $self->method =~ /^(?:POST|PUT)$/ ) {
$length -= length($buffer); my $body = '';
$self->{body} .= $buffer; if ( $self->env->{'_psgix.buffered'} ) {
} my $length = $self->content_length;
while ( $length > 0 ) {
my $buffer;
$self->body->read( $buffer,
( $length < 8192 ) ? $length : 8192 );
$length -= length($buffer);
$body .= $buffer;
} }
else {
$self->_psgiInput->read( $self->{body},
$self->{CONTENT_LENGTH}, 0 );
}
utf8::upgrade( $self->{body} );
} }
else {
$self->body->read( $body, $self->content_length, 0 );
}
utf8::upgrade($body);
return $body;
} }
); }
has error => ( is => 'rw', isa => 'Str', default => '' );
has respHeaders => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } ); *params = \&Plack::Request::param;
sub set_param {
my ( $self, $k, $v ) = @_;
$self->param;
$self->env->{'plack.request.merged'}->{$k} =
$self->env->{'plack.request.query'}->{$k} = $v;
}
sub wantJSON { sub wantJSON {
return 1 return 1
@ -147,7 +103,8 @@ sub wantJSON {
# JSON parser # JSON parser
sub jsonBodyToObj { sub jsonBodyToObj {
my $self = shift; my $self = shift;
unless ( $self->contentType =~ /application\/json/ ) { return $self->{json_body} if ( $self->{json_body} );
unless ( $self->content_type =~ /application\/json/ ) {
$self->error('Data is not JSON'); $self->error('Data is not JSON');
return undef; return undef;
} }
@ -155,24 +112,12 @@ sub jsonBodyToObj {
$self->error('No data'); $self->error('No data');
return undef; return undef;
} }
return $self->body if ( ref( $self->body ) ); my $j = eval { from_json( $self->read_body ) };
my $j = eval { from_json( $self->body ) };
if ($@) { if ($@) {
$self->error("$@$!"); $self->error("$@$!");
return undef; return undef;
} }
return $self->{body} = $j; return $self->{json_body} = $j;
}
sub parseBody {
my $self = shift;
if ( $self->contentType =~ /application\/json/ ) {
%{ $self->_params } =
( %{ $self->_params }, %{ $self->jsonBodyToObj } );
}
elsif ( $self->contentType =~ /^application\/x-www-form-urlencoded/ ) {
$self->_urlcode2params( $self->body );
}
} }
1; 1;
@ -244,10 +189,6 @@ Client TCP port.
HTTP method asked by client (GET/POST/PUT/DELETE). HTTP method asked by client (GET/POST/PUT/DELETE).
=head3 scriptname
SCRIPT_NAME environment variable provided by HTTP server.
=head3 get_server_port =head3 get_server_port
Server port. Server port.

View File

@ -118,8 +118,9 @@ sub handler {
if ( !@path and $self->defaultRoute ) { if ( !@path and $self->defaultRoute ) {
@path = ( $self->defaultRoute ); @path = ( $self->defaultRoute );
} }
my $res = $self->followPath( $req, $self->routes->{ $req->method }, \@path ); my $res =
return $res ? $res : $self->sendError($req,'Bad request',400); $self->followPath( $req, $self->routes->{ $req->method }, \@path );
return $res ? $res : $self->sendError( $req, 'Bad request', 400 );
} }
sub followPath { sub followPath {
@ -130,12 +131,12 @@ sub followPath {
return $routes->{$w}->( $self, $req, @$path ); return $routes->{$w}->( $self, $req, @$path );
} }
my $res = $self->followPath( $req, $routes->{$w}, $path ); my $res = $self->followPath( $req, $routes->{$w}, $path );
return $res if($res); return $res if ($res);
unshift @$path, $w; unshift @$path, $w;
} }
if ( $routes->{':'} ) { if ( $routes->{':'} ) {
my $v = shift @$path; my $v = shift @$path;
$req->params->{ $routes->{'#'} } = $v; $req->set_param($routes->{'#'}, $v);
if ( ref( $routes->{':'} ) eq 'CODE' ) { if ( ref( $routes->{':'} ) eq 'CODE' ) {
return $routes->{':'}->( $self, $req, @$path ); return $routes->{':'}->( $self, $req, @$path );
} }

View File

@ -33,6 +33,7 @@ sub build_jail {
my @t = my @t =
$self->customFunctions ? split( /\s+/, $self->customFunctions ) : (); $self->customFunctions ? split( /\s+/, $self->customFunctions ) : ();
foreach (@t) { foreach (@t) {
no warnings 'redefine';
$api->lmLog( "Custom function : $_", 'debug' ); $api->lmLog( "Custom function : $_", 'debug' );
my $sub = $_; my $sub = $_;
unless (/::/) { unless (/::/) {

View File

@ -66,7 +66,7 @@ sub handler {
my $hdrs = $req->{respHeaders}; my $hdrs = $req->{respHeaders};
$req->{respHeaders} = []; $req->{respHeaders} = [];
my @convertedHdrs = my @convertedHdrs =
( 'Content-Length' => 0, Cookie => ( $req->cookies // '' ) ); ( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) );
my $i = 0; my $i = 0;
while ( my $k = shift @$hdrs ) { while ( my $k = shift @$hdrs ) {
my $v = shift @$hdrs; my $v = shift @$hdrs;

View File

@ -62,7 +62,7 @@ sub set_user {
sub header_in { sub header_in {
my ( $class, $header ) = @_; my ( $class, $header ) = @_;
$header ||= $class; # to use header_in as a method or as a function $header ||= $class; # to use header_in as a method or as a function
return $request->{ cgiName($header) }; return $request->env->{ cgiName($header) };
} }
## @method void set_header_in(hash headers) ## @method void set_header_in(hash headers)
@ -71,7 +71,7 @@ sub header_in {
sub set_header_in { sub set_header_in {
my ( $class, %headers ) = @_; my ( $class, %headers ) = @_;
while ( my ( $h, $v ) = each %headers ) { while ( my ( $h, $v ) = each %headers ) {
$request->{ cgiName($h) } = $v; $request->env->{ cgiName($h) } = $v;
} }
} }
@ -81,7 +81,7 @@ sub set_header_in {
sub unset_header_in { sub unset_header_in {
my ( $class, @headers ) = @_; my ( $class, @headers ) = @_;
foreach my $h (@headers) { foreach my $h (@headers) {
delete $request->{ cgiName($h) }; delete $request->env->{ cgiName($h) };
} }
} }
@ -108,7 +108,7 @@ sub hostname {
# returns client IP address # returns client IP address
# @return IP_Addr string client IP # @return IP_Addr string client IP
sub remote_ip { sub remote_ip {
return $request->remote_ip; return $request->address;
} }
## @method boolean is_initial_req ## @method boolean is_initial_req
@ -122,7 +122,7 @@ sub is_initial_req {
# gets the query string # gets the query string
# @return args string Query string # @return args string Query string
sub args { sub args {
return $request->query; return $request->query_string;
} }
## @method string uri ## @method string uri
@ -140,21 +140,21 @@ sub uri {
# returns the URI, with arguments and with path portion normalized # returns the URI, with arguments and with path portion normalized
# @return URI with normalized path portion # @return URI with normalized path portion
sub uri_with_args { sub uri_with_args {
return $request->uri; return $request->request_uri;
} }
## @method string unparsed_uri ## @method string unparsed_uri
# returns the full original request URI, with arguments # returns the full original request URI, with arguments
# @return full original request URI, with arguments # @return full original request URI, with arguments
sub unparsed_uri { sub unparsed_uri {
return $request->unparsed_uri; return $request->request_uri;
} }
## @method string get_server_port ## @method string get_server_port
# returns the port the server is receiving the current request on # returns the port the server is receiving the current request on
# @return port string server port # @return port string server port
sub get_server_port { sub get_server_port {
return $request->get_server_port; return $request->port;
} }
## @method string method ## @method string method

View File

@ -61,6 +61,7 @@ sub _run {
$self->lmLog( $self->lmLog(
"User not authenticated, Try in use, cancel redirection", "User not authenticated, Try in use, cancel redirection",
'debug' ); 'debug' );
$req->userData( {} );
$req->respHeaders( [] ); $req->respHeaders( [] );
$self->routes( $self->unAuthRoutes ); $self->routes( $self->unAuthRoutes );
} }

View File

@ -69,8 +69,8 @@ clean();
sub Lemonldap::NG::Handler::PSGI::handler { sub Lemonldap::NG::Handler::PSGI::handler {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
ok( $req->{HTTP_AUTH_USER} eq 'dwho', 'Header is given to app' ) ok( $req->env->{HTTP_AUTH_USER} eq 'dwho', 'Header is given to app' )
or explain( $req->{HTTP_REMOTE_USER}, 'dwho' ); or explain( $req->env->{HTTP_AUTH_USER}, 'dwho' );
count(1); count(1);
return [ 200, [ 'Content-Type', 'text/plain' ], ['Hello'] ]; return [ 200, [ 'Content-Type', 'text/plain' ], ['Hello'] ];
} }

View File

@ -42,7 +42,7 @@ count(2);
# Check headers # Check headers
%h = @{ $res->[1] }; %h = @{ $res->[1] };
ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' ) ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
or explain( $h, 'Auth-User => "dwho"' ); or explain( \%h, 'Auth-User => "dwho"' );
count(1); count(1);
# Denied query # Denied query

View File

@ -10,6 +10,8 @@ our $client;
our $count = 1; our $count = 1;
$Data::Dumper::Deparse = 1; $Data::Dumper::Deparse = 1;
no warnings 'redefine';
my $module; my $module;
our $sessionId = our $sessionId =
'f5eec18ebb9bc96352595e2d8ce962e8ecf7af7c9a98cb9a43f9cd181cf4b545'; 'f5eec18ebb9bc96352595e2d8ce962e8ecf7af7c9a98cb9a43f9cd181cf4b545';
@ -84,7 +86,7 @@ has app => (
return $module->run( return $module->run(
{ {
configStorage => { type => 'File', dirName => 't' }, configStorage => { type => 'File', dirName => 't' },
logLevel => 'warn', logLevel => 'error',
cookieName => 'lemonldap', cookieName => 'lemonldap',
securedCookie => 0, securedCookie => 0,
https => 0, https => 0,

View File

@ -97,7 +97,7 @@ sub getConfKey {
# when 'latest' => replace by last cfgNum # when 'latest' => replace by last cfgNum
if ( $req->params('cfgNum') eq 'latest' ) { if ( $req->params('cfgNum') eq 'latest' ) {
my $tmp = $self->confAcc->lastCfg; my $tmp = $self->confAcc->lastCfg;
$req->params( 'cfgNum', $tmp ); $req->set_param( 'cfgNum', $tmp );
if ($Lemonldap::NG::Common::Conf::msg) { if ($Lemonldap::NG::Common::Conf::msg) {
$req->error($Lemonldap::NG::Common::Conf::msg); $req->error($Lemonldap::NG::Common::Conf::msg);
return undef; return undef;
@ -107,7 +107,9 @@ sub getConfKey {
$req->error("cfgNum must be a number"); $req->error("cfgNum must be a number");
return undef; return undef;
} }
unless ( defined $self->getConfByNum( $req->params('cfgNum'), @args ) ) { unless (
defined $self->getConfByNum( scalar( $req->params('cfgNum') ), @args ) )
{
$req->error( "Configuration " $req->error( "Configuration "
. $req->params('cfgNum') . $req->params('cfgNum')
. " is not available (" . " is not available ("
@ -1050,7 +1052,8 @@ sub diff {
my ( $self, $req, @path ) = @_; my ( $self, $req, @path ) = @_;
return $self->sendError( $req, 'to many arguments in path info', 400 ) return $self->sendError( $req, 'to many arguments in path info', 400 )
if (@path); if (@path);
my @cfgNum = ( $req->params('conf1'), $req->params('conf2') ); my @cfgNum =
( scalar( $req->param('conf1') ), scalar( $req->param('conf2') ) );
my @conf; my @conf;
# Load the 2 configurations # Load the 2 configurations

View File

@ -123,7 +123,7 @@ sub scanTree {
$self->newConf->{cfgAuthor} = $self->newConf->{cfgAuthor} =
$self->req->userData->{ $Lemonldap::NG::Handler::Main::tsv->{whatToTrace} $self->req->userData->{ $Lemonldap::NG::Handler::Main::tsv->{whatToTrace}
|| '_whatToTrace' } // "anonymous"; || '_whatToTrace' } // "anonymous";
$self->newConf->{cfgAuthorIP} = $self->req->remote_ip; $self->newConf->{cfgAuthorIP} = $self->req->address;
$self->newConf->{cfgDate} = time; $self->newConf->{cfgDate} = time;
$self->newConf->{key} ||= $self->newConf->{key} ||=
join( '', map { chr( int( rand(94) ) + 33 ) } ( 1 .. 16 ) ); join( '', map { chr( int( rand(94) ) + 33 ) } ( 1 .. 16 ) );

View File

@ -150,7 +150,7 @@ sub notifications {
return $self->notification( $req, $notif, $type ) if ($notif); return $self->notification( $req, $notif, $type ) if ($notif);
# Case 2: list # Case 2: list
my $params = $req->params(); my $params = $req->parameters();
my ( $notifs, $res ); my ( $notifs, $res );
$notifs = $self->notifAccess->$sub(); $notifs = $self->notifAccess->$sub();

View File

@ -83,7 +83,7 @@ sub sessions {
my $mod = $self->getMod($req) my $mod = $self->getMod($req)
or return $self->sendError( $req, undef, 400 ); or return $self->sendError( $req, undef, 400 );
my $params = $req->params(); my $params = $req->parameters();
my $type = delete $params->{sessionType}; my $type = delete $params->{sessionType};
$type = $type eq 'global' ? 'SSO' : ucfirst($type); $type = $type eq 'global' ? 'SSO' : ucfirst($type);
@ -164,7 +164,7 @@ sub sessions {
my $total = ( keys %$res ); my $total = ( keys %$res );
# 2.4 Special case doubleIp (users connected from more than 1 IP) # 2.4 Special case doubleIp (users connected from more than 1 IP)
if ( $params->{doubleIp} ) { if ( defined $params->{doubleIp} ) {
my %r; my %r;
# 2.4.1 Store user IP addresses in %r # 2.4.1 Store user IP addresses in %r

View File

@ -300,6 +300,7 @@
"logout": "Logout", "logout": "Logout",
"logoutServices": "Logout forward", "logoutServices": "Logout forward",
"logParams": "Logs", "logParams": "Logs",
"lwpSslOpts": "SSL options for server requests",
"macros": "Macros", "macros": "Macros",
"mailBody": "Success mail content", "mailBody": "Success mail content",
"mailCharset": "Charset", "mailCharset": "Charset",
@ -350,6 +351,7 @@
"newRule": "New rule", "newRule": "New rule",
"newValue": "New value", "newValue": "New value",
"next": "Next", "next": "Next",
"nginxCustomHandlers": "Custom Nginx handlers",
"noAjaxHook": "Keep redirections for Ajax", "noAjaxHook": "Keep redirections for Ajax",
"noDatas": "No datas to display", "noDatas": "No datas to display",
"notABoolean": "Not a boolean", "notABoolean": "Not a boolean",

View File

@ -300,6 +300,7 @@
"logout": "Déconnexion", "logout": "Déconnexion",
"logoutServices": "Transfert de la déconnexion", "logoutServices": "Transfert de la déconnexion",
"logParams": "Journalisation", "logParams": "Journalisation",
"lwpSslOpts": "Options SSL pour les requêtes serveur",
"macros": "Macros", "macros": "Macros",
"mailBody": "Contenu du message de succès", "mailBody": "Contenu du message de succès",
"mailCharset": "Charset", "mailCharset": "Charset",
@ -350,6 +351,7 @@
"newRule": "Nouvelle règle", "newRule": "Nouvelle règle",
"newValue": "Nouvelle valeur", "newValue": "Nouvelle valeur",
"next": "Suivante", "next": "Suivante",
"nginxCustomHandlers": "Handlers Nginx personnalisés",
"noAjaxHook": "Conserver les redirections pour Ajax", "noAjaxHook": "Conserver les redirections pour Ajax",
"noDatas": "Aucune donnée à afficher", "noDatas": "Aucune donnée à afficher",
"notABoolean": "Pas un booléen", "notABoolean": "Pas un booléen",

View File

@ -18,7 +18,7 @@ sub init {
sub extractFormInfo { sub extractFormInfo {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
unless ( $req->{user} = $req->{REMOTE_USER} ) { unless ( $req->{user} = $req->env->{REMOTE_USER} ) {
$self->lmLog( 'Apache is not configured to authenticate users!', $self->lmLog( 'Apache is not configured to authenticate users!',
'error' ); 'error' );
return PE_ERROR; return PE_ERROR;

View File

@ -81,7 +81,7 @@ sub extractFormInfo {
# if we are receving SAML request or response # if we are receving SAML request or response
my $url = $req->uri; my $url = $req->uri;
my $request_method = $req->method; my $request_method = $req->method;
my $content_type = $req->contentType; my $content_type = $req->content_type;
# 1.1 SSO assertion consumer # 1.1 SSO assertion consumer
if ( $url =~ $self->sloAssConsumerRe ) { if ( $url =~ $self->sloAssConsumerRe ) {
@ -774,7 +774,7 @@ sub extractFormInfo {
'debug' ); 'debug' );
# Artifact request are sent with SOAP trough POST # Artifact request are sent with SOAP trough POST
my $art_request = $req->body; my $art_request = $req->read_body;
my $art_response; my $art_response;
# Create Login object # Create Login object
@ -874,11 +874,12 @@ sub extractFormInfo {
. "<p><i>" . "<p><i>"
. $idp . $idp
. "</i></p>\n" . "</i></p>\n"
. ( $req->param("url") . (
$req->param("url")
? "<input type=\"hidden\" name=\"url\" value=\"" ? "<input type=\"hidden\" name=\"url\" value=\""
. $req->param("url") . "\" />" . $req->param("url") . "\" />"
: '' ) : ''
. "<input type=\"hidden\" name=\"idp\" value=\"$idp\" />\n"; ) . "<input type=\"hidden\" name=\"idp\" value=\"$idp\" />\n";
$self->p->info( $req, $html ); $self->p->info( $req, $html );
@ -1420,12 +1421,7 @@ sub getIDP {
my $idp; my $idp;
my $idpName; my $idpName;
my $idp_cookie; my $idp_cookie = $req->cookies->{ $self->{conf}->{samlIdPResolveCookie} };
if ( $req->cookies
&& $req->cookies =~ /$self->{conf}->{samlIdPResolveCookie}=([^,; ]+)/o )
{
$idp_cookie = $1;
}
# Case 1: Recover IDP from idp URL Parameter # Case 1: Recover IDP from idp URL Parameter
unless ( $idp = $req->param("idp") ) { unless ( $idp = $req->param("idp") ) {

View File

@ -25,7 +25,7 @@ sub init {
sub extractFormInfo { sub extractFormInfo {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
return PE_OK return PE_OK
if ( $req->user( $req->{ $self->SSLField } ) ); if ( $req->user( $req->env->{ $self->SSLField } ) );
if ( $req->{SSL_CLIENT_S_DN} ) { if ( $req->{SSL_CLIENT_S_DN} ) {
$self->p->userError( $self->p->userError(
"$self->SSLField was not found in user certificate"); "$self->SSLField was not found in user certificate");

View File

@ -27,7 +27,7 @@ sub extractFormInfo {
$user_header = 'HTTP_' . uc($user_header); $user_header = 'HTTP_' . uc($user_header);
$user_header =~ s/\-/_/g; $user_header =~ s/\-/_/g;
unless ( $req->{user} = $req->{$user_header} ) { unless ( $req->{user} = $req->env->{$user_header} ) {
$self->lmLog( "No header " . $self->conf->{slaveUserHeader} . " found", $self->lmLog( "No header " . $self->conf->{slaveUserHeader} . " found",
'error' ); 'error' );
return PE_USERNOTFOUND; return PE_USERNOTFOUND;

View File

@ -875,7 +875,6 @@ qq'<h3 trspan="oidcConsent,$display_name">The application $display_name would li
# Handle token endpoint # Handle token endpoint
sub token { sub token {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$req->parseBody if ( $req->method =~ /^post$/i );
$self->lmLog( "URL detected as an OpenID Connect TOKEN URL", 'debug' ); $self->lmLog( "URL detected as an OpenID Connect TOKEN URL", 'debug' );
# Check authentication # Check authentication
@ -1034,7 +1033,6 @@ sub token {
sub userInfo { sub userInfo {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$self->lmLog( "URL detected as an OpenID Connect USERINFO URL", 'debug' ); $self->lmLog( "URL detected as an OpenID Connect USERINFO URL", 'debug' );
$req->parseBody if ( $req->method =~ /^post$/i );
my $access_token = $self->getEndPointAccessToken($req); my $access_token = $self->getEndPointAccessToken($req);
@ -1091,7 +1089,6 @@ sub userInfo {
sub jwks { sub jwks {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$self->lmLog( "URL detected as an OpenID Connect JWKS URL", 'debug' ); $self->lmLog( "URL detected as an OpenID Connect JWKS URL", 'debug' );
$req->parseBody if ( $req->method =~ /^post$/i );
my $jwks = { keys => [] }; my $jwks = { keys => [] };
@ -1117,7 +1114,7 @@ sub registration {
# TODO: check Initial Access Token # TODO: check Initial Access Token
# Specific message to allow DOS detection # Specific message to allow DOS detection
my $source_ip = $req->remote_ip; my $source_ip = $req->address;
$self->lmLog( "OpenID Connect Registration request from $source_ip", $self->lmLog( "OpenID Connect Registration request from $source_ip",
'warn' ); 'warn' );
@ -1128,7 +1125,7 @@ sub registration {
} }
# Get client metadata # Get client metadata
my $client_metadata_json = $req->body; my $client_metadata_json = $req->read_body;
unless ($client_metadata_json) { unless ($client_metadata_json) {
return $self->p->sendError( $req, 'Missing POST datas', 400 ); return $self->p->sendError( $req, 'Missing POST datas', 400 );
} }
@ -1221,7 +1218,6 @@ sub endSessionDone {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$self->lmLog( "URL detected as an OpenID Connect END SESSION URL", $self->lmLog( "URL detected as an OpenID Connect END SESSION URL",
'debug' ); 'debug' );
$req->parseBody if ( $req->method =~ /^post$/i );
$self->lmLog( "User is already logged out", 'debug' ); $self->lmLog( "User is already logged out", 'debug' );
my $post_logout_redirect_uri = $req->param('post_logout_redirect_uri'); my $post_logout_redirect_uri = $req->param('post_logout_redirect_uri');
@ -1246,7 +1242,6 @@ sub checkSession {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$self->lmLog( "URL detected as an OpenID Connect CHECK SESSION URL", $self->lmLog( "URL detected as an OpenID Connect CHECK SESSION URL",
'debug' ); 'debug' );
$req->parseBody if ( $req->method =~ /^post$/i );
my $portalPath = $self->conf->{portal}; my $portalPath = $self->conf->{portal};
$portalPath =~ s#^https?://[^/]+/?#/#; $portalPath =~ s#^https?://[^/]+/?#/#;

View File

@ -147,7 +147,7 @@ sub run {
# if we are receving SAML request or response # if we are receving SAML request or response
my $url = $req->uri; my $url = $req->uri;
my $request_method = $req->param('issuerMethod') || $req->method; my $request_method = $req->param('issuerMethod') || $req->method;
my $content_type = $req->contentType(); my $content_type = $req->content_type();
my $idp_initiated = $req->param('IDPInitiated'); my $idp_initiated = $req->param('IDPInitiated');
my $idp_initiated_sp = $req->param('sp'); my $idp_initiated_sp = $req->param('sp');
my $idp_initiated_spConfKey = $req->param('spConfKey'); my $idp_initiated_spConfKey = $req->param('spConfKey');
@ -981,7 +981,7 @@ sub artifactServer {
'debug' ); 'debug' );
# Artifact request are sent with SOAP trough POST # Artifact request are sent with SOAP trough POST
my $art_request = $req->body; my $art_request = $req->read_body;
my $art_response; my $art_response;
# Create Login object # Create Login object
@ -1022,7 +1022,7 @@ sub soapSloServer {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
my $url = $req->uri; my $url = $req->uri;
my $request_method = $req->param('issuerMethod') || $req->method; my $request_method = $req->param('issuerMethod') || $req->method;
my $content_type = $req->contentType(); my $content_type = $req->content_type();
$self->lmLog( "URL $url detected as an SLO URL", 'debug' ); $self->lmLog( "URL $url detected as an SLO URL", 'debug' );
@ -1269,7 +1269,7 @@ sub logout {
# for them. # for them.
# Redirect on logout page when all is done. # Redirect on logout page when all is done.
if ( $self->sendLogoutRequestToProviders( $req, $logout ) ) { if ( $self->sendLogoutRequestToProviders( $req, $logout ) ) {
$self->{urldc} = $req->scriptname . "?logout=1"; $self->{urldc} = $req->script_name . "?logout=1";
return PE_OK; return PE_OK;
} }
@ -1401,7 +1401,7 @@ sub sloServer {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
my $url = $req->uri; my $url = $req->uri;
my $request_method = $req->param('issuerMethod') || $req->method; my $request_method = $req->param('issuerMethod') || $req->method;
my $content_type = $req->contentType(); my $content_type = $req->content_type();
$self->lmLog( "URL $url detected as an SLO URL", 'debug' ); $self->lmLog( "URL $url detected as an SLO URL", 'debug' );
# Check SAML Message # Check SAML Message
@ -1616,7 +1616,7 @@ sub attributeServer {
$self->lmLog( "URL $url detected as an attribute service URL", 'debug' ); $self->lmLog( "URL $url detected as an attribute service URL", 'debug' );
# Attribute request are sent with SOAP trough POST # Attribute request are sent with SOAP trough POST
my $att_request = $req->body; my $att_request = $req->read_body;
my $att_response; my $att_response;
# Process request # Process request

View File

@ -15,9 +15,9 @@ use JSON;
use LWP::UserAgent; use LWP::UserAgent;
use MIME::Base64 qw/encode_base64 decode_base64/; use MIME::Base64 qw/encode_base64 decode_base64/;
use Mouse; use Mouse;
use URI::Escape; use WWW::Form::UrlEncoded qw/parse_urlencoded build_urlencoded/;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK); use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_REDIRECT);
our $VERSION = '2.0.0'; our $VERSION = '2.0.0';
@ -216,8 +216,8 @@ sub getCallbackUri {
# Use authChoiceParam in redirect URL # Use authChoiceParam in redirect URL
if ( $req->param( $self->conf->{authChoiceParam} ) ) { if ( $req->param( $self->conf->{authChoiceParam} ) ) {
$callback_uri .= '&' $callback_uri .= '&'
. $self->{authChoiceParam} . '=' . build_urlencoded( $self->{authChoiceParam} =>
. uri_escape( $req->param( $self->conf->{authChoiceParam} ) ); $req->param( $self->conf->{authChoiceParam} ) );
} }
$self->lmLog( "OpenIDConnect Callback URI: $callback_uri", 'debug' ); $self->lmLog( "OpenIDConnect Callback URI: $callback_uri", 'debug' );
@ -265,32 +265,23 @@ sub buildAuthorizationCodeAuthnRequest {
$nonceSession->update( { '_utime' => time } ); $nonceSession->update( { '_utime' => time } );
$nonce = $nonceSession->id; $nonce = $nonceSession->id;
} }
$client_id = uri_escape($client_id);
$scope = uri_escape($scope);
$response_type = uri_escape($response_type);
$redirect_uri = uri_escape($redirect_uri);
$state = uri_escape($state) if defined $state;
$nonce = uri_escape($nonce) if defined $nonce;
$display = uri_escape($display) if defined $display;
$prompt = uri_escape($prompt) if defined $prompt;
$max_age = uri_escape($max_age) if defined $max_age;
$ui_locales = uri_escape($ui_locales) if defined $ui_locales;
$acr_values = uri_escape($acr_values) if defined $acr_values;
my $authn_uri = my $authn_uri =
$authorize_uri $authorize_uri
. ( $authorize_uri =~ /\?/ ? '&' : '?' ) . ( $authorize_uri =~ /\?/ ? '&' : '?' )
. "response_type=$response_type" . build_urlencoded(
. "&client_id=$client_id" response_type => $response_type,
. "&scope=$scope" client_id => $client_id,
. "&redirect_uri=$redirect_uri"; scope => $scope,
$authn_uri .= "&state=$state" if defined $state; redirect_uri => $redirect_uri,
$authn_uri .= "&nonce=$nonce" if defined $nonce; ( defined $state ? ( state => $state ) : () ),
$authn_uri .= "&display=$display" if defined $display; ( defined $nonce ? ( nonce => $nonce ) : () ),
$authn_uri .= "&prompt=$prompt" if defined $prompt; ( defined $display ? ( display => $display ) : () ),
$authn_uri .= "&max_age=$max_age" if $max_age; ( defined $prompt ? ( prompt => $prompt ) : () ),
$authn_uri .= "&ui_locales=$ui_locales" if defined $ui_locales; ( $max_age ? ( max_age => $max_age ) : () ),
$authn_uri .= "&acr_values=$acr_values" if defined $acr_values; ( defined $ui_locales ? ( ui_locales => $ui_locales ) : () ),
( defined $acr_values ? ( acr_values => $acr_values ) : () )
);
$self->lmLog( $self->lmLog(
"OpenIDConnect Authorization Code Flow Authn Request: $authn_uri", "OpenIDConnect Authorization Code Flow Authn Request: $authn_uri",
@ -308,19 +299,14 @@ sub buildAuthorizationCodeAuthnRequest {
sub buildAuthorizationCodeAuthnResponse { sub buildAuthorizationCodeAuthnResponse {
my ( $self, $redirect_uri, $code, $state, $session_state ) = @_; my ( $self, $redirect_uri, $code, $state, $session_state ) = @_;
my $response_url = $redirect_uri; my $response_url =
$redirect_uri
$response_url .= ( $redirect_uri =~ /\?/ ? '&' : '?' ); . ( $redirect_uri =~ /\?/ ? '&' : '?' )
. build_urlencoded(
$response_url .= "code=" . uri_escape($code); code => $code,
( $state ? ( state => $state ) : () ),
if ($state) { ( $session_state ? ( session_state => $session_state ) : () )
$response_url .= "&state=" . uri_escape($state); );
}
if ($session_state) {
$response_url .= "&session_state=" . uri_escape($session_state);
}
return $response_url; return $response_url;
} }
@ -338,20 +324,18 @@ sub buildImplicitAuthnResponse {
$session_state ) $session_state )
= @_; = @_;
my $response_url = "$redirect_uri#id_token=" . uri_escape($id_token); my $response_url = "$redirect_uri#"
if ($access_token) { . build_urlencoded(
$response_url .= id_token => $id_token,
"&token_type=bearer&access_token=" . uri_escape($access_token); (
} $access_token
if ($expires_in) { ? ( token_type => 'bearer', access_token => $access_token )
$response_url .= "&expires_in=" . uri_escape($expires_in); : ()
} ),
if ($state) { ( $expires_in ? ( expires_in => $expires_in ) : () ),
$response_url .= "&state=" . uri_escape($state); ( $state ? ( state => $state ) : () ),
} ( $session_state ? ( session_state => $session_state ) : () )
if ($session_state) { );
$response_url .= "&session_state=" . uri_escape($session_state);
}
return $response_url; return $response_url;
} }
@ -370,23 +354,18 @@ sub buildHybridAuthnResponse {
$id_token, $expires_in, $state, $session_state $id_token, $expires_in, $state, $session_state
) = @_; ) = @_;
my $response_url = "$redirect_uri#code=" . uri_escape($code); my $response_url = "$redirect_uri#"
if ($access_token) { . build_urlencoded(
$response_url .= code => $code,
"&token_type=bearer&access_token=" . uri_escape($access_token); (
} $access_token
if ($id_token) { ? ( token_type => 'bearer', access_token => $access_token )
$response_url .= "&id_token=" . uri_escape($id_token); : ()
} ),
if ($expires_in) { ( $expires_in ? ( expires_in => $expires_in ) : () ),
$response_url .= "&expires_in=" . uri_escape($expires_in); ( $state ? ( state => $state ) : () ),
} ( $session_state ? ( session_state => $session_state ) : () )
if ($state) { );
$response_url .= "&state=" . uri_escape($state);
}
if ($session_state) {
$response_url .= "&session_state=" . uri_escape($session_state);
}
return $response_url; return $response_url;
} }
@ -1025,18 +1004,18 @@ sub returnRedirectError {
my $urldc = my $urldc =
$redirect_url $redirect_url
. ( $fragment ? '#' : $redirect_url =~ /\?/ ? '&' : '?' ) . ( $fragment ? '#' : $redirect_url =~ /\?/ ? '&' : '?' )
. "error=" . build_urlencoded(
. uri_escape($error); error => $error,
$urldc .= "&error_description=" . uri_escape($error_description) (
if defined $error_description; defined $error_description
$urldc .= "&error_uri=" . uri_escape($error_uri) if defined $error_uri; ? ( error_description => $error_description )
$urldc .= "&state=" . uri_escape($state) if defined $state; : ()
),
$self->lmLog( "Redirect user to $urldc", 'debug' ); ( defined $error_uri ? ( error_uri => $error_uri ) : () ),
( defined $state ? ( state => $state ) : () )
);
$req->urldc($urldc); $req->urldc($urldc);
return PE_REDIRECT;
$req->steps( [] );
return PE_OK;
} }
#sub returnJSONStatus { #sub returnJSONStatus {
@ -1331,11 +1310,12 @@ sub buildLogoutRequest {
my @tab = (qw(id_token_hint post_logout_redirect_uri state)); my @tab = (qw(id_token_hint post_logout_redirect_uri state));
my @prms; my @prms;
for ( my $i = 0 ; $i < 3 ; $i++ ) { for ( my $i = 0 ; $i < 3 ; $i++ ) {
push @prms, "$tab[$i]=" . uri_escape( $args[$i] ) push @prms, $tab[$i], $args[$i]
if defined( $args[$i] ); if defined( $args[$i] );
} }
my $response_url = $redirect_uri; my $response_url = $redirect_uri;
$response_url .= ( $response_url =~ /\?/ ? '&' : '?' ) . join( '&', @prms ) $response_url .=
( $response_url =~ /\?/ ? '&' : '?' ) . build_urlencoded(@prms)
if (@prms); if (@prms);
return $response_url; return $response_url;
} }
@ -1351,7 +1331,7 @@ sub buildLogoutResponse {
if ($state) { if ($state) {
$response_url .= ( $redirect_uri =~ /\?/ ? '&' : '?' ); $response_url .= ( $redirect_uri =~ /\?/ ? '&' : '?' );
$response_url .= "state=" . uri_escape($state); $response_url .= build_urlencoded( state => $state );
} }
return $response_url; return $response_url;

View File

@ -76,7 +76,9 @@ sub goToPortal {
$req->urldc( $req->urldc(
$self->conf->{remotePortal} . "?url=" $self->conf->{remotePortal} . "?url="
. encode_base64( . encode_base64(
$self->conf->{portal} . ( $req->query ? "?$req->query" : '' ), '' $self->conf->{portal}
. ( $req->query_string ? '?' . $req->query_string : '' ),
''
) )
); );
return PE_REDIRECT; return PE_REDIRECT;

View File

@ -411,7 +411,6 @@ sub checkMessage {
# 2.2.1. POST # 2.2.1. POST
if ( $content_type !~ /xml/ ) { if ( $content_type !~ /xml/ ) {
$req->parseBody unless ( %{ $req->params } );
$method = Lasso::Constants::HTTP_METHOD_POST; $method = Lasso::Constants::HTTP_METHOD_POST;
$self->lmLog( "SAML method: HTTP-POST", 'debug' ); $self->lmLog( "SAML method: HTTP-POST", 'debug' );
@ -462,7 +461,7 @@ sub checkMessage {
$self->lmLog( "SAML method: HTTP-SOAP", 'debug' ); $self->lmLog( "SAML method: HTTP-SOAP", 'debug' );
# SOAP is always a request # SOAP is always a request
$request = $req->body; $request = $req->read_body;
$self->lmLog( "HTTP-SOAP: SAML Request $request", 'debug' ); $self->lmLog( "HTTP-SOAP: SAML Request $request", 'debug' );
} }
@ -3023,13 +3022,13 @@ sub getQueryString {
my $query_string; my $query_string;
if ( $self->conf->{samlUseQueryStringSpecific} ) { if ( $self->conf->{samlUseQueryStringSpecific} ) {
my @pairs = split( /&/, $req->param('issuerQuery') || $req->query ); my @pairs = split( /&/, $req->param('issuerQuery') || $req->query_string );
$query_string = join( ';', @pairs ); $query_string = join( ';', @pairs );
} }
else { else {
# TODO: verify this # TODO: verify this
$query_string = $req->param('issuerQuery') || $req->query; $query_string = $req->param('issuerQuery') || $req->query_string;
} }
return $query_string; return $query_string;

View File

@ -18,7 +18,7 @@ our $VERSION = '2.0.0';
# @return true if remote IP is accredited in LL::NG conf # @return true if remote IP is accredited in LL::NG conf
sub checkIP { sub checkIP {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
my $remoteIP = $req->remote_ip; my $remoteIP = $req->address;
return 1 return 1
if (!$self->conf->{slaveMasterIP} if (!$self->conf->{slaveMasterIP}
|| $self->conf->{slaveMasterIP} =~ /\b$remoteIP\b/ ); || $self->conf->{slaveMasterIP} =~ /\b$remoteIP\b/ );

View File

@ -371,10 +371,10 @@ sub getSkin {
# Fill sessionInfo to eval rule if empty (unauthenticated user) # Fill sessionInfo to eval rule if empty (unauthenticated user)
$req->{sessionInfo}->{_url} ||= $req->{urldc}; $req->{sessionInfo}->{_url} ||= $req->{urldc};
$req->{sessionInfo}->{ipAddr} ||= $req->remote_ip; $req->{sessionInfo}->{ipAddr} ||= $req->address;
# Load specific skin from skinRules # Load specific skin from skinRules
foreach my $rule ( @{ $self->conf->skinRules } ) { foreach my $rule ( @{ $self->conf->{skinRules} } ) {
if ( $rule->[1]->( $req->sessionInfo ) ) { if ( $rule->[1]->( $req->sessionInfo ) ) {
$skin = $rule->[0]; $skin = $rule->[0];
$self->lmLog( "Skin $skin selected from skin rule", 'debug' ); $self->lmLog( "Skin $skin selected from skin rule", 'debug' );

View File

@ -37,10 +37,8 @@ sub init {
if ( my $path = $self->conf->{"issuerDB${type}Path"} ) { if ( my $path = $self->conf->{"issuerDB${type}Path"} ) {
$path =~ s/^.*?(\w+).*?$/$1/; $path =~ s/^.*?(\w+).*?$/$1/;
$self->path($path); $self->path($path);
$self->addUnauthRoute( $path => { '*' => '_redirect' }, ['GET'] ); $self->addUnauthRoute( $path => { '*' => '_redirect' }, ['GET','POST'] );
$self->addUnauthRoute( $path => { '*' => '_pRedirect' }, ['POST'] ); $self->addAuthRoute( $path => { '*' => "_forAuthUser" }, ['GET','POST'] );
$self->addAuthRoute( $path => { '*' => "_forAuthUser" }, ['GET'] );
$self->addAuthRoute( $path => { '*' => "_pForAuthUser" }, ['POST'] );
} }
else { else {
$self->lmLog( "No path declared for issuer $type. Skipping", 'debug' ); $self->lmLog( "No path declared for issuer $type. Skipping", 'debug' );
@ -54,16 +52,16 @@ sub init {
sub _redirect { sub _redirect {
my ( $self, $req, @path ) = @_; my ( $self, $req, @path ) = @_;
$self->lmLog( 'Processing _redirect', 'debug' ); $self->lmLog( 'Processing _redirect', 'debug' );
my $prms = $req->params; my $prms = $req->parameters;
foreach my $k ( keys %$prms ) { foreach my $k ( keys %$prms ) {
$self->p->setHiddenFormValue( $req, $k, $prms->{$k}, '', 0 ); $self->p->setHiddenFormValue( $req, $k, $prms->{$k}, '', 0 );
} }
$self->p->setHiddenFormValue( $req, 'issuerMethod', $req->method, '', 0 ); $self->p->setHiddenFormValue( $req, 'issuerMethod', $req->method, '', 0 );
$self->p->setHiddenFormValue( $req, 'issuerQuery', $req->query, '', 0 ); $self->p->setHiddenFormValue( $req, 'issuerQuery', $req->query_string, '', 0 );
$req->{urldc} = $req->{urldc} =
$self->conf->{portal} $self->conf->{portal}
. $req->path . $req->path
. ( $req->query ? '?' . $req->query : '' ); . ( $req->query_string ? '?' . $req->query_string : '' );
# TODO: launch normal process with 'run' at the end # TODO: launch normal process with 'run' at the end
return $self->p->do( return $self->p->do(
@ -82,13 +80,6 @@ sub _redirect {
); );
} }
sub _pRedirect {
my ( $self, $req, @path ) = @_;
$self->lmLog( '_pRedirect: parsing posted datas', 'debug' );
$req->parseBody;
return $self->_redirect( $req, @path );
}
# Case 3: authentified user, launch # Case 3: authentified user, launch
sub _forAuthUser { sub _forAuthUser {
my ( $self, $req, @path ) = @_; my ( $self, $req, @path ) = @_;
@ -106,13 +97,6 @@ sub _forAuthUser {
); );
} }
sub _pForAuthUser {
my ( $self, $req, @path ) = @_;
$self->lmLog( 'Parsing posted datas', 'debug' );
$req->parseBody;
return $self->_forAuthUser( $req, @path );
}
1; 1;
__END__ __END__

View File

@ -39,7 +39,6 @@ sub process {
# For post requests, parse datas # For post requests, parse datas
sub restoreArgs { sub restoreArgs {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$req->parseBody;
$req->mustRedirect(1); $req->mustRedirect(1);
return PE_OK; return PE_OK;
} }
@ -66,11 +65,11 @@ sub controlUrl {
my $time = time() - $self->conf->{cipher}->decrypt($2); my $time = time() - $self->conf->{cipher}->decrypt($2);
if ( $time < 600 ) { if ( $time < 600 ) {
$self->lmLog( "Confirm parameter accepted $c", 'debug' ); $self->lmLog( "Confirm parameter accepted $c", 'debug' );
$req->param( 'confirm', $c ); $req->set_param( 'confirm', $c );
} }
else { else {
$self->lmLog( 'Confirmation to old, refused', 'notice' ); $self->lmLog( 'Confirmation to old, refused', 'notice' );
$req->param( 'confirm', 0 ); $req->set_param( 'confirm', 0 );
} }
} }
} }
@ -131,7 +130,7 @@ sub controlUrl {
sub checkLogout { sub checkLogout {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
if ( $req->param('logout') ) { if ( defined $req->param('logout') ) {
$req->steps( $req->steps(
[ @{ $self->beforeLogout }, 'authLogout', 'deleteSession' ] ); [ @{ $self->beforeLogout }, 'authLogout', 'deleteSession' ] );
} }
@ -194,7 +193,7 @@ sub deleteSession {
if ( !$req->urldc and !$req->postUrl ) { if ( !$req->urldc and !$req->postUrl ) {
$self->lmLog( 'No other target defined, redirect on logout', $self->lmLog( 'No other target defined, redirect on logout',
'debug' ); 'debug' );
$req->urldc( $req->scriptname . "?logout=1" ); $req->urldc( $req->script_name . "?logout=1" );
} }
} }
@ -292,7 +291,7 @@ sub setSessionInfo {
$req->{sessionInfo}->{_userDB} = $self->getModule( $req, "user" ); $req->{sessionInfo}->{_userDB} = $self->getModule( $req, "user" );
# Store IP address from remote address or X-FORWARDED-FOR header # Store IP address from remote address or X-FORWARDED-FOR header
$req->{sessionInfo}->{ipAddr} = $req->remote_ip; $req->{sessionInfo}->{ipAddr} = $req->address;
# Date and time # Date and time
if ( $self->conf->{updateSession} ) { if ( $self->conf->{updateSession} ) {

View File

@ -14,6 +14,7 @@ our $VERSION = '2.0.0';
package Lemonldap::NG::Portal::Main; package Lemonldap::NG::Portal::Main;
use strict; use strict;
use WWW::Form::UrlEncoded 'build_urlencoded';
# List constants # List constants
sub authProcess { qw(extractFormInfo getUser authenticate) } sub authProcess { qw(extractFormInfo getUser authenticate) }
@ -480,7 +481,9 @@ sub isTrustedUrl {
sub stamp { sub stamp {
my $self = shift; my $self = shift;
return $self->conf->{cipher} ? $self->conf->{cipher}->encrypt( time() ) : 1; my $res = $self->conf->{cipher} ? $self->conf->{cipher}->encrypt( time() ) : 1;
$res =~ s/\+/%2B/g;
return $res;
} }
# Transfer POST data with auto submit # Transfer POST data with auto submit
@ -524,7 +527,7 @@ sub setHiddenFormValue {
# Store value # Store value
if ($val) { if ($val) {
$key = $prefix . $key; $key = $prefix . $key;
$val = encode_base64( $val, '' ) if $base64; $val =~ s/\+/%2B/g;
$req->{portalHiddenFormValues}->{$key} = $val; $req->{portalHiddenFormValues}->{$key} = $val;
$self->lmLog( "Store $val in hidden key $key", 'debug' ); $self->lmLog( "Store $val in hidden key $key", 'debug' );
} }

View File

@ -217,9 +217,7 @@ sub getNotifBack {
# Search for Lemonldap::NG cookie (ciphered) # Search for Lemonldap::NG cookie (ciphered)
my $id; my $id;
unless ($id = $req->cookies unless ( $id = $req->cookies->{ $self->{conf}->{cookieName} } ) {
and $id =~ s/$self->{conf}->{cookieName}=([^,; ]+)/$1/o )
{
return $self->p->sendError( $req, 'No cookie found', 401 ); return $self->p->sendError( $req, 'No cookie found', 401 );
} }
$id = $self->p->HANDLER->tsv->{cipher}->decrypt($id) $id = $self->p->HANDLER->tsv->{cipher}->decrypt($id)
@ -237,9 +235,8 @@ sub getNotifBack {
if ($notifs) { if ($notifs) {
# Get accepted notifications # Get accepted notifications
$req->parseBody;
my ( $refs, $checks ) = ( {}, {} ); my ( $refs, $checks ) = ( {}, {} );
my $prms = $req->params; my $prms = $req->parameters;
foreach ( keys %$prms ) { foreach ( keys %$prms ) {
my $v = $prms->{$_}; my $v = $prms->{$_};
if (s/^reference//) { if (s/^reference//) {

View File

@ -89,7 +89,7 @@ sub _register {
$req->datas->{registerInfo}->{mail} = $req->param('mail'); $req->datas->{registerInfo}->{mail} = $req->param('mail');
$req->datas->{registerInfo}->{firstname} = $req->param('firstname'); $req->datas->{registerInfo}->{firstname} = $req->param('firstname');
$req->datas->{registerInfo}->{lastname} = $req->param('lastname'); $req->datas->{registerInfo}->{lastname} = $req->param('lastname');
$req->datas->{registerInfo}->{ipAddr} = $req->remote_ip(); $req->datas->{registerInfo}->{ipAddr} = $req->address;
# Captcha for register form # Captcha for register form
# Only if register session does not already exist # Only if register session does not already exist

View File

@ -105,7 +105,7 @@ SKIP: {
expectOK($res); expectOK($res);
my $idpId = expectCookie($res); my $idpId = expectCookie($res);
# Post SAML artifact to SP # Post SAML response to SP
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
m#<form.+?action="http://auth.sp.com(.*?)".+?method="post"#, m#<form.+?action="http://auth.sp.com(.*?)".+?method="post"#,
@ -126,7 +126,7 @@ SKIP: {
length => length($s), length => length($s),
cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata', cookie => 'lemonldapidp=http://auth.idp.com/saml/metadata',
), ),
'Post artifact to SP' 'Post SAML response to SP'
); );
my $spId = expectCookie($res); my $spId = expectCookie($res);
expectRedirection( $res, 'http://auth.sp.com' ); expectRedirection( $res, 'http://auth.sp.com' );

View File

@ -76,13 +76,12 @@ count(1);
qr#^http://auth.rp.com/?\?openidconnectcallback=1\#(.*)$# ); qr#^http://auth.rp.com/?\?openidconnectcallback=1\#(.*)$# );
my %prms = map { split /=/, $_ } split /&/, $query; my %prms = map { split /=/, $_ } split /&/, $query;
ok( $prms{id_token}, ' id_token found' );
ok( $prms{token_type}, ' token_type found' ); ok( $prms{token_type}, ' token_type found' );
ok( $prms{session_state}, ' session_state found' ); ok( $prms{session_state}, ' session_state found' );
ok( $prms{access_token}, ' access_token found' ); ok( $prms{access_token}, ' access_token found' );
ok( $prms{state}, ' state found' ); ok( $prms{state}, ' state found' );
ok( $prms{session_state}, ' session_state found' ); ok( $prms{session_state}, ' session_state found' );
count(6); count(5);
my $at; my $at;
ok( $at = $rp->p->_userDB->getUserInfo( 'op', $prms{access_token} ), ok( $at = $rp->p->_userDB->getUserInfo( 'op', $prms{access_token} ),

View File

@ -261,11 +261,11 @@ sub logout {
main::ok( main::ok(
( defined( $c = main::getCookies($res)->{lemonldap} ) and not $c ), ( defined( $c = main::getCookies($res)->{lemonldap} ) and not $c ),
'Cookie is deleted' ) 'Cookie is deleted' )
or explain( $res->[1], "Set-Cookie => 'lemonldap='" ); or main::explain( $res->[1], "Set-Cookie => 'lemonldap='" );
main::ok( $res = $self->_get( '/', cookie => "lemonldap=$id" ), main::ok( $res = $self->_get( '/', cookie => "lemonldap=$id" ),
'Disconnect request' ) 'Disconnect request' )
or explain( $res, '[<code>,<hdrs>,<content>]' ); or explain( $res, '[<code>,<hdrs>,<content>]' );
main::ok( $res->[0] == 401, 'Response is 401' ) or explain( $res, 401 ); main::ok( $res->[0] == 401, 'Response is 401' ) or main::explain( $res, 401 );
main::count(5); main::count(5);
} }