Option to hide empty headers with CheckUser (#2106)

lowercase-endpoints
Christophe Maudoux 5 years ago
parent 8c29111140
commit 8753cc4cf6
  1. 2
      lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Constants.pm
  2. 4
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm
  3. 6
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm
  4. 1
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Tree.pm
  5. 1
      lemonldap-ng-manager/site/htdocs/static/languages/ar.json
  6. 1
      lemonldap-ng-manager/site/htdocs/static/languages/de.json
  7. 1
      lemonldap-ng-manager/site/htdocs/static/languages/en.json
  8. 1
      lemonldap-ng-manager/site/htdocs/static/languages/fr.json
  9. 1
      lemonldap-ng-manager/site/htdocs/static/languages/it.json
  10. 1
      lemonldap-ng-manager/site/htdocs/static/languages/tr.json
  11. 1
      lemonldap-ng-manager/site/htdocs/static/languages/vi.json
  12. 1
      lemonldap-ng-manager/site/htdocs/static/languages/zh.json
  13. 2
      lemonldap-ng-manager/site/htdocs/static/reverseTree.json
  14. 2
      lemonldap-ng-manager/site/htdocs/static/struct.json
  15. 15
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CheckUser.pm
  16. 8
      lemonldap-ng-portal/t/67-CheckUser-with-token.t
  17. 13
      lemonldap-ng-portal/t/67-CheckUser.t
  18. 5
      lemonldap-ng-portal/t/lmConf-1.json

@ -24,7 +24,7 @@ use constant MANAGERSECTION => "manager";
use constant SESSIONSEXPLORERSECTION => "sessionsExplorer";
use constant APPLYSECTION => "apply";
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|AllowOffline|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|o(?:ntextSwitchingStopWithLogout|mpactConf|rsEnabled)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|re(?:st(?:(?:Session|Config)Server|ExportSecretKeys)|freshSessions)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|d(?:isablePersistentStorage|biDynamicHashEnabled)|g(?:roupsBeforeMacros|lobalLogoutTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|AllowOffline|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:Empty(?:Header|Value)s|PersistentInfo))?|State|XSS)|o(?:ntextSwitchingStopWithLogout|mpactConf|rsEnabled)|da)|p(?:ortal(?:Display(?:Re(?:setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|re(?:st(?:(?:Session|Config)Server|ExportSecretKeys)|freshSessions)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|d(?:isablePersistentStorage|biDynamicHashEnabled)|g(?:roupsBeforeMacros|lobalLogoutTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs))$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );

@ -839,6 +839,10 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'default' => 0,
'type' => 'bool'
},
'checkUserDisplayEmptyHeaders' => {
'default' => 0,
'type' => 'bool'
},
'checkUserDisplayEmptyValues' => {
'default' => 0,
'type' => 'bool'

@ -476,6 +476,12 @@ sub attributes {
documentation => 'Display session empty values',
flags => 'p',
},
checkUserDisplayEmptyHeaders => {
default => 0,
type => 'bool',
documentation => 'Display empty headers',
flags => 'p',
},
globalLogoutRule => {
type => 'boolOrExpr',
default => 0,

@ -724,6 +724,7 @@ sub tree {
'checkUserIdRule',
'checkUserHiddenAttributes',
'checkUserSearchAttributes',
'checkUserDisplayEmptyHeaders',
'checkUserDisplayPersistentInfo',
'checkUserDisplayEmptyValues',
]

@ -188,6 +188,7 @@
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"السمات المخفية",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyHeaders":"Display empty headers",
"checkUserDisplayEmptyValues":"Display empty values",
"checkUserSearchAttributes":"Attributes used for searching sessions",
"choiceParams":"اختيارالإعدادات",

@ -188,6 +188,7 @@
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyheaders":"Display empty headers",
"checkUserDisplayEmptyValues":"Display empty values",
"checkUserSearchAttributes":"Attributes used for searching sessions",
"choiceParams":"Choice parameters",

@ -188,6 +188,7 @@
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyHeaders":"Display empty headers",
"checkUserDisplayEmptyValues":"Display empty values",
"checkUserSearchAttributes":"Attributes used for searching sessions",
"choiceParams":"Choice parameters",

@ -188,6 +188,7 @@
"checkUserIdRule":"Règle d'utilisation des identités",
"checkUserHiddenAttributes":"Attributs masqués",
"checkUserDisplayPersistentInfo":"Afficher les données de session persistante",
"checkUserDisplayEmptyHeaders":"Afficher les entêtes nuls",
"checkUserDisplayEmptyValues":"Afficher les valeurs nulles",
"checkUserSearchAttributes":"Attributs utilisés pour rechercher les sessions",
"choiceParams":"Paramètres des choix",

@ -188,6 +188,7 @@
"checkUserIdRule":"Uso della regola delle identità",
"checkUserHiddenAttributes":"Attributi nascosti",
"checkUserDisplayPersistentInfo":"Mostra sessione persistente",
"checkUserDisplayEmptyHeaders":"Display empty headers",
"checkUserDisplayEmptyValues":"Mostra valori vuoti",
"checkUserSearchAttributes":"Attributes used for searching sessions",
"choiceParams":"Scelta parametri",

@ -188,6 +188,7 @@
"checkUserIdRule":"Kimlik kullanım kuralı",
"checkUserHiddenAttributes":"Gizli nitelikler",
"checkUserDisplayPersistentInfo":"Kalıcı oturumu görüntüle",
"checkUserDisplayEmptyHeaders":"Display empty headers",
"checkUserDisplayEmptyValues":"Boş değerleri görüntüle",
"checkUserSearchAttributes":"Arama oturumlarında kullanılan nitelikler",
"choiceParams":"Tercih parametreleri",

@ -188,6 +188,7 @@
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Thuộc tính ẩn",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyHeaders":"Display empty headers",
"checkUserDisplayEmptyValues":"Display empty values",
"checkUserSearchAttributes":"Attributes used for searching sessions",
"choiceParams":"Các tham số lựa chọn",

@ -188,6 +188,7 @@
"checkUserIdRule":"Identities use rule",
"checkUserHiddenAttributes":"Hidden attributes",
"checkUserDisplayPersistentInfo":"Display persistent session",
"checkUserDisplayEmptyHeaders":"Display empty headers",
"checkUserDisplayEmptyValues":"Display empty values",
"checkUserSearchAttributes":"Attributes used for searching sessions",
"choiceParams":"Choice parameters",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -441,7 +441,14 @@ sub _headers {
$self->p->HANDLER->headersInit( $self->{conf} );
$self->logger->debug(
"Return \"$attrs->{ $self->{conf}->{whatToTrace} }\" headers");
return $self->p->HANDLER->checkHeaders( $req, $attrs );
return $self->p->HANDLER->checkHeaders( $req, $attrs )
if ( $self->conf->{checkUserDisplayEmptyHeaders} );
$self->logger->debug("Remove empty headers");
my @headers = grep $_->{value} =~ /.+/,
@{ $self->p->HANDLER->checkHeaders( $req, $attrs ) };
return \@headers;
}
sub _splitAttributes {
@ -457,7 +464,7 @@ sub _splitAttributes {
if ( $element->{key} eq 'groups' ) {
$self->logger->debug('Key "groups" found');
my $separator = $self->{conf}->{multiValuesSeparator};
my @tmp = split /\Q$separator/, $element->{value};
my @tmp = split /\Q$separator/, $element->{value};
$grps = [ map { { value => $_ } } sort @tmp ];
next;
}
@ -500,8 +507,8 @@ sub _splitAttributes {
sub _removePersistentAttributes {
my ( $self, $attrs ) = @_;
my $regex = join '|', split /\s+/, $self->persistentAttrs;
my @keys = grep /$regex/, keys %$attrs;
my $regex = join '|', split /\s+/, $self->persistentAttrs;
my @keys = grep /$regex/, keys %$attrs;
$self->logger->debug("Remove persistent session attributes");
delete @$attrs{@keys};

@ -125,6 +125,12 @@ ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
or explain( $res->[2]->[0], 'trspan="macros"' );
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
ok( $res->[2]->[0] =~ m%testHeader1: %, 'Found testHeader1' )
or explain( $res->[2]->[0], 'Header Key: testHeader1' );
ok( $res->[2]->[0] =~ m%testHeader2: %, 'Found testHeader2' )
or explain( $res->[2]->[0], 'Header Key: testHeader2' );
ok( $res->[2]->[0] !~ m%emptyHeader: %, 'emptyHeader not found' )
or explain( $res->[2]->[0], 'Header Key: emptyHeader' );
ok( $res->[2]->[0] =~ m%: rtyler%, 'Found rtyler' )
or explain( $res->[2]->[0], 'Header Value: rtyler' );
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
@ -134,7 +140,7 @@ ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
'Found _whatToTrace' )
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
count(11);
count(14);
$query =~ s/user=dwho/user=msmith/;
$query =~

@ -21,6 +21,7 @@ my $client = LLNG::Manager::Test->new( {
checkUserIdRule => '$uid ne "msmith"',
checkUserSearchAttributes => 'employee_nbr test1 _user test2 mail',
checkUserDisplayPersistentInfo => 1,
checkUserDisplayEmptyHeaders => 1,
checkUserDisplayEmptyValues => 1,
totp2fSelfRegistration => 1,
totp2fActivation => 1,
@ -222,16 +223,20 @@ ok(
),
'POST checkuser'
);
count(1);
( $host, $url, $query ) =
expectForm( $res, undef, '/checkuser', 'user', 'url' );
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
or explain( $res->[2]->[0], 'trspan="checkUser"' );
count(2);
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
ok( $res->[2]->[0] =~ m%testHeader1: %, 'Found testHeader1' )
or explain( $res->[2]->[0], 'Header Key: testHeader1' );
ok( $res->[2]->[0] =~ m%testHeader2: %, 'Found testHeader2' )
or explain( $res->[2]->[0], 'Header Key: testHeader2' );
ok( $res->[2]->[0] =~ m%emptyHeader: %, 'Found emptyHeader' )
or explain( $res->[2]->[0], 'Header Key: emptyHeader' );
ok( $res->[2]->[0] =~ m%: dwho<br/>%, 'Found dwho' )
or explain( $res->[2]->[0], 'Header Value: dwho' );
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
@ -239,7 +244,7 @@ ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
ok( $res->[2]->[0] =~ m%<td scope="row">dwho</td>%, 'Found dwho' )
or explain( $res->[2]->[0], 'Macro Value dwho' );
count(3);
count(7);
# Request with mail
$query =~ s/user=dwho/user=dwho%40badwolf.org/;

@ -14,7 +14,10 @@
"domain": "example.com",
"exportedHeaders": {
"test1.example.com": {
"Auth-User": "$uid"
"Auth-User": "$uid",
"testHeader1": "testHeader_value",
"testHeader2": "' '",
"emptyHeader": "''"
},
"test2.example.com": {
"Auth-User": "$uid"

Loading…
Cancel
Save