From aa34a28bd378909ea5da259028da135392d4616e Mon Sep 17 00:00:00 2001 From: Xavier Guimard Date: Sat, 30 Jan 2016 12:26:14 +0000 Subject: [PATCH] Rearrange Nginx files --- Makefile | 13 +- _example/etc/handler-nginx.conf | 3 +- debian/control | 2 +- e2e-tests/llng.psgi | 4 +- .../lib/Lemonldap/NG/Common/PSGI/Request.pm | 2 + .../lib/Lemonldap/NG/Handler/API.pm | 6 +- .../NG/Handler/API/ExperimentalNginx.pm | 222 ++++++++++++++++++ .../lib/Lemonldap/NG/Handler/API/Nginx.pm | 216 +---------------- .../lib/Lemonldap/NG/Handler/API/PSGI.pm | 4 + .../Lemonldap/NG/Handler/API/PSGI/Server.pm | 12 - .../lib/Lemonldap/NG/Handler/Nginx.pm | 72 ++++++ .../lib/Lemonldap/NG/Handler/PSGI/Base.pm | 41 +--- .../lib/Lemonldap/NG/Handler/PSGI/Server.pm | 31 +-- 13 files changed, 341 insertions(+), 287 deletions(-) create mode 100644 lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/ExperimentalNginx.pm delete mode 100644 lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI/Server.pm create mode 100644 lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Nginx.pm diff --git a/Makefile b/Makefile index 973c0e67b..efc6fc18d 100644 --- a/Makefile +++ b/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 # diff --git a/_example/etc/handler-nginx.conf b/_example/etc/handler-nginx.conf index 18d396736..8e5df2958 100644 --- a/_example/etc/handler-nginx.conf +++ b/_example/etc/handler-nginx.conf @@ -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; diff --git a/debian/control b/debian/control index fc12b46de..0bd45dca4 100644 --- a/debian/control +++ b/debian/control @@ -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, diff --git a/e2e-tests/llng.psgi b/e2e-tests/llng.psgi index 3ec1baec0..ed63e9cc7 100644 --- a/e2e-tests/llng.psgi +++ b/e2e-tests/llng.psgi @@ -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; diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm index eb62e0d5d..62beeb42b 100644 --- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm @@ -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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API.pm index 5c4fd160e..a8218ed96 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API.pm @@ -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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/ExperimentalNginx.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/ExperimentalNginx.pm new file mode 100644 index 000000000..ef8d865ad --- /dev/null +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/ExperimentalNginx.pm @@ -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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/Nginx.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/Nginx.pm index ef8d865ad..2f45970d5 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/Nginx.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/Nginx.pm @@ -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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI.pm index 1817e0eaa..7e13b5d13 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI.pm @@ -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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI/Server.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI/Server.pm deleted file mode 100644 index 785e98dc8..000000000 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/API/PSGI/Server.pm +++ /dev/null @@ -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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Nginx.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Nginx.pm new file mode 100644 index 000000000..d88361c54 --- /dev/null +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Nginx.pm @@ -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: Name +# - Headervalue: value +# where 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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Base.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Base.pm index 7b2101244..b3e9d4908 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Base.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Base.pm @@ -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; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Server.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Server.pm index 567b9e0f6..10070e939 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Server.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Server.pm @@ -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;