Merge branch '2381' into 'v2.0'
2381 See merge request lemonldap-ng/lemonldap-ng!170
This commit is contained in:
commit
d8a3569ed0
|
@ -503,6 +503,9 @@ Some options are available:
|
|||
- Maintenance mode: reject all requests with a maintenance message
|
||||
- Aliases: list of aliases for this virtual host *(avoid to rewrite
|
||||
rules,...)*
|
||||
- Access to trace: can be used for overwriting REMOTE_CUSTOM with a custom function.
|
||||
Provide a comma separated list with custom function path and args.
|
||||
By example: My::accessToTrace, 'Dr Who', 'dwho@badwolf.org'
|
||||
- Type: handler type (normal,
|
||||
:doc:`ServiceToken Handler<servertoserver>`,
|
||||
:doc:`DevOps Handler<devopshandler>`,...)
|
||||
|
@ -515,6 +518,29 @@ Some options are available:
|
|||
seconds. This TTL can be customized for each virtual host.
|
||||
|
||||
|
||||
.. attention::
|
||||
|
||||
A hash reference containing $req, $session, $vhost, $custom and an array reference
|
||||
with provided parameters is passed to accessToTrace custom function.
|
||||
|
||||
::
|
||||
|
||||
package My;
|
||||
|
||||
sub accessToTrace {
|
||||
my $hash = shift;
|
||||
my $custom = $hash->{custom};
|
||||
my $req = $hash->{req};
|
||||
my $vhost = $hash->{vhost};
|
||||
my $custom = hash->{custom};
|
||||
|
||||
return
|
||||
"$custom alias $hash->{params}->[0]#$hash->{params}->[1]:$hash->{session}->{groups}";
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
.. danger::
|
||||
|
||||
A same virtual host can serve many locations. Each
|
||||
|
|
|
@ -8,4 +8,10 @@ sub get_additional_arg {
|
|||
return $_[0];
|
||||
}
|
||||
|
||||
sub accessToTrace {
|
||||
my $hash = shift;
|
||||
return
|
||||
"$hash->{custom} alias $hash->{params}->[0] $hash->{params}->[1]:$hash->{session}->{groups}";
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -164,6 +164,16 @@
|
|||
"default": "accept"
|
||||
}
|
||||
},
|
||||
"vhostOptions":{
|
||||
"manager.example.com": {
|
||||
"vhostMaintenance": 0,
|
||||
"vhostPort": -1,
|
||||
"vhostHttps": -1,
|
||||
"vhostAliases": "",
|
||||
"vhostServiceTokenTTL": -1,
|
||||
"vhostAccessToTrace": "My::accessToTrace, Doctor, Who","vhostType":"Main"
|
||||
}
|
||||
},
|
||||
"loginHistoryEnabled": 1,
|
||||
"macros": {
|
||||
"UA" : "$ENV{HTTP_USER_AGENT}",
|
||||
|
|
|
@ -30,7 +30,7 @@ our $oidcOPMetaDataNodeKeys = 'oidcOPMetaData(?:Options(?:C(?:lient(?:Secret|ID)
|
|||
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:uth(?:orizationCodeExpiration|nLevel)|llow(?:PasswordGrant|Offline)|ccessTokenExpiration|dditionalAudiences)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|(?:ExportedVar|Macro)s)';
|
||||
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|UserAttribut|DisplayNam)e|S(?:ign(?:S[LS]OMessage|atureMethod)|toreSAMLToken|[LS]OBinding|ortNumber)|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Re(?:questedAuthnContext|solutionRule|layStateURL)|Force(?:Authn|UTF8)|I(?:sPassive|con)|NameIDFormat)|ExportedAttributes|XML)';
|
||||
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:S(?:ign(?:S[LS]OMessage|atureMethod)|essionNotOnOrAfterTimeout)|N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|AuthnLevel|ForceUTF8)|(?:ExportedAttribute|Macro)s|XML)';
|
||||
our $virtualHostKeys = '(?:vhost(?:A(?:uthnLevel|liases)|(?:Maintenanc|Typ)e|ServiceTokenTTL|Https|Port)|(?:exportedHeader|locationRule)s|post)';
|
||||
our $virtualHostKeys = '(?:vhost(?:A(?:ccessToTrace|uthnLevel|liases)|(?:Maintenanc|Typ)e|ServiceTokenTTL|Https|Port)|(?:exportedHeader|locationRule)s|post)';
|
||||
|
||||
our $authParameters = {
|
||||
adParams => [qw(ADPwdMaxAge ADPwdExpireWarning)],
|
||||
|
|
|
@ -238,6 +238,8 @@ sub defaultValuesInit {
|
|||
$conf->{vhostOptions}->{$vhost}->{vhostAuthnLevel};
|
||||
$class->tsv->{serviceTokenTTL}->{$vhost} =
|
||||
$conf->{vhostOptions}->{$vhost}->{vhostServiceTokenTTL};
|
||||
$class->tsv->{accessToTrace}->{$vhost} =
|
||||
$conf->{vhostOptions}->{$vhost}->{vhostAccessToTrace};
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Main running methods file
|
||||
package Lemonldap::NG::Handler::Main::Run;
|
||||
|
||||
our $VERSION = '2.0.9';
|
||||
our $VERSION = '2.0.10';
|
||||
|
||||
package Lemonldap::NG::Handler::Main;
|
||||
|
||||
|
@ -105,6 +105,7 @@ sub checkType {
|
|||
sub run {
|
||||
my ( $class, $req, $rule, $protection ) = @_;
|
||||
my ( $id, $session );
|
||||
my $vhost = $class->resolveAlias($req);
|
||||
|
||||
return $class->DECLINED unless ( $class->is_initial_req($req) );
|
||||
|
||||
|
@ -149,9 +150,41 @@ sub run {
|
|||
|
||||
# ACCOUNTING (1. Inform web server)
|
||||
$class->set_user( $req, $session->{ $class->tsv->{whatToTrace} } );
|
||||
$class->set_custom( $req, $session->{ $class->tsv->{customToTrace} } )
|
||||
if $class->tsv->{customToTrace}
|
||||
and $session->{ $class->tsv->{customToTrace} };
|
||||
|
||||
my $custom;
|
||||
$custom = $session->{ $class->tsv->{customToTrace} }
|
||||
if ( $class->tsv->{customToTrace}
|
||||
and $session->{ $class->tsv->{customToTrace} } );
|
||||
if ( $class->tsv->{accessToTrace}->{$vhost} ) {
|
||||
my ( $function, @params ) = split /\s*,\s*/,
|
||||
$class->tsv->{accessToTrace}->{$vhost};
|
||||
if ( $function =~ qr/^(?:\w+(?:::\w+)*(?:\s+\w+(?:::\w+)*)*)?$/ ) {
|
||||
my $c = eval {
|
||||
no strict 'refs';
|
||||
&{$function}( {
|
||||
req => $req,
|
||||
vhost => $vhost,
|
||||
session => $session,
|
||||
custom => $custom,
|
||||
params => \@params
|
||||
}
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
$class->logger->error(
|
||||
"Failed to overwrite customToTrace: $@");
|
||||
}
|
||||
else {
|
||||
$class->logger->debug("Overwrite customToTrace with: $c");
|
||||
$custom = $c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$class->logger->error(
|
||||
"accessToTrace: Bad custom function name");
|
||||
}
|
||||
}
|
||||
$class->set_custom( $req, $custom ) if $custom;
|
||||
|
||||
# AUTHORIZATION
|
||||
return ( $class->forbidden( $req, $session ), $session )
|
||||
|
|
|
@ -4,7 +4,10 @@ use MIME::Base64;
|
|||
use Data::Dumper;
|
||||
use URI::Escape;
|
||||
|
||||
require 't/test-psgi-lib.pm';
|
||||
BEGIN {
|
||||
require 't/test-psgi-lib.pm';
|
||||
require 't/custom.pm';
|
||||
}
|
||||
|
||||
init('Lemonldap::NG::Handler::Server::Nginx');
|
||||
|
||||
|
@ -31,6 +34,26 @@ count(4);
|
|||
# Authentified queries
|
||||
# --------------------
|
||||
|
||||
# Authorized query
|
||||
ok(
|
||||
$res =
|
||||
$client->_get( '/', undef, 'test4.example.com', "lemonldap=$sessionId" ),
|
||||
'Authentified query'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
count(2);
|
||||
|
||||
# Check headers
|
||||
%h = @{ $res->[1] };
|
||||
ok(
|
||||
$h{'Lm-Remote-Custom'} eq
|
||||
'dwho@badwolf.org alias Doctor Who:users; timelords',
|
||||
'Lm-Remote-User is overwriten'
|
||||
)
|
||||
or explain( \%h,
|
||||
'Lm-Remote-User => "dwho@badwolf.org alias Doctor Who:users; timelords"' );
|
||||
count(1);
|
||||
|
||||
# Authorized query
|
||||
ok( $res = $client->_get( '/', undef, undef, "lemonldap=$sessionId" ),
|
||||
'Authentified query' );
|
||||
|
@ -43,7 +66,11 @@ ok( $h{'Headername1'} eq 'Auth-User', 'Headername1 is set to "Auth-User"' )
|
|||
or explain( \%h, 'Headername1 => "Auth-User"' );
|
||||
ok( $h{'Headervalue1'} eq 'dwho', 'Headervalue1 is set to "dwho"' )
|
||||
or explain( \%h, 'Headervalue1 => "dwho"' );
|
||||
count(2);
|
||||
ok(
|
||||
$h{'Lm-Remote-Custom'} eq 'dwho@badwolf.org',
|
||||
'Lm-Remote-User is set "dwho@badwolf.org"'
|
||||
) or explain( \%h, 'Lm-Remote-User => "dwho@badwolf.org"' );
|
||||
count(3);
|
||||
|
||||
# Request an URI protected by custom function -> allowed
|
||||
ok(
|
||||
|
|
|
@ -4,6 +4,7 @@ use MIME::Base64;
|
|||
|
||||
BEGIN {
|
||||
require 't/test-psgi-lib.pm';
|
||||
require 't/custom.pm';
|
||||
}
|
||||
|
||||
init('Lemonldap::NG::Handler::PSGI');
|
||||
|
@ -39,7 +40,6 @@ ok(
|
|||
'Authentified query'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res, 200 );
|
||||
|
||||
count(2);
|
||||
|
||||
# Denied query
|
||||
|
@ -50,7 +50,6 @@ ok(
|
|||
'Denied query'
|
||||
);
|
||||
ok( $res->[0] == 403, 'Code is 403' ) or explain( $res->[0], 403 );
|
||||
|
||||
count(2);
|
||||
|
||||
# Bad cookie
|
||||
|
@ -67,11 +66,9 @@ ok( $res->[0] == 302, 'Code is 302' ) or explain( $res->[0], 302 );
|
|||
unlink(
|
||||
't/sessions/lock/Apache-Session-e5eec18ebb9bc96352595e2d8ce962e8ecf7af7c9a98cb9a43f9cd181cf4b545.lock'
|
||||
);
|
||||
|
||||
count(2);
|
||||
|
||||
done_testing( count() );
|
||||
|
||||
clean();
|
||||
|
||||
sub Lemonldap::NG::Handler::PSGI::handler {
|
||||
|
|
9
lemonldap-ng-handler/t/custom.pm
Normal file
9
lemonldap-ng-handler/t/custom.pm
Normal file
|
@ -0,0 +1,9 @@
|
|||
package My;
|
||||
|
||||
sub accessToTrace {
|
||||
my $hash = shift;
|
||||
return
|
||||
"$hash->{custom} alias $hash->{params}->[0] $hash->{params}->[1]:$hash->{session}->{groups}";
|
||||
}
|
||||
|
||||
1;
|
|
@ -58,6 +58,9 @@
|
|||
"^/logout": "logout_sso",
|
||||
"default": "accept"
|
||||
},
|
||||
"test4.example.com": {
|
||||
"default": "accept"
|
||||
},
|
||||
"*.example.org": {
|
||||
"^/orgdeny": "deny",
|
||||
"default": "accept"
|
||||
|
@ -80,8 +83,12 @@
|
|||
"userDB": "Demo",
|
||||
"vhostOptions": {
|
||||
"test2.example.com": {
|
||||
"vhostAuthnLevel": 5
|
||||
}
|
||||
"vhostAuthnLevel": 5
|
||||
},
|
||||
"test4.example.com": {
|
||||
"vhostAccessToTrace": "My::accessToTrace, Doctor, Who"
|
||||
}
|
||||
},
|
||||
"whatToTrace": "_whatToTrace"
|
||||
"whatToTrace": "_whatToTrace",
|
||||
"customToTrace": "mail"
|
||||
}
|
||||
|
|
|
@ -4136,6 +4136,10 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
|
|||
'utotp2fLogo' => {
|
||||
'type' => 'text'
|
||||
},
|
||||
'vhostAccessToTrace' => {
|
||||
'default' => '',
|
||||
'type' => 'text'
|
||||
},
|
||||
'vhostAliases' => {
|
||||
'default' => '',
|
||||
'type' => 'text'
|
||||
|
|
|
@ -2227,8 +2227,9 @@ sub attributes {
|
|||
type => 'int',
|
||||
default => -1,
|
||||
},
|
||||
vhostAliases => { type => 'text', default => '' },
|
||||
vhostType => {
|
||||
vhostAccessToTrace => { type => 'text', default => '' },
|
||||
vhostAliases => { type => 'text', default => '' },
|
||||
vhostType => {
|
||||
type => 'select',
|
||||
select => [
|
||||
{ k => 'AuthBasic', v => 'AuthBasic' },
|
||||
|
|
|
@ -27,10 +27,10 @@ sub cTrees {
|
|||
help => 'configvhost.html#options',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'vhostPort', 'vhostHttps',
|
||||
'vhostMaintenance', 'vhostAliases',
|
||||
'vhostType', 'vhostAuthnLevel',
|
||||
'vhostServiceTokenTTL'
|
||||
'vhostPort', 'vhostHttps',
|
||||
'vhostMaintenance', 'vhostAliases',
|
||||
'vhostAccessToTrace', 'vhostType',
|
||||
'vhostAuthnLevel', 'vhostServiceTokenTTL'
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1327,6 +1327,12 @@ function templates(tpl,key) {
|
|||
"id" : tpl+"s/"+key+"/"+"vhostAliases",
|
||||
"title" : "vhostAliases"
|
||||
},
|
||||
{
|
||||
"default" : "",
|
||||
"get" : tpl+"s/"+key+"/"+"vhostAccessToTrace",
|
||||
"id" : tpl+"s/"+key+"/"+"vhostAccessToTrace",
|
||||
"title" : "vhostAccessToTrace"
|
||||
},
|
||||
{
|
||||
"default" : "Main",
|
||||
"get" : tpl+"s/"+key+"/"+"vhostType",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Verify U2F key",
|
||||
"verifyTOTPKey":"Verify TOTP key",
|
||||
"version":"الإصدار",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"اسماء مستعارة",
|
||||
"vhostAuthnLevel":"مستوى إثبات الهوية واجب",
|
||||
"vhostHttps":"إتش تي تي بي س",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Verify U2F key",
|
||||
"verifyTOTPKey":"Verify TOTP key",
|
||||
"version":"Version",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"Aliases",
|
||||
"vhostAuthnLevel":"Required authentication level",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Verify U2F key",
|
||||
"verifyTOTPKey":"Verify TOTP key",
|
||||
"version":"Version",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"Aliases",
|
||||
"vhostAuthnLevel":"Required authentication level",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Vérifier la clef U2F",
|
||||
"verifyTOTPKey":"Vérifier la clef TOTP",
|
||||
"version":"Version",
|
||||
"vhostAccessToTrace":"Accès à tracer",
|
||||
"vhostAliases":"Alias",
|
||||
"vhostAuthnLevel":"Niveau d'authentification requis",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Verifica la chiave U2F",
|
||||
"verifyTOTPKey":"Verifica la chiave TOTP",
|
||||
"version":"Versioni",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"Alias",
|
||||
"vhostAuthnLevel":"Livello di autenticazione richiesto",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Sprawdź klucz U2F",
|
||||
"verifyTOTPKey":"Sprawdź klucz TOTP",
|
||||
"version":"Wersja",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"Aliasy",
|
||||
"vhostAuthnLevel":"Wymagany poziom uwierzytelnienia",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"U2F anahtarını doğrula",
|
||||
"verifyTOTPKey":"TOTP anahtarını doğrula",
|
||||
"version":"Sürüm",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"Takma adlar",
|
||||
"vhostAuthnLevel":"Gereken doğrulama seviyesi",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Verify U2F key",
|
||||
"verifyTOTPKey":"Verify TOTP key",
|
||||
"version":"Phiên bản",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"Bí danh",
|
||||
"vhostAuthnLevel":"Mức xác thực bắt buộc",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
|
@ -1001,6 +1001,7 @@
|
|||
"verifyU2FKey":"Verify U2F key",
|
||||
"verifyTOTPKey":"Verify TOTP key",
|
||||
"version":"Version",
|
||||
"vhostAccessToTrace":"Access to trace",
|
||||
"vhostAliases":"Aliases",
|
||||
"vhostAuthnLevel":"Required authentication level",
|
||||
"vhostHttps":"HTTPS",
|
||||
|
|
Loading…
Reference in New Issue
Block a user