Rearrange Nginx files
This commit is contained in:
parent
9237dc785a
commit
aa34a28bd3
13
Makefile
13
Makefile
|
@ -321,6 +321,11 @@ start_web_server: all prepare_test_server
|
|||
@if test "$(TESTWEBSERVER)" = "apache"; then \
|
||||
LLNG_DEFAULTCONFFILE=`pwd`/e2e-tests/conf/lemonldap-ng.ini /usr/sbin/apache2 -d `pwd`/e2e-tests -f apache2.conf -k start; \
|
||||
elif test "$(TESTWEBSERVER)" = "nginx"; then \
|
||||
echo "Testing nginx conf"; \
|
||||
$(NGINX) -t -p `pwd`/e2e-tests \
|
||||
-g 'error_log '`pwd`'/e2e-tests/conf/nginx.log;' \
|
||||
-c `pwd`/e2e-tests/nginx.conf \
|
||||
2>&1 | grep -v 'Permission denied' || true; \
|
||||
echo "Launching nginx"; \
|
||||
$(NGINX) -p `pwd`/e2e-tests \
|
||||
-g 'error_log '`pwd`'/e2e-tests/conf/nginx.log;' \
|
||||
|
@ -364,12 +369,10 @@ restart_web_server: start_web_server
|
|||
|
||||
plackup:
|
||||
@LLNG_DEFAULTCONFFILE=`pwd`/e2e-tests/conf/lemonldap-ng.ini \
|
||||
/sbin/start-stop-daemon --start \
|
||||
--pidfile e2e-tests/conf/plackup.pid \
|
||||
-d `pwd` -b -m \
|
||||
--exec /usr/bin/plackup -- \
|
||||
-s FCGI \
|
||||
plackup -s FCGI \
|
||||
--listen e2e-tests/conf/llng.sock \
|
||||
--daemonize --pid e2e-tests/conf/plackup.pid \
|
||||
--nproc 1 --proc-title llng-fastcgi-server \
|
||||
e2e-tests/llng.psgi
|
||||
|
||||
#
|
||||
|
|
|
@ -25,7 +25,8 @@ server {
|
|||
# Client requests
|
||||
location / {
|
||||
auth_request /lmauth;
|
||||
auth_request_set $lmlocation $upstream_http_x_location;
|
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user;
|
||||
auth_request_set $lmlocation $upstream_http_location;
|
||||
error_page 401 $lmlocation;
|
||||
try_files $uri $uri/ =404;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ Package: liblemonldap-ng-handler-perl
|
|||
Architecture: all
|
||||
Depends: ${misc:Depends},
|
||||
${perl:Depends},
|
||||
libapache2-mod-perl2,
|
||||
libapache2-mod-perl2 | nginx,
|
||||
liblemonldap-ng-common-perl (= ${binary:Version}),
|
||||
libmouse-perl,
|
||||
liburi-perl,
|
||||
|
|
|
@ -18,8 +18,8 @@ my %_apps;
|
|||
|
||||
my %builder = (
|
||||
handler => sub {
|
||||
require Lemonldap::NG::Handler::PSGI::Server;
|
||||
return Lemonldap::NG::Handler::PSGI::Server->run( {} );
|
||||
require Lemonldap::NG::Handler::Nginx;
|
||||
return Lemonldap::NG::Handler::Nginx->run( {} );
|
||||
},
|
||||
manager => sub {
|
||||
require Lemonldap::NG::Manager;
|
||||
|
|
|
@ -119,6 +119,8 @@ has CONTENT_LENGTH => (
|
|||
);
|
||||
has error => ( is => 'rw', isa => 'Str', default => '' );
|
||||
|
||||
has respHeaders => ( is => 'rw', isa => 'HashRef' );
|
||||
|
||||
# JSON parser
|
||||
sub jsonBodyToObj {
|
||||
my $self = shift;
|
||||
|
|
|
@ -43,8 +43,8 @@ sub AUTOLOAD {
|
|||
# - Nginx
|
||||
if ( !$mode or $func eq 'newRequest' ) {
|
||||
$mode =
|
||||
( ( caller(1) )[0] eq 'Lemonldap::NG::Handler::PSGI::Server' )
|
||||
? 'PSGI/Server'
|
||||
( ( caller(1) )[0] eq 'Lemonldap::NG::Handler::Nginx' )
|
||||
? 'Nginx'
|
||||
: (
|
||||
( caller(0) )[0] =~ /^Lemonldap::NG::Handler::PSGI/
|
||||
or (
|
||||
|
@ -57,7 +57,7 @@ sub AUTOLOAD {
|
|||
: $ENV{GATEWAY_INTERFACE} ? 'CGI'
|
||||
: ( MP == 2 ) ? 'ApacheMP2'
|
||||
: ( MP == 1 ) ? 'ApacheMP1'
|
||||
: $main::{'nginx::'} ? 'Nginx'
|
||||
: $main::{'nginx::'} ? 'ExperimentalNginx'
|
||||
: 'CGI';
|
||||
unless ( $INC{"Lemonldap/NG/Handler/API/$mode.pm"} ) {
|
||||
$mode =~ s#/#::#g;
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
package Lemonldap::NG::Handler::API::Nginx;
|
||||
|
||||
our $VERSION = '1.9.0';
|
||||
|
||||
use constant FORBIDDEN => 403;
|
||||
use constant HTTP_UNAUTHORIZED => 401;
|
||||
use constant REDIRECT => 302;
|
||||
use constant OK => 0;
|
||||
use constant DECLINED => -1;
|
||||
use constant DONE => -2;
|
||||
use constant SERVER_ERROR => 500;
|
||||
use constant AUTH_REQUIRED => 401;
|
||||
use constant MAINTENANCE => 503;
|
||||
|
||||
my $request; # Nginx object for current request
|
||||
|
||||
## @method void thread_share(string $variable)
|
||||
# not applicable with Nginx
|
||||
sub thread_share {
|
||||
}
|
||||
|
||||
## @method void setServerSignature(string sign)
|
||||
# modifies web server signature
|
||||
# @param $sign String to add to server signature
|
||||
sub setServerSignature {
|
||||
my ( $class, $sign ) = @_;
|
||||
|
||||
# TODO
|
||||
}
|
||||
|
||||
sub newRequest {
|
||||
my ( $class, $r ) = @_;
|
||||
$request = $r;
|
||||
$Lemonldap::NG::API::mode = 'Nginx';
|
||||
}
|
||||
|
||||
## @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
|
||||
}
|
||||
|
||||
## @method void set_user(string user)
|
||||
# sets remote_user
|
||||
# @param user string username
|
||||
sub set_user {
|
||||
my ( $class, $user ) = @_;
|
||||
$request->variable( 'lmremote_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->header_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 ) {
|
||||
if ( $h =~ /cookie/i ) {
|
||||
|
||||
# TODO: check that variable $lmcookie is defined,
|
||||
# else warn that LL::NG cookie will not be removed
|
||||
$request->variable( 'lmcookie', $v );
|
||||
}
|
||||
else {
|
||||
# TODO: check that header is not yet set, else throw warning
|
||||
# or reject request if mode paranoid is set
|
||||
# TODO: check that variable nginxName($h) is defined,
|
||||
# else warn that header will not be sent
|
||||
$request->variable( nginxName($h), $v );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## @method void unset_header_in(array headers)
|
||||
# removes request headers
|
||||
# @param headers array with header names to remove
|
||||
sub unset_header_in {
|
||||
my ( $class, @headers ) = @_;
|
||||
foreach my $h1 (@headers) {
|
||||
|
||||
# TODO: check that header is not yet set, else throw warning
|
||||
$request->variable( nginxName($h), '' );
|
||||
}
|
||||
}
|
||||
|
||||
## @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 ) {
|
||||
if ( $h =~ /location/i ) {
|
||||
$request->variable( 'lmlocation', $v );
|
||||
}
|
||||
else {
|
||||
$request->header_out( $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->variable('host');
|
||||
}
|
||||
|
||||
## @method string remote_ip
|
||||
# returns client IP address
|
||||
# @return IP_Addr string client IP
|
||||
sub remote_ip {
|
||||
my $class = shift;
|
||||
return $request->variable('remote_addr');
|
||||
}
|
||||
|
||||
## @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 1;
|
||||
}
|
||||
|
||||
## @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;
|
||||
return $request->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->variable('request_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->variable('server_port');
|
||||
}
|
||||
|
||||
## @method string method
|
||||
# returns the method the request is sent with
|
||||
# @return port string server port
|
||||
sub method {
|
||||
my $class = shift;
|
||||
return $request->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);
|
||||
}
|
||||
|
||||
## @method void addToHtmlHead(string data)
|
||||
# add data at end of html head: not feasible with Nginx
|
||||
# @param data Text to add in html head
|
||||
sub addToHtmlHead {
|
||||
my ( $class, $data ) = @_;
|
||||
|
||||
# TODO: throw error log
|
||||
}
|
||||
|
||||
## @method void setPostParams(hashref $params)
|
||||
# add or modify parameters in POST request body: not feasible with Nginx
|
||||
# @param $params hashref containing name => value
|
||||
sub setPostParams {
|
||||
my ( $class, $params ) = @_;
|
||||
|
||||
# TODO: throw error log
|
||||
}
|
||||
|
||||
sub nginxName {
|
||||
my $h = lc(shift);
|
||||
$h =~ s/-/_/g;
|
||||
return "lm_$h";
|
||||
}
|
||||
|
||||
1;
|
|
@ -1,222 +1,12 @@
|
|||
package Lemonldap::NG::Handler::API::Nginx;
|
||||
|
||||
use strict;
|
||||
our $VERSION = '1.9.0';
|
||||
|
||||
use constant FORBIDDEN => 403;
|
||||
use constant HTTP_UNAUTHORIZED => 401;
|
||||
use constant REDIRECT => 302;
|
||||
use constant OK => 0;
|
||||
use constant DECLINED => -1;
|
||||
use constant DONE => -2;
|
||||
use constant SERVER_ERROR => 500;
|
||||
use constant AUTH_REQUIRED => 401;
|
||||
use constant MAINTENANCE => 503;
|
||||
use base 'Lemonldap::NG::Handler::API::PSGI';
|
||||
|
||||
my $request; # Nginx object for current request
|
||||
|
||||
## @method void thread_share(string $variable)
|
||||
# not applicable with Nginx
|
||||
sub thread_share {
|
||||
}
|
||||
|
||||
## @method void setServerSignature(string sign)
|
||||
# modifies web server signature
|
||||
# @param $sign String to add to server signature
|
||||
sub setServerSignature {
|
||||
my ( $class, $sign ) = @_;
|
||||
|
||||
# TODO
|
||||
}
|
||||
|
||||
sub newRequest {
|
||||
my ( $class, $r ) = @_;
|
||||
$request = $r;
|
||||
$Lemonldap::NG::API::mode = 'Nginx';
|
||||
}
|
||||
|
||||
## @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
|
||||
}
|
||||
|
||||
## @method void set_user(string user)
|
||||
# sets remote_user
|
||||
# @param user string username
|
||||
sub set_user {
|
||||
my ( $class, $user ) = @_;
|
||||
$request->variable( 'lmremote_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->header_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 ) {
|
||||
if ( $h =~ /cookie/i ) {
|
||||
|
||||
# TODO: check that variable $lmcookie is defined,
|
||||
# else warn that LL::NG cookie will not be removed
|
||||
$request->variable( 'lmcookie', $v );
|
||||
}
|
||||
else {
|
||||
# TODO: check that header is not yet set, else throw warning
|
||||
# or reject request if mode paranoid is set
|
||||
# TODO: check that variable nginxName($h) is defined,
|
||||
# else warn that header will not be sent
|
||||
$request->variable( nginxName($h), $v );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## @method void unset_header_in(array headers)
|
||||
# removes request headers
|
||||
# @param headers array with header names to remove
|
||||
sub unset_header_in {
|
||||
my ( $class, @headers ) = @_;
|
||||
foreach my $h1 (@headers) {
|
||||
|
||||
# TODO: check that header is not yet set, else throw warning
|
||||
$request->variable( nginxName($h), '' );
|
||||
}
|
||||
}
|
||||
|
||||
## @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 ) {
|
||||
if ( $h =~ /location/i ) {
|
||||
$request->variable( 'lmlocation', $v );
|
||||
}
|
||||
else {
|
||||
$request->header_out( $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->variable('host');
|
||||
}
|
||||
|
||||
## @method string remote_ip
|
||||
# returns client IP address
|
||||
# @return IP_Addr string client IP
|
||||
sub remote_ip {
|
||||
my $class = shift;
|
||||
return $request->variable('remote_addr');
|
||||
}
|
||||
|
||||
## @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 1;
|
||||
}
|
||||
|
||||
## @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;
|
||||
return $request->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->variable('request_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->variable('server_port');
|
||||
}
|
||||
|
||||
## @method string method
|
||||
# returns the method the request is sent with
|
||||
# @return port string server port
|
||||
sub method {
|
||||
my $class = shift;
|
||||
return $request->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);
|
||||
}
|
||||
|
||||
## @method void addToHtmlHead(string data)
|
||||
# add data at end of html head: not feasible with Nginx
|
||||
# @param data Text to add in html head
|
||||
sub addToHtmlHead {
|
||||
my ( $class, $data ) = @_;
|
||||
|
||||
# TODO: throw error log
|
||||
}
|
||||
|
||||
## @method void setPostParams(hashref $params)
|
||||
# add or modify parameters in POST request body: not feasible with Nginx
|
||||
# @param $params hashref containing name => value
|
||||
sub setPostParams {
|
||||
my ( $class, $params ) = @_;
|
||||
|
||||
# TODO: throw error log
|
||||
}
|
||||
|
||||
sub nginxName {
|
||||
my $h = lc(shift);
|
||||
$h =~ s/-/_/g;
|
||||
return "lm_$h";
|
||||
return $Lemonldap::NG::Handler::API::PSGI::request->original_uri;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -30,6 +30,10 @@ sub thread_share {
|
|||
# nothing to do in PSGI
|
||||
}
|
||||
|
||||
## @method void newRequest($r)
|
||||
# Store request in global $request variable
|
||||
#
|
||||
#@param $r Lemonldap::NG::Common::PSGI::Request
|
||||
sub newRequest {
|
||||
my ( $class, $r ) = @_;
|
||||
$request = $r;
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package Lemonldap::NG::Handler::API::PSGI::Server;
|
||||
|
||||
use strict;
|
||||
our $VERSION = '1.9.0';
|
||||
|
||||
use base 'Lemonldap::NG::Handler::API::PSGI';
|
||||
|
||||
sub uri {
|
||||
return $Lemonldap::NG::Handler::API::PSGI::request->original_uri;
|
||||
}
|
||||
|
||||
1;
|
|
@ -0,0 +1,72 @@
|
|||
# PSGI authentication package written for Nginx. It replace
|
||||
# Lemonldap::NG::Handler::PSGI::Server to manage Nginx behaviour
|
||||
package Lemonldap::NG::Handler::Nginx;
|
||||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Handler::SharedConf qw(:tsv);
|
||||
|
||||
extends 'Lemonldap::NG::Handler::PSGI';
|
||||
|
||||
## @method Code-Ref _run()
|
||||
# Return a subroutine that call _authAndTrace() and tranform redirection
|
||||
# response code from 302 to 401 (not authenticated) ones. This is required
|
||||
# because Nginx "auth_request" parameter does not accept it. The Nginx
|
||||
# configuration file should transform them back to 302 using:
|
||||
#
|
||||
# auth_request_set $lmlocation $upstream_http_location;
|
||||
# error_page 401 $lmlocation;
|
||||
#
|
||||
#@return subroutine that will be called to manage FastCGI queries
|
||||
sub _run {
|
||||
my $self = shift;
|
||||
return sub {
|
||||
my $req = $_[0];
|
||||
$self->lmLog( 'New request', 'debug' );
|
||||
my $res = $self->_authAndTrace(
|
||||
Lemonldap::NG::Common::PSGI::Request->new( $_[0] ) );
|
||||
|
||||
# Transform 302 responses in 401 since Nginx refuse it
|
||||
if ( $res->[0] == 302 or $res->[0] == 303 ) {
|
||||
$res->[0] = 401;
|
||||
}
|
||||
|
||||
# TODO: transform headers in $res->[1]
|
||||
return $res;
|
||||
};
|
||||
}
|
||||
|
||||
## @method PSGI-Response router()
|
||||
# Transform headers returned by handler main process:
|
||||
# each "Name: value" is transformed to:
|
||||
# - Headername<i>: Name
|
||||
# - Headervalue<i>: value
|
||||
# where <i> is an integer starting from 1
|
||||
# It can be used in Nginx virtualhost configuration:
|
||||
#
|
||||
# auth_request_set $headername1 $upstream_http_headername1;
|
||||
# auth_request_set $headervalue1 $upstream_http_headervalue1;
|
||||
# #proxy_set_header $headername1 $headervalue1;
|
||||
# # OR
|
||||
# #fastcgi_param $fheadername1 $headervalue1;
|
||||
#
|
||||
# It add also a header called Lm-Remote-User set to whatToTrace value that can
|
||||
# be used in Nginx virtualhost configuration to insert user id in logs
|
||||
#
|
||||
# auth_request_set $llremoteuser $upstream_http_lm_remote_user
|
||||
#
|
||||
#@param $req Lemonldap::NG::Common::PSGI::Request
|
||||
sub router {
|
||||
my ( $self, $req ) = @_;
|
||||
my $hdrs = $req->{respHeaders} || {};
|
||||
my @convertedHdrs =
|
||||
[ 'Lm-Remote-User', $self->userId, 'Content-Length', 0 ];
|
||||
my $i = 0;
|
||||
foreach my $k ( keys %$hdrs ) {
|
||||
$i++;
|
||||
push @convertedHdrs, "Headername$i", $k, "Headervalue$i", $hdrs->{$k};
|
||||
}
|
||||
return [ 200, \@convertedHdrs, [] ];
|
||||
}
|
||||
|
||||
1;
|
|
@ -8,6 +8,8 @@ our $VERSION = '1.9.0';
|
|||
|
||||
has protection => ( is => 'rw', isa => 'Str' );
|
||||
|
||||
## @method boolean init($args)
|
||||
# Initalize main handler
|
||||
sub init {
|
||||
my ( $self, $args ) = @_;
|
||||
eval { Lemonldap::NG::Handler::SharedConf->init($self) };
|
||||
|
@ -25,6 +27,9 @@ sub init {
|
|||
return 1;
|
||||
}
|
||||
|
||||
## @methodi CODE-ref _run
|
||||
# Check if protecton is activated then return a code ref that will launch
|
||||
# _authAndTrace() if protection in on or router() else
|
||||
sub _run {
|
||||
my $self = shift;
|
||||
|
||||
|
@ -45,6 +50,8 @@ sub _run {
|
|||
|
||||
else {
|
||||
$self->lmLog( 'PSGI app is not protected', 'debug' );
|
||||
|
||||
# Check if main handler initialization has been done
|
||||
unless (%$tsv) {
|
||||
$self->lmLog( 'Checking conf', 'debug' );
|
||||
eval { Lemonldap::NG::Handler::SharedConf->checkConf() };
|
||||
|
@ -58,6 +65,9 @@ sub _run {
|
|||
}
|
||||
}
|
||||
|
||||
## @method private PSGI-Response _authAndTrace($req)
|
||||
# Launch Lemonldap::NG::Handler::SharedConf::run() and then router() if
|
||||
# response is 200.
|
||||
sub _authAndTrace {
|
||||
my ( $self, $req ) = @_;
|
||||
Lemonldap::NG::Handler::API->newRequest($req);
|
||||
|
@ -69,36 +79,6 @@ sub _authAndTrace {
|
|||
$self->lmLog( 'User authenticated, calling router()', 'debug' );
|
||||
return $self->router($req);
|
||||
}
|
||||
|
||||
# Ajax hook: Ajax requests can not understand 30x responses. This
|
||||
# is not really HTTP compliant but nothing in this
|
||||
# protocol can do this. Our javascripts understand that
|
||||
# they have to prompt user with the URL
|
||||
#elsif (
|
||||
# $req->accept =~ m|application/json|
|
||||
# or ( $req->contentType
|
||||
# and $req->contentType =~ m|application/json| )
|
||||
# )
|
||||
#{
|
||||
# $self->lmLog( 'Ajax request detected', 'debug' );
|
||||
# if ( $res == 302 or $res == 303 ) {
|
||||
# $self->lmLog( 'Rewrite redirection to 401 response', 'debug' );
|
||||
# return [
|
||||
# 401, [ 'WWW-Authenticate' => $req->{respHeaders}->{Location} ], ['']
|
||||
# ];
|
||||
# }
|
||||
# else {
|
||||
# $self->lmLog(
|
||||
# "Lemonldap::NG::Handler::SharedConf::run() returns $res",
|
||||
# 'debug' );
|
||||
# return [
|
||||
# $res, [ 'Content-Type', 'application/json' ],
|
||||
# [qq({"error":"$res"})]
|
||||
# ];
|
||||
# }
|
||||
#}
|
||||
|
||||
# Non Ajax requests may be redirected to portal
|
||||
else {
|
||||
my %h = $req->{respHeaders} ? %{ $req->{respHeaders} } : ();
|
||||
my $s = $tsv->{portal}->() . "?lmError=$res";
|
||||
|
@ -148,4 +128,5 @@ sub sendError {
|
|||
$err = '[' . $self->userId($req) . "] $err";
|
||||
return $self->Lemonldap::NG::Common::PSGI::sendError( $req, $err, $code );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -6,27 +6,18 @@ use Lemonldap::NG::Handler::SharedConf qw(:tsv);
|
|||
|
||||
extends 'Lemonldap::NG::Handler::PSGI';
|
||||
|
||||
## @method PSGI-Response router($res)
|
||||
# If PSGI is used as an authentication FastCGI only, this method will be
|
||||
# called for authenticated users and will set headers in response without
|
||||
# content.
|
||||
# @param $req Lemonldap::NG::Common::PSGI::Request
|
||||
sub router {
|
||||
return [ 200, [], [] ];
|
||||
}
|
||||
|
||||
sub _run {
|
||||
my $self = shift;
|
||||
return sub {
|
||||
my $req = $_[0];
|
||||
$self->lmLog( 'New request', 'debug' );
|
||||
my $res = $self->_authAndTrace(
|
||||
Lemonldap::NG::Common::PSGI::Request->new( $_[0] ) );
|
||||
|
||||
# Transform 302 responses in 401 since Nginx refuse it
|
||||
if($res->[0] == 302 or $res->[0] == 303) {
|
||||
$res->[0] = 401;
|
||||
push @{$res->[1]},'X-Location' => $tsv->{portal}->();
|
||||
}
|
||||
|
||||
# TODO: transform headers in $res->[1]
|
||||
return $res;
|
||||
};
|
||||
my ( $self, $req ) = @_;
|
||||
my $hdrs = $req->{respHeaders} || {};
|
||||
return [
|
||||
200, [ 'Lm-Remote-User', $self->userId, 'Content-Length', 0, %$hdrs ],
|
||||
[]
|
||||
];
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
Loading…
Reference in New Issue