Replace SERVER_ERROR by abort when possible (#204)

This commit is contained in:
Xavier Guimard 2010-10-20 20:05:32 +00:00
parent d01b6caa15
commit a0f2dbf501
8 changed files with 55 additions and 33 deletions

View File

@ -186,6 +186,7 @@ status = 0
;useRedirectOnForbidden = 1 ;useRedirectOnForbidden = 1
# Hide LemonLDAP::NG Handler in Apache Server Signature # Hide LemonLDAP::NG Handler in Apache Server Signature
;hideSignature = 1 ;hideSignature = 1
useRedirectOnError = 1
# Zimbra Handler parameters # Zimbra Handler parameters
;zimbraPreAuthKey = XXXX ;zimbraPreAuthKey = XXXX
@ -212,6 +213,11 @@ status = 0
# Use the following to modify error output: # Use the following to modify error output:
;hideLogLevels = debug|info ;hideLogLevels = debug|info
[sessionsExplorer]
# Sessions explorer inherits from manager section. You can override here
# some parameters like 'protection'
;protection = authenticate
[apply] [apply]
# URL used to reload configuration # URL used to reload configuration

View File

@ -82,12 +82,8 @@ sub run ($$) {
# Catch SOAP errors # Catch SOAP errors
if ( $r->fault ) { if ( $r->fault ) {
$class->lmLog( return $class->abort( "SOAP request to the portal failed: "
"SOAP request to the portal failed: " . $r->fault->{faultstring} );
. $r->fault->{faultstring},
'error'
);
return SERVER_ERROR;
} }
else { else {
my $res = $r->result(); my $res = $r->result();

View File

@ -86,7 +86,7 @@ sub defaultValuesInit {
# @return boolean # @return boolean
sub localInit { sub localInit {
my ( $class, $args ) = splice @_; my ( $class, $args ) = splice @_;
$class->abort( die(
"$class : unable to build configuration : $Lemonldap::NG::Common::Conf::msg" "$class : unable to build configuration : $Lemonldap::NG::Common::Conf::msg"
) )
unless ( $lmConf = unless ( $lmConf =
@ -122,10 +122,8 @@ sub localInit {
sub run($$) { sub run($$) {
my ( $class, $r ) = splice @_; my ( $class, $r ) = splice @_;
if ( time() - $lastReload > $reloadTime ) { if ( time() - $lastReload > $reloadTime ) {
unless ( my $tmp = $class->testConf(1) == OK ) { die( "$class: No configuration found" )
$class->lmLog( "$class: No configuration found", 'error' ); unless ( $class->testConf(1) == OK );
return SERVER_ERROR;
}
} }
return $class->SUPER::run($r); return $class->SUPER::run($r);
} }

View File

@ -47,6 +47,7 @@ our (
$customFunctions, $transform, $cda, $customFunctions, $transform, $cda,
$childInitDone, $httpOnly, $cookieExpiration, $childInitDone, $httpOnly, $cookieExpiration,
$timeoutActivity, $datasUpdate, $useRedirectOnForbidden, $timeoutActivity, $datasUpdate, $useRedirectOnForbidden,
$useRedirectOnError,
); );
########################################## ##########################################
@ -74,7 +75,8 @@ BEGIN {
], ],
traces => [qw( $whatToTrace $statusPipe $statusOut)], traces => [qw( $whatToTrace $statusPipe $statusOut)],
apache => [ apache => [
qw( MP OK REDIRECT FORBIDDEN DONE DECLINED SERVER_ERROR useRedirectOnForbidden ) qw( MP OK REDIRECT FORBIDDEN DONE DECLINED SERVER_ERROR
$useRedirectOnForbidden $useRedirectOnError )
], ],
post => [qw($transform)], post => [qw($transform)],
cda => ['$cda'], cda => ['$cda'],
@ -140,6 +142,7 @@ BEGIN {
threads::shared::share($statusOut); threads::shared::share($statusOut);
threads::shared::share($timeoutActivity); threads::shared::share($timeoutActivity);
threads::shared::share($useRedirectOnForbidden); threads::shared::share($useRedirectOnForbidden);
threads::shared::share($useRedirectOnError);
}; };
} }
elsif ( MP() == 1 ) { elsif ( MP() == 1 ) {
@ -187,20 +190,34 @@ sub logout_mp2 : method {
shift->unlog(@_); shift->unlog(@_);
} }
## @rmethod int abort(string mess)
# Logs message and exit or redirect to the portal if "useRedirectOnError" is
# set to true.
# @param $mess Message to log
# @return Apache2::Const::REDIRECT or Apache2::Const::SERVER_ERROR
sub abort { sub abort {
my ( $class, $mess ) = splice @_; my ( $class, $mess ) = splice @_;
# If abort is called without a valid request, fall to die
eval {
my $args = $apacheRequest->args; my $args = $apacheRequest->args;
my $uri = $apacheRequest->uri . ( $args ? "?$args" : "" ); my $uri = $apacheRequest->uri . ( $args ? "?$args" : "" );
# Set error 500 in logs even if "useRedirectOnError" is set
$apacheRequest->push_handlers( $apacheRequest->push_handlers(
PerlLogHandler => sub { $_[0]->status(SERVER_ERROR); DECLINED; } ); PerlLogHandler => sub { $_[0]->status(SERVER_ERROR); DECLINED; } );
$class->lmLog( $mess, 'error' ); $class->lmLog( $mess, 'error' );
if ($useRedirectOnForbidden) {
# Redirect or die
if ($useRedirectOnError) {
$class->lmLog( "Use redirect for error", 'debug' ); $class->lmLog( "Use redirect for error", 'debug' );
return $class->goToPortal( $uri, 'lmError=500' ); return $class->goToPortal( $uri, 'lmError=500' );
} }
else { else {
return SERVER_ERROR; return SERVER_ERROR;
} }
};
die $mess if ($@);
} }
## @rmethod void lmLog(string mess, string level) ## @rmethod void lmLog(string mess, string level)
@ -209,7 +226,7 @@ sub abort {
# @param $level string (debug, info, warning or error) # @param $level string (debug, info, warning or error)
sub lmLog { sub lmLog {
my ( $class, $mess, $level ) = splice @_; my ( $class, $mess, $level ) = splice @_;
$class->abort("Level is required") unless ($level); die("Level is required") unless ($level);
my $call; my $call;
unless ( $level eq 'debug' ) { unless ( $level eq 'debug' ) {
my @tmp = caller(); my @tmp = caller();
@ -485,7 +502,7 @@ sub childInit {
sub purgeCache { sub purgeCache {
my $class = shift; my $class = shift;
eval "use $localStorage;"; eval "use $localStorage;";
$class->abort("Unable to load $localStorage: $@") if ($@); die("Unable to load $localStorage: $@") if ($@);
# At each Apache (re)start, we've to clear the cache to avoid living # At each Apache (re)start, we've to clear the cache to avoid living
# with old datas # with old datas
@ -665,6 +682,10 @@ sub defaultValuesInit {
$httpOnly = defined($httpOnly) ? $httpOnly : $args->{httpOnly}; $httpOnly = defined($httpOnly) ? $httpOnly : $args->{httpOnly};
$cookieExpiration = $args->{cookieExpiration} || $cookieExpiration; $cookieExpiration = $args->{cookieExpiration} || $cookieExpiration;
$timeoutActivity = $args->{timeoutActivity} || $timeoutActivity || 0; $timeoutActivity = $args->{timeoutActivity} || $timeoutActivity || 0;
$useRedirectOnError =
defined($useRedirectOnError)
? $useRedirectOnError
: $args->{useRedirectOnError};
$useRedirectOnForbidden = $useRedirectOnForbidden =
defined($useRedirectOnForbidden) defined($useRedirectOnForbidden)
? $useRedirectOnForbidden ? $useRedirectOnForbidden
@ -677,7 +698,7 @@ sub defaultValuesInit {
# @param $args reference to the configuration hash # @param $args reference to the configuration hash
sub portalInit { sub portalInit {
my ( $class, $args ) = splice @_; my ( $class, $args ) = splice @_;
$class->abort("portal parameter required") unless ( $args->{portal} ); die("portal parameter required") unless ( $args->{portal} );
if ( $args->{portal} =~ /[\$\(&\|"']/ ) { if ( $args->{portal} =~ /[\$\(&\|"']/ ) {
my $portal = $class->conditionSub( $args->{portal} ); my $portal = $class->conditionSub( $args->{portal} );
eval "sub portal {return &\$portal}"; eval "sub portal {return &\$portal}";
@ -685,7 +706,7 @@ sub portalInit {
else { else {
eval "sub portal {return '$args->{portal}'}"; eval "sub portal {return '$args->{portal}'}";
} }
$class->abort("Unable to read portal parameter ($@)") if ($@); die("Unable to read portal parameter ($@)") if ($@);
1; 1;
} }
@ -695,9 +716,9 @@ sub portalInit {
sub globalStorageInit { sub globalStorageInit {
my ( $class, $args ) = splice @_; my ( $class, $args ) = splice @_;
$globalStorage = $args->{globalStorage} $globalStorage = $args->{globalStorage}
or $class->abort("globalStorage required"); or die("globalStorage required");
eval "use $globalStorage;"; eval "use $globalStorage;";
$class->abort($@) if ($@); die($@) if ($@);
$globalStorageOptions = $args->{globalStorageOptions}; $globalStorageOptions = $args->{globalStorageOptions};
} }
@ -1274,10 +1295,8 @@ sub redirectFilter {
sub status($$) { sub status($$) {
my ( $class, $r ) = splice @_; my ( $class, $r ) = splice @_;
$class->lmLog( "$class: request for status", 'debug' ); $class->lmLog( "$class: request for status", 'debug' );
unless ( $statusPipe and $statusOut ) { return $class->abort("$class: status page can not be displayed")
$class->lmLog( "$class: status page can not be displayed", 'error' ); unless ( $statusPipe and $statusOut );
return SERVER_ERROR;
}
$r->handler("perl-script"); $r->handler("perl-script");
print $statusPipe "STATUS" . ( $r->args ? " " . $r->args : '' ) . "\n"; print $statusPipe "STATUS" . ( $r->args ? " " . $r->args : '' ) . "\n";
my $buf; my $buf;

View File

@ -29,7 +29,7 @@ sub defaultValuesInit {
# If not, try to read it from /etc/lemonldap-ng/sympa.secret # If not, try to read it from /etc/lemonldap-ng/sympa.secret
if ( !$sympaSecret and -r '/etc/lemonldap-ng/sympa.secret' ) { if ( !$sympaSecret and -r '/etc/lemonldap-ng/sympa.secret' ) {
open S, '/etc/lemonldap-ng/sympa.secret' open S, '/etc/lemonldap-ng/sympa.secret'
or $class->abort("Unable to open /etc/lemonldap-ng/sympa.secret"); or die("Unable to open /etc/lemonldap-ng/sympa.secret");
$sympaSecret = join( '', <S> ); $sympaSecret = join( '', <S> );
close S; close S;
$sympaSecret =~ s/[\r\n]//g; $sympaSecret =~ s/[\r\n]//g;
@ -63,10 +63,8 @@ sub run {
return $ret unless ( $ret == OK ); return $ret unless ( $ret == OK );
# Fail if no sympaSecret # Fail if no sympaSecret
unless ($sympaSecret) { return $class->abort("No Sympa secret configured")
$class->lmLog( "No Sympa secret configured", 'error' ); unless ($sympaSecret);
return SERVER_ERROR;
}
# Mail value # Mail value
my $mail = $datas->{$sympaMailKey}; my $mail = $datas->{$sympaMailKey};

View File

@ -75,10 +75,8 @@ sub run {
return OK unless ( $uri =~ $zimbraSsoUrl ); return OK unless ( $uri =~ $zimbraSsoUrl );
# Check mandatory parameters # Check mandatory parameters
unless ($zimbraPreAuthKey) { return $class->abort("No Zimbra preauth key configured");
$class->lmLog( "No Zimbra preauth key configured", 'error' ); unless ($zimbraPreAuthKey);
return SERVER_ERROR;
}
# Build URL # Build URL
my $zimbra_url = $class->_buildZimbraPreAuthUrl( my $zimbra_url = $class->_buildZimbraPreAuthUrl(

View File

@ -730,10 +730,13 @@ sub struct {
}, },
redirection => { redirection => {
_nodes => [qw(https port useRedirectOnForbidden)], _nodes => [
qw(https port useRedirectOnForbidden useRedirectOnError)
],
https => 'bool:/https', https => 'bool:/https',
port => 'int:/port', port => 'int:/port',
useRedirectOnForbidden => 'bool:/useRedirectOnForbidden', useRedirectOnForbidden => 'bool:/useRedirectOnForbidden',
useRedirectOnError => 'bool:/useRedirectOnError',
}, },
specialHandlers => { specialHandlers => {
@ -1390,6 +1393,7 @@ sub testStruct {
test => qr/^[a-zA-Z][\w\:]*$/, test => qr/^[a-zA-Z][\w\:]*$/,
msgFail => 'Bad module name', msgFail => 'Bad module name',
}, },
useRedirectOnError => $boolean,
useRedirectOnForbidden => $boolean, useRedirectOnForbidden => $boolean,
useXForwardedForIP => $boolean, useXForwardedForIP => $boolean,
variables => $testNotDefined, variables => $testNotDefined,
@ -1696,6 +1700,7 @@ sub defaultConf {
userControl => '^[\w\.\-@]+$', userControl => '^[\w\.\-@]+$',
userDB => 'LDAP', userDB => 'LDAP',
passwordDB => 'LDAP', passwordDB => 'LDAP',
useRedirectOnError => '1',
useRedirectOnForbidden => '0', useRedirectOnForbidden => '0',
useXForwardedForIP => '0', useXForwardedForIP => '0',
vhostPort => '-1', vhostPort => '-1',

View File

@ -290,6 +290,7 @@ sub en {
userDB => 'Users module', userDB => 'Users module',
userControl => 'Username control', userControl => 'Username control',
userPivot => 'Login field name in user table', userPivot => 'Login field name in user table',
useRedirectOnError => 'Redirect on handler error',
useRedirectOnForbidden => 'Redirect on forbidden', useRedirectOnForbidden => 'Redirect on forbidden',
useXForwardedForIP => "Use X-Forwarded-For header address", useXForwardedForIP => "Use X-Forwarded-For header address",
variables => "Variables", variables => "Variables",
@ -671,6 +672,7 @@ sub fr {
userDB => "Module d'utilisateurs", userDB => "Module d'utilisateurs",
userControl => "Contrôle du nom d'utilisateur", userControl => "Contrôle du nom d'utilisateur",
userPivot => 'Champ identifiant dans la table des utilisateurs', userPivot => 'Champ identifiant dans la table des utilisateurs',
useRedirectOnError => 'Redirection pour les erreurs d\'agent',
useRedirectOnForbidden => 'Redirection pour les accès interdits', useRedirectOnForbidden => 'Redirection pour les accès interdits',
useXForwardedForIP => useXForwardedForIP =>
"Utiliser l'adresse IP de l'en-tête X-Forwarded-For", "Utiliser l'adresse IP de l'en-tête X-Forwarded-For",