package Lemonldap::NG::Handler::PSGI::Base; use 5.10.0; use Mouse; use Lemonldap::NG::Handler::SharedConf qw(:tsv :variables :jailSharedVars); 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) }; if ( $@ and not $self->{protection} eq 'none' ) { $self->error($@); return 0; } unless ( Lemonldap::NG::Handler::SharedConf->checkConf($self) or $self->{protection} eq 'none' ) { $self->error( "Unable to protect this app ($Lemonldap::NG::Common::Conf::msg)"); return 0; } return 1; } ## @methodi void _run() # Check if protecton is activated then return a code ref that will launch # _authAndTrace() if protection in on or router() else #@return code-ref sub _run { my $self = shift; # Override _run() only if protection != 'none' my $rule = $self->{protection} || $localConfig->{protection}; if ( $rule ne 'none' ) { $self->lmLog( 'PSGI app is protected', 'debug' ); $rule = $rule eq "authenticate" ? "accept" : $rule eq "manager" ? "" : $rule; # Handle requests # Developers, be careful: Only this part is executed at each request return sub { return $self->_authAndTrace( Lemonldap::NG::Common::PSGI::Request->new( $_[0] ) ); }; } 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() }; $self->lmLog( $@, 'error' ) if ($@); } # Handle unprotected requests return sub { $self->router( Lemonldap::NG::Common::PSGI::Request->new( $_[0] ) ); }; } } ## @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); my $res = Lemonldap::NG::Handler::SharedConf->run( $self->{protection} || $localConfig->{protection} ); $req->userData($datas) if ($datas); if ( $res < 300 ) { $self->lmLog( 'User authenticated, calling router()', 'debug' ); return $self->router($req); } else { my %h = $req->{respHeaders} ? %{ $req->{respHeaders} } : (); my $s = $tsv->{portal}->() . "?lmError=$res"; $s = 'Redirection' . qq{} . '

Please wait

' . qq{

An error occurs, you're going to be redirected to $s.

} . ''; $h{'Content-Type'} = 'text/html'; $h{'Content-Length'} = length $s; return [ $res, [%h], [$s] ]; } } ## @method hashRef user() # @return hash of user datas sub user { my ( $self, $req ) = @_; return $req->userData || { _whatToTrace => 'anonymous' }; } ## @method string userId() # @return user identifier to log sub userId { my ( $self, $req ) = @_; return $req->userData->{_whatToTrace} || 'anonymous'; } ## @method boolean group(string group) # @param $group name of the Lemonldap::NG group to test # @return boolean : true if user is in this group sub group { my ( $self, $req, $group ) = @_; return () unless ( $req->userData->{groups} ); return ( $req->userData->{groups} =~ /\b$group\b/ ); } ## @method PSGI::Response sendError($req,$err,$code) # Add user di to $err before calling Lemonldap::NG::Common::PSGI::sendError() # @param $req Lemonldap::NG::Common::PSGI::Request # @param $err String to push # @code int HTTP error code (default to 500) sub sendError { my ( $self, $req, $err, $code ) = @_; $err ||= $req->error; $err = '[' . $self->userId($req) . "] $err"; return $self->Lemonldap::NG::Common::PSGI::sendError( $req, $err, $code ); } 1;