Merge branch 'v2.0' into 2952

2952
Christophe Maudoux 2 years ago
commit c2fbe31800
  1. 8
      doc/sources/admin/authldap.rst
  2. 26
      doc/sources/admin/upgrade_2_x.rst
  3. 66
      lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/DefaultValues.pm
  4. 4
      lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/RESTServer.pm
  5. 2
      lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/ReConstants.pm
  6. 31
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Attributes.pm
  7. 4
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Attributes.pm
  8. 1
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Build/Tree.pm
  9. 2
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/Conf/Tests.pm
  10. 3
      lemonldap-ng-manager/site/htdocs/static/js/conftree.min.js
  11. 2
      lemonldap-ng-manager/site/htdocs/static/js/conftree.min.js.map
  12. 3
      lemonldap-ng-manager/site/htdocs/static/languages/ar.json
  13. 1
      lemonldap-ng-manager/site/htdocs/static/languages/en.json
  14. 3
      lemonldap-ng-manager/site/htdocs/static/languages/es.json
  15. 1
      lemonldap-ng-manager/site/htdocs/static/languages/fr.json
  16. 3
      lemonldap-ng-manager/site/htdocs/static/languages/he.json
  17. 3
      lemonldap-ng-manager/site/htdocs/static/languages/it.json
  18. 3
      lemonldap-ng-manager/site/htdocs/static/languages/pl.json
  19. 3
      lemonldap-ng-manager/site/htdocs/static/languages/pt.json
  20. 3
      lemonldap-ng-manager/site/htdocs/static/languages/pt_BR.json
  21. 3
      lemonldap-ng-manager/site/htdocs/static/languages/ru.json
  22. 3
      lemonldap-ng-manager/site/htdocs/static/languages/tr.json
  23. 3
      lemonldap-ng-manager/site/htdocs/static/languages/vi.json
  24. 3
      lemonldap-ng-manager/site/htdocs/static/languages/zh.json
  25. 3
      lemonldap-ng-manager/site/htdocs/static/languages/zh_TW.json
  26. 2
      lemonldap-ng-manager/site/htdocs/static/reverseTree.json
  27. 2
      lemonldap-ng-manager/site/htdocs/static/struct.json
  28. 2
      lemonldap-ng-portal/MANIFEST
  29. 4
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Choice.pm
  30. 5
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/Net/LDAP.pm
  31. 12
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Display.pm
  32. 7
      lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm
  33. 2
      lemonldap-ng-portal/site/templates/bootstrap/passwordpolicy.tpl
  34. 2
      lemonldap-ng-portal/site/templates/common/script.tpl
  35. 2
      lemonldap-ng-portal/t/02-Password-Demo-Local-Ppolicy.t
  36. 63
      lemonldap-ng-portal/t/21-Auth-LDAP-group-with-group-filter.t
  37. 63
      lemonldap-ng-portal/t/21-Auth-LDAP-group-without-group-filter.t
  38. 2
      lemonldap-ng-portal/t/43-MailPasswordReset.t
  39. 7
      lemonldap-ng-portal/t/testslapd/users.ldif

@ -154,8 +154,12 @@ Groups
- **Search base**: DN of groups branch. If no value, disable group
searching.
- **Object class**: objectClass of the groups (default: groupOfNames).
If you are using Active Directory you need to modify this value to ``group``.
- **Group Filter**: LDAP filter for groups, can be used to have several
group object classes (for example ``(|(objectClass=groupOfNames)(objectClass=groupOfURLs))``).
If this value is empty, the **Object class** parameter is used to build the filter.
- **Object class**: objectClass of the groups (default: ``groupOfNames``).
If you are using Active Directory you need to modify this value to ``group``.
This parameter is ignored if **Group filter** is set.
- **Target attribute**: name of the attribute in the groups storing the
link to the user (default: member).
- **User source attribute**: name of the attribute in users entries

@ -52,9 +52,11 @@ However, restoring previous behavior is not recommended, as you are likely to ru
even more encoding bugs in the long run.
Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~
Font Awesome application icons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It is now possible to use Font Awesome icons in the application menu.
@ -81,6 +83,28 @@ If you modified the default ``menu.tpl`` template, you need to update it:
If you are using the default templates from the ``bootstrap`` theme, you don't need to change anything.
Password policy
^^^^^^^^^^^^^^^
It is recommended to update your theme's ``passwordpolicy.tpl`` to correctly display special characters in password policies
::
--- a/lemonldap-ng-portal/site/templates/bootstrap/passwordpolicy.tpl
+++ b/lemonldap-ng-portal/site/templates/bootstrap/passwordpolicy.tpl
@@ -34,7 +34,7 @@
<TMPL_IF NAME="PPOLICY_ALLOWEDSPECHAR">
<li>
<i id="ppolicy-allowedspechar-feedback" class="fa fa-li"> </i>
- <span trspan="passwordPolicySpecialChar">Allowed special characters:</span> <TMPL_VAR NAME="PPOLICY_ALLOWEDSPECHAR">
+ <span trspan="passwordPolicySpecialChar">Allowed special characters:</span> <TMPL_VAR NAME="PPOLICY_ALLOWEDSPECHAR" ESCAPE="html">
</li>
</TMPL_IF>
<TMPL_IF NAME="ENABLE_CHECKHIBP">
If you are using the default templates from the ``bootstrap`` theme, you don't need to change anything.
2.16.1
--------

@ -17,21 +17,21 @@ sub defaultValues {
},
'authChoiceParam' => 'lmAuth',
'authentication' => 'Demo',
'available2F' =>
'available2F' =>
'UTOTP,TOTP,U2F,REST,Mail2F,Ext2F,WebAuthn,Yubikey,Radius,Password',
'available2FSelfRegistration' => 'Password,TOTP,U2F,WebAuthn,Yubikey',
'bruteForceProtectionLockTimes' => '15, 30, 60, 300, 600',
'bruteForceProtectionMaxAge' => 300,
'bruteForceProtectionMaxFailed' => 3,
'bruteForceProtectionMaxLockTime' => 900,
'bruteForceProtectionTempo' => 30,
'captcha_mail_enabled' => 1,
'captcha_register_enabled' => 1,
'captcha_size' => 6,
'casAccessControlPolicy' => 'none',
'casAuthnLevel' => 1,
'casTicketExpiration' => 0,
'certificateResetByMailCeaAttribute' => 'description',
'bruteForceProtectionMaxLockTime' => 900,
'bruteForceProtectionTempo' => 30,
'captcha_mail_enabled' => 1,
'captcha_register_enabled' => 1,
'captcha_size' => 6,
'casAccessControlPolicy' => 'none',
'casAuthnLevel' => 1,
'casTicketExpiration' => 0,
'certificateResetByMailCeaAttribute' => 'description',
'certificateResetByMailCertificateAttribute' =>
'userCertificate;binary',
'certificateResetByMailValidityDelay' => 0,
@ -103,7 +103,7 @@ sub defaultValues {
'globalLogoutTimer' => 1,
'globalStorage' => 'Apache::Session::File',
'globalStorageOptions' => {
'Directory' => '/var/lib/lemonldap-ng/sessions/',
'Directory' => '/var/lib/lemonldap-ng/sessions/',
'generateModule' =>
'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
@ -181,18 +181,18 @@ sub defaultValues {
'lwpOpts' => {
'timeout' => 10
},
'macros' => {},
'mail2fActivation' => 0,
'mail2fCodeRegex' => '\\d{6}',
'mailCharset' => 'utf-8',
'mailFrom' => 'noreply@example.com',
'mailSessionKey' => 'mail',
'mailTimeout' => 0,
'managerDn' => '',
'managerPassword' => '',
'max2FDevices' => 10,
'max2FDevicesNameLength' => 20,
'multiValuesSeparator' => '; ',
'macros' => {},
'mail2fActivation' => 0,
'mail2fCodeRegex' => '\\d{6}',
'mailCharset' => 'utf-8',
'mailFrom' => 'noreply@example.com',
'mailSessionKey' => 'mail',
'mailTimeout' => 0,
'managerDn' => '',
'managerPassword' => '',
'max2FDevices' => 10,
'max2FDevicesNameLength' => 20,
'multiValuesSeparator' => '; ',
'mySessionAuthorizedRWKeys' =>
[ '_appsListOrder', '_oidcConnectedRP', '_oidcConsents' ],
'newLocationWarningLocationAttribute' => 'ipAddr',
@ -200,7 +200,7 @@ sub defaultValues {
'newLocationWarningMaxValues' => '0',
'notificationDefaultCond' => '',
'notificationServerPOST' => 1,
'notificationServerSentAttributes' =>
'notificationServerSentAttributes' =>
'uid reference date title subtitle text check',
'notificationsMaxRetrieve' => 3,
'notificationStorage' => 'File',
@ -257,7 +257,7 @@ sub defaultValues {
'passwordPolicyMinUpper' => 0,
'passwordPolicySpecialChar' => '__ALL__',
'passwordResetAllowedRetries' => 3,
'persistentSessionAttributes' =>
'persistentSessionAttributes' =>
'_loginHistory _2fDevices _oidcConsents notification_',
'port' => -1,
'portal' => 'http://auth.example.com/',
@ -268,7 +268,7 @@ sub defaultValues {
'portalDisplayGeneratePassword' => 1,
'portalDisplayLoginHistory' => 1,
'portalDisplayLogout' => 1,
'portalDisplayOidcConsents' =>
'portalDisplayOidcConsents' =>
'$_oidcConsents && $_oidcConsents =~ /\\w+/',
'portalDisplayOrder' =>
'Appslist ChangePassword LoginHistory OidcConsents Logout',
@ -305,11 +305,11 @@ sub defaultValues {
'http://auth.example.com/Lemonldap/NG/Common/PSGI/SOAPService',
'proxy' => 'http://auth.example.com/sessions'
},
'requireToken' => 1,
'rest2fActivation' => 0,
'restAuthnLevel' => 2,
'restClockTolerance' => 15,
'sameSite' => '',
'requireToken' => 1,
'rest2fActivation' => 0,
'restAuthnLevel' => 2,
'restClockTolerance' => 15,
'sameSite' => '',
'samlAttributeAuthorityDescriptorAttributeServiceSOAP' =>
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;',
'samlAuthnContextMapKerberos' => 4,
@ -349,7 +349,7 @@ sub defaultValues {
'0;1;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/proxySingleSignOnArtifact',
'samlSPSSODescriptorAssertionConsumerServiceHTTPPost' =>
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleSignOnPost',
'samlSPSSODescriptorAuthnRequestsSigned' => 1,
'samlSPSSODescriptorAuthnRequestsSigned' => 1,
'samlSPSSODescriptorSingleLogoutServiceHTTPPost' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'samlSPSSODescriptorSingleLogoutServiceHTTPRedirect' =>
@ -362,7 +362,7 @@ sub defaultValues {
'sfEngine' => '::2F::Engines::Default',
'sfManagerRule' => 1,
'sfRemovedMsgRule' => 0,
'sfRemovedNotifMsg' =>
'sfRemovedNotifMsg' =>
'_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
'sfRemovedNotifRef' => 'RemoveSF',
'sfRemovedNotifTitle' => 'Second factor notification',

@ -582,7 +582,7 @@ sub authChoiceModules {
unless ($key) {
my @res;
foreach my $k ( sort keys %$value ) {
my $data = [ split /;/, $value->{$k} ];
my $data = [ split /;\s*/, $value->{$k} ];
if ( $data->[5] ) {
my $over;
eval { $over = from_json( $data->[5] ) };
@ -605,7 +605,7 @@ sub authChoiceModules {
return $self->sendJSONresponse( $req, \@res );
}
else {
my $r = $value->{$key} ? [ split( /[;\|]/, $value->{$key} ) ] : [];
my $r = $value->{$key} ? [ split( /;\s*/, $value->{$key} ) ] : [];
return $self->sendJSONresponse( $req, { value => $r } );
}
}

@ -45,7 +45,7 @@ our $authParameters = {
githubParams => [qw(githubAuthnLevel githubClientID githubClientSecret githubUserField githubScope)],
gpgParams => [qw(gpgAuthnLevel gpgDb)],
kerberosParams => [qw(krbAuthnLevel krbKeytab krbByJs krbRemoveDomain krbAllowedDomains)],
ldapParams => [qw(ldapAuthnLevel ldapExportedVars ldapServer ldapPort ldapVerify ldapBase managerDn managerPassword ldapTimeout ldapIOTimeout ldapVersion ldapRaw ldapCAFile ldapCAPath LDAPFilter AuthLDAPFilter mailLDAPFilter ldapSearchDeref ldapGroupBase ldapGroupObjectClass ldapGroupAttributeName ldapGroupAttributeNameUser ldapGroupAttributeNameSearch ldapGroupDecodeSearchedValue ldapGroupRecursive ldapGroupAttributeNameGroup ldapPpolicyControl ldapSetPassword ldapChangePasswordAsUser ldapPwdEnc ldapUsePasswordResetAttribute ldapPasswordResetAttribute ldapPasswordResetAttributeValue ldapAllowResetExpiredPassword ldapGetUserBeforePasswordChange ldapITDS)],
ldapParams => [qw(ldapAuthnLevel ldapExportedVars ldapServer ldapPort ldapVerify ldapBase managerDn managerPassword ldapTimeout ldapIOTimeout ldapVersion ldapRaw ldapCAFile ldapCAPath LDAPFilter AuthLDAPFilter mailLDAPFilter ldapSearchDeref ldapGroupBase groupLDAPFilter ldapGroupObjectClass ldapGroupAttributeName ldapGroupAttributeNameUser ldapGroupAttributeNameSearch ldapGroupDecodeSearchedValue ldapGroupRecursive ldapGroupAttributeNameGroup ldapPpolicyControl ldapSetPassword ldapChangePasswordAsUser ldapPwdEnc ldapUsePasswordResetAttribute ldapPasswordResetAttribute ldapPasswordResetAttributeValue ldapAllowResetExpiredPassword ldapGetUserBeforePasswordChange ldapITDS)],
linkedinParams => [qw(linkedInAuthnLevel linkedInClientID linkedInClientSecret linkedInFields linkedInUserField linkedInScope)],
nullParams => [qw(nullAuthnLevel)],
oidcParams => [qw(oidcAuthnLevel oidcRPCallbackGetParam oidcRPStateTimeout)],

@ -67,7 +67,7 @@ sub types {
'hostname' => {
'form' => 'text',
'msgFail' => '__badHostname__',
'test' =>
'test' =>
qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))?$/
},
'int' => {
@ -261,7 +261,7 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\
'url' => {
'form' => 'text',
'msgFail' => '__badUrl__',
'test' =>
'test' =>
qr/(?:^$|(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::(?:(?:[0-9]*)))?(?:\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:\/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?](?:(?:(?:[;\/?:@&=+\$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?))/
}
};
@ -839,7 +839,7 @@ sub attributes {
},
'casSrvMetaDataOptionsUrl' => {
'msgFail' => '__badUrl__',
'test' =>
'test' =>
qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::(?:(?:[0-9]*)))?(?:\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:\/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?](?:(?:(?:[;\/?:@&=+\$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?)/,
'type' => 'text'
},
@ -1393,7 +1393,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'domain' => {
'default' => 'example.com',
'msgFail' => '__badDomainName__',
'test' =>
'test' =>
qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?))?$/,
'type' => 'text'
},
@ -1539,7 +1539,7 @@ qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-
},
'globalStorageOptions' => {
'default' => {
'Directory' => '/var/lib/lemonldap-ng/sessions/',
'Directory' => '/var/lib/lemonldap-ng/sessions/',
'generateModule' =>
'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
@ -1564,6 +1564,9 @@ qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-
},
'type' => 'grantContainer'
},
'groupLDAPFilter' => {
'type' => 'text'
},
'groups' => {
'default' => {},
'test' => sub {
@ -1664,7 +1667,7 @@ qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-
'issuerDBGetParameters' => {
'default' => {},
'keyMsgFail' => '__badHostname__',
'keyTest' =>
'keyTest' =>
qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)$/,
'test' => {
'keyMsgFail' => '__badKeyName__',
@ -2958,7 +2961,7 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'pdataDomain' => {
'default' => '',
'msgFail' => '__badDomainName__',
'test' =>
'test' =>
qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?))?$/,
'type' => 'text'
},
@ -2979,7 +2982,7 @@ qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-
'portal' => {
'default' => 'http://auth.example.com/',
'msgFail' => '__badUrl__',
'test' =>
'test' =>
qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::(?:(?:[0-9]*)))?(?:\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:\/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?](?:(?:(?:[;\/?:@&=+\$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?)/,
'type' => 'url'
},
@ -3326,7 +3329,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'keyTest' =>
qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+))(?::\d+)?$/,
'msgFail' => '__badUrl__',
'test' =>
'test' =>
qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::(?:(?:[0-9]*)))?(?:\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:\/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?](?:(?:(?:[;\/?:@&=+\$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?)/,
'type' => 'keyTextContainer'
},
@ -3506,19 +3509,19 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlCommonDomainCookieDomain' => {
'msgFail' => '__badDomainName__',
'test' =>
'test' =>
qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)$/,
'type' => 'text'
},
'samlCommonDomainCookieReader' => {
'msgFail' => '__badUrl__',
'test' =>
'test' =>
qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::(?:(?:[0-9]*)))?(?:\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:\/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?](?:(?:(?:[;\/?:@&=+\$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?)/,
'type' => 'text'
},
'samlCommonDomainCookieWriter' => {
'msgFail' => '__badUrl__',
'test' =>
'test' =>
qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::(?:(?:[0-9]*)))?(?:\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:\/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?](?:(?:(?:[;\/?:@&=+\$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?)/,
'type' => 'text'
},
@ -3535,7 +3538,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlDiscoveryProtocolURL' => {
'msgFail' => '__badUrl__',
'test' =>
'test' =>
qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)))(?::(?:(?:[0-9]*)))?(?:\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*)(?:\/(?:(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)(?:;(?:(?:[a-zA-Z0-9\-_.!~*'():@&=+\$,]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*))*))*))(?:[?](?:(?:(?:[;\/?:@&=+\$,a-zA-Z0-9\-_.!~*'()]+|(?:%[a-fA-F0-9][a-fA-F0-9]))*)))?))?)/,
'type' => 'text'
},
@ -4354,7 +4357,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'SMTPServer' => {
'default' => '',
'test' =>
'test' =>
qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)|(?:[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+))(?::\d+)?)?$/,
'type' => 'text'
},

@ -3731,6 +3731,10 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
type => 'text',
documentation => 'LDAP filter for auth search'
},
groupLDAPFilter => {
type => 'text',
documentation => 'LDAP filter for group search'
},
ldapGroupDecodeSearchedValue => {
default => 0,
type => 'bool',

@ -284,6 +284,7 @@ sub tree {
form => 'simpleInputContainer',
nodes => [
'ldapGroupBase',
'groupLDAPFilter',
'ldapGroupObjectClass',
'ldapGroupAttributeName',
'ldapGroupAttributeNameUser',

@ -1021,7 +1021,7 @@ sub tests {
{
my $hasPwdBE = 0;
foreach ( keys %{ $conf->{authChoiceModules} } ) {
my @mods = split /[;\|]/, $conf->{authChoiceModules}->{$_};
my @mods = split /;\s*/, $conf->{authChoiceModules}->{$_};
$hasPwdBE ||= 1 unless $mods[2] eq 'Null';
}
return ( -1,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -404,6 +404,7 @@
"gpgDb":"GPG database",
"gpgParams":"GPG parameters",
"grantSessionRules":"ظروف الافتتاح",
"groupLDAPFilter":"Group Filter",
"groups":"المجموعات",
"groupsBeforeMacros":"Compute groups before macros",
"hGroups":"المجموعات (هاش ريف)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"خدمة أل يو أر ل",
"yubikey2fUserCanRemoveKey":"Allow user to remove Yubikey",
"zeroConfExplanations":"لا يحتوي الخادم على إعدادات. استخدام قالب لحفظ الأول"
}
}

@ -404,6 +404,7 @@
"gpgDb":"GPG database",
"gpgParams":"GPG parameters",
"grantSessionRules":"Opening conditions",
"groupLDAPFilter":"Group Filter",
"groups":"Groups",
"groupsBeforeMacros":"Compute groups before macros",
"hGroups":"Groups (HashRef)",

@ -404,6 +404,7 @@
"gpgDb":"Base de datos GPS",
"gpgParams":"Parámetros GPS",
"grantSessionRules":"Condiciones de apertura",
"groupLDAPFilter":"Group Filter",
"groups":"Grupos",
"groupsBeforeMacros":"Método para formulario de información",
"hGroups":"Groups (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"URL de servicio",
"yubikey2fUserCanRemoveKey":"Allow user to remove Yubikey",
"zeroConfExplanations":"Server has no configuration. Use template to save the first."
}
}

@ -404,6 +404,7 @@
"gpgDb":"Base de données GPG",
"gpgParams":"Paramètres GPG",
"grantSessionRules":"Conditions d'ouverture",
"groupLDAPFilter":"Filtre pour les groupes",
"groups":"Groupes",
"groupsBeforeMacros":"Calculer les groupes avant les macros",
"hGroups":"Groupes (HashRef)",

@ -404,6 +404,7 @@
"gpgDb":"מסד נתוני GPG",
"gpgParams":"משתני GPG",
"grantSessionRules":"תנאי פתיחה",
"groupLDAPFilter":"Group Filter",
"groups":"קבוצות",
"groupsBeforeMacros":"לחשב את הקבוצות לפני תסריטי המאקרו",
"hGroups":"קבוצות (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"כתובת שירות",
"yubikey2fUserCanRemoveKey":"לאפשר למשתמש להסיר Yubikey",
"zeroConfExplanations":"Server has no configuration. Use template to save the first."
}
}

@ -404,6 +404,7 @@
"gpgDb":"Database GPG",
"gpgParams":"Parametri GPG",
"grantSessionRules":"Condizioni di apertura",
"groupLDAPFilter":"Group Filter",
"groups":"Gruppi",
"groupsBeforeMacros":"Compute groups before macros",
"hGroups":"Gruppi (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"URL del servizio",
"yubikey2fUserCanRemoveKey":"Autorizza l'utente a rimuovere la Yubikey",
"zeroConfExplanations":"Il server non ha alcuna configurazione. Utilizza il modello per salvare il primo."
}
}

@ -404,6 +404,7 @@
"gpgDb":"Baza danych GPG",
"gpgParams":"Parametry GPG",
"grantSessionRules":"Warunki otwarcia",
"groupLDAPFilter":"Group Filter",
"groups":"Grupy",
"groupsBeforeMacros":"Oblicz grupy przed makrami",
"hGroups":"Grupy (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"URL usługi",
"yubikey2fUserCanRemoveKey":"Pozwól użytkownikowi usunąć Yubikey",
"zeroConfExplanations":"Serwer nie ma konfiguracji. Użyj szablonu, aby zapisać pierwszy."
}
}

@ -404,6 +404,7 @@
"gpgDb":"Banco de dados GPG",
"gpgParams":"Parâmetros GPG",
"grantSessionRules":"Condições de abertura",
"groupLDAPFilter":"Group Filter",
"groups":"Grupos",
"groupsBeforeMacros":"Computar grupos antes de macros",
"hGroups":"Grupos (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"URL do serviço",
"yubikey2fUserCanRemoveKey":"Permitir que usuário remova o Yubikey",
"zeroConfExplanations":"O servidor não tem configuração. Use o modelo para salvar a primeira"
}
}

@ -404,6 +404,7 @@
"gpgDb":"Banco de dados GPG",
"gpgParams":"Parâmetros GPG",
"grantSessionRules":"Condições de abertura",
"groupLDAPFilter":"Group Filter",
"groups":"Grupos",
"groupsBeforeMacros":"Computar grupos antes de macros",
"hGroups":"Grupos (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"URL do serviço",
"yubikey2fUserCanRemoveKey":"Permitir que usuário remova o Yubikey",
"zeroConfExplanations":"O servidor não tem configuração. Use o modelo para salvar a primeira"
}
}

@ -404,6 +404,7 @@
"gpgDb":"База данных GPG",
"gpgParams":"Параметры GPG",
"grantSessionRules":"Условия открытия",
"groupLDAPFilter":"Group Filter",
"groups":"Группы",
"groupsBeforeMacros":"Вычислять группы перед макросами",
"hGroups":"Группы (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"URL службы",
"yubikey2fUserCanRemoveKey":"Разрешить пользователю удалять Yubikey",
"zeroConfExplanations":"Сервер не имеет конфигурации. Используйте шаблон, чтобы создать ее."
}
}

@ -404,6 +404,7 @@
"gpgDb":"GPG veritabanı",
"gpgParams":"GPG parametreleri",
"grantSessionRules":"Açılış koşulları",
"groupLDAPFilter":"Group Filter",
"groups":"Gruplar",
"groupsBeforeMacros":"Grupları makrolardan önce hesapla",
"hGroups":"Gruplar (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"Servis URL'si",
"yubikey2fUserCanRemoveKey":"Yubikey'i kaldırmak için kullanıcıya izin ver",
"zeroConfExplanations":"Sunucunun yapılandırması yok. Şimdi bir tane kaydetmek için şablonu kullanın."
}
}

@ -404,6 +404,7 @@
"gpgDb":"cơ sở dữ liệu GPG",
"gpgParams":"Tham số GPG",
"grantSessionRules":"Điều kiện mở",
"groupLDAPFilter":"Group Filter",
"groups":"Nhóm",
"groupsBeforeMacros":"Tính toán các nhóm trước macros",
"hGroups":"Nhóm (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"Dịch vụ URL",
"yubikey2fUserCanRemoveKey":"Cho phép người dùng xóa Yubikey",
"zeroConfExplanations":"Máy chủ không có cấu hình. Sử dụng mẫu để lưu đầu tiên. "
}
}

@ -404,6 +404,7 @@
"gpgDb":"GPG 資料庫",
"gpgParams":"GPG 參數",
"grantSessionRules":"開啟條件",
"groupLDAPFilter":"Group Filter",
"groups":"群組",
"groupsBeforeMacros":"在巨集前計算群組",
"hGroups":"群組 (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"服務 URL",
"yubikey2fUserCanRemoveKey":"允許使用者移除 Yubikey",
"zeroConfExplanations":"伺服器未設定。使用飯本來儲存第一個。"
}
}

@ -404,6 +404,7 @@
"gpgDb":"GPG 資料庫",
"gpgParams":"GPG 參數",
"grantSessionRules":"開啟條件",
"groupLDAPFilter":"Group Filter",
"groups":"群組",
"groupsBeforeMacros":"在巨集前計算群組",
"hGroups":"群組 (HashRef)",
@ -1327,4 +1328,4 @@
"yubikey2fUrl":"服務 URL",
"yubikey2fUserCanRemoveKey":"允許使用者移除 Yubikey",
"zeroConfExplanations":"伺服器未設定。使用飯本來儲存第一個。"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -569,6 +569,8 @@ t/20-Auth-and-password-DBI.t
t/20-Auth-DBI-utf8.t
t/21-Auth-and-password-LDAP.t
t/21-Auth-LDAP-attributes.t
t/21-Auth-LDAP-group-with-group-filter.t
t/21-Auth-LDAP-group-without-group-filter.t
t/21-Auth-LDAP-Policy-Combination.t
t/21-Auth-LDAP-Policy-only.t
t/21-Auth-LDAP-Policy.t

@ -36,7 +36,7 @@ sub init {
foreach my $name ( keys %{ $self->conf->{authChoiceModules} } ) {
my @mods =
split( /[;\|]/, $self->conf->{authChoiceModules}->{$name} );
split( /;\s*/, $self->conf->{authChoiceModules}->{$name} );
my $module = '::'
. [ 'Auth', 'UserDB', 'Password' ]->[$type] . '::'
. $mods[$type];
@ -219,7 +219,7 @@ sub _buildAuthLoop {
# Find modules associated to authChoice
my ( $auth, $userDB, $passwordDB, $url, $condition ) =
split( /[;\|]/, $self->conf->{authChoiceModules}->{$_} );
split( /;\s*/, $self->conf->{authChoiceModules}->{$_} );
unless ( $_choiceRules->{$_} ) {
$self->logger->error("$_ has no rule");

@ -20,7 +20,7 @@ use Net::LDAP qw(LDAP_PP_PASSWORD_EXPIRED LDAP_PP_ACCOUNT_LOCKED
use utf8;
our $VERSION = '2.0.15';
our $VERSION = '2.17.0';
# INITIALIZATION
@ -659,8 +659,9 @@ sub searchGroups {
my $groups = {};
# Creating search filter
my $groupSearchFilter = $self->{conf}->{groupLDAPFilter} || "(objectClass=" . $self->{conf}->{ldapGroupObjectClass} . ")";
my $searchFilter =
"(&(objectClass=" . $self->{conf}->{ldapGroupObjectClass} . ")(|";
"(&" . $groupSearchFilter . "(|";
foreach ( split( $self->{conf}->{multiValuesSeparator}, $value ) ) {
$searchFilter .= "(" . $key . "=" . escape_filter_value($_) . ")";
}

@ -318,7 +318,11 @@ sub display {
),
(
$self->conf->{passwordPolicyMinSpeChar} || $self->speChars()
? ( PPOLICY_ALLOWEDSPECHAR => $self->speChars() )
? (
PPOLICY_ALLOWEDSPECHAR => $self->speChars(),
PPOLICY_ALLOWEDSPECHAR_JSON =>
to_json( $self->speChars(), { allow_nonref => 1 } ),
)
: ()
),
(
@ -556,7 +560,11 @@ sub display {
),
(
$self->conf->{passwordPolicyMinSpeChar} || $self->speChars()
? ( PPOLICY_ALLOWEDSPECHAR => $self->speChars() )
? (
PPOLICY_ALLOWEDSPECHAR => $self->speChars(),
PPOLICY_ALLOWEDSPECHAR_JSON =>
to_json( $self->speChars(), { allow_nonref => 1 } ),
)
: ()
),
);

@ -4,6 +4,7 @@ use strict;
use Encode;
use Mouse;
use POSIX qw(strftime);
use JSON;
use Lemonldap::NG::Common::FormEncode;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
@ -631,8 +632,10 @@ sub display {
PPOLICY_MINLOWER => $self->conf->{passwordPolicyMinLower},
PPOLICY_MINUPPER => $self->conf->{passwordPolicyMinUpper},
PPOLICY_MINDIGIT => $self->conf->{passwordPolicyMinDigit},
PPOLICY_MINSPECHAR => $self->conf->{passwordPolicyMinSpeChar},
PPOLICY_ALLOWEDSPECHAR => $speChars,
PPOLICY_MINSPECHAR => $self->conf->{passwordPolicyMinSpeChar},
PPOLICY_ALLOWEDSPECHAR => $speChars,
PPOLICY_ALLOWEDSPECHAR_JSON =>
to_json( $speChars, { allow_nonref => 1 } ),
DISPLAY_GENERATE_PASSWORD =>
$self->conf->{portalDisplayGeneratePassword},
);

@ -34,7 +34,7 @@
<TMPL_IF NAME="PPOLICY_ALLOWEDSPECHAR">
<li>
<i id="ppolicy-allowedspechar-feedback" class="fa fa-li"> </i>
<span trspan="passwordPolicySpecialChar">Allowed special characters:</span> <TMPL_VAR NAME="PPOLICY_ALLOWEDSPECHAR">
<span trspan="passwordPolicySpecialChar">Allowed special characters:</span> <TMPL_VAR NAME="PPOLICY_ALLOWEDSPECHAR" ESCAPE="html">
</li>
</TMPL_IF>
<TMPL_IF NAME="ENABLE_CHECKHIBP">

@ -33,7 +33,7 @@
"minupper": "<TMPL_VAR NAME="PPOLICY_MINUPPER" DEFAULT="0">",
"mindigit": "<TMPL_VAR NAME="PPOLICY_MINDIGIT" DEFAULT="0">",
"nopolicy": "<TMPL_VAR NAME="PPOLICY_NOPOLICY" DEFAULT="0">",
"allowedspechar": "<TMPL_VAR NAME="PPOLICY_ALLOWEDSPECHAR" ESCAPE="js" DEFAULT="">",
"allowedspechar": <TMPL_VAR NAME="PPOLICY_ALLOWEDSPECHAR_JSON" DEFAULT='""'>,
"minspechar": "<TMPL_VAR NAME="PPOLICY_MINSPECHAR" DEFAULT="0">"
},</TMPL_IF>
"enablePasswordDisplay":<TMPL_VAR NAME="ENABLE_PASSWORD_DISPLAY" DEFAULT="0">,

@ -326,7 +326,7 @@ m%<span trspan="passwordPolicyMinSpeChar">Minimal special characters:</span> 2%,
) or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSpeChar' );
ok(
$res->[2]->[0] =~
m%\Q<span trspan="passwordPolicySpecialChar">Allowed special characters:</span> <space> [ \ }%,
m%\Q<span trspan="passwordPolicySpecialChar">Allowed special characters:</span> &lt;space&gt; [ \ }%,
' passwordPolicySpecialChar'
) or print STDERR Dumper( $res->[2]->[0], 'passwordPolicySpecialChar' );
ok( $res->[2]->[0] !~ m%class="fa fa-eye-slash toggle-password">%,

@ -0,0 +1,63 @@
use warnings;
use Test::More;
use strict;
use IO::String;
require 't/test-lib.pm';
my $res;
my $maintests = 5;
no warnings 'once';
SKIP: {
skip 'LLNGTESTLDAP is not set', $maintests unless ( $ENV{LLNGTESTLDAP} );
require 't/test-ldap.pm';
my $client = LLNG::Manager::Test->new(
{
ini => {
logLevel => 'error',
useSafeJail => 1,
authentication => 'LDAP',
portal => 'http://auth.example.com/',
userDB => 'Same',
passwordDB => 'LDAP',
portalRequireOldPassword => 1,
ldapServer => $main::slapd_url,
ldapBase => 'ou=users,dc=example,dc=com',
ldapGroupBase => 'ou=groups,dc=example,dc=com',
groupLDAPFilter => '(|(objectClass=extensibleObject)(objectClass=groupOfNames))',
ldapGroupAttributeName => 'member',
managerDn => 'cn=admin,dc=example,dc=com',
managerPassword => 'admin',
restSessionServer => 1,
}
}
);
# Try to authenticate
# -------------------
ok(
$res = $client->_post(
'/', IO::String->new('user=dwho&password=dwho'),
length => 23
),
'Auth query'
);
expectOK($res);
my $id = expectCookie($res);
ok( $res = $client->_get("/sessions/global/$id"), 'Get UTF-8' );
expectOK($res);
ok( $res = eval { JSON::from_json( $res->[2]->[0] ) }, ' GET JSON' )
or print STDERR $@;
ok( defined $res->{hGroups}->{extgroup}, 'Group extgroup found in session');
ok( defined $res->{hGroups}->{mygroup}, 'Group mygroup found in session');
}
count($maintests);
clean_sessions();
done_testing( count() );

@ -0,0 +1,63 @@
use warnings;
use Test::More;
use strict;
use IO::String;
require 't/test-lib.pm';
my $res;
my $maintests = 5;
no warnings 'once';
SKIP: {
skip 'LLNGTESTLDAP is not set', $maintests unless ( $ENV{LLNGTESTLDAP} );
require 't/test-ldap.pm';
my $client = LLNG::Manager::Test->new(
{
ini => {
logLevel => 'error',
useSafeJail => 1,
authentication => 'LDAP',
portal => 'http://auth.example.com/',
userDB => 'Same',
passwordDB => 'LDAP',
portalRequireOldPassword => 1,
ldapServer => $main::slapd_url,
ldapBase => 'ou=users,dc=example,dc=com',
ldapGroupBase => 'ou=groups,dc=example,dc=com',
ldapGroupObjectClass => 'extensibleObject',
ldapGroupAttributeName => 'member',
managerDn => 'cn=admin,dc=example,dc=com',
managerPassword => 'admin',
restSessionServer => 1,
}
}
);
# Try to authenticate
# -------------------
ok(
$res = $client->_post(
'/', IO::String->new('user=dwho&password=dwho'),
length => 23
),
'Auth query'
);
expectOK($res);
my $id = expectCookie($res);
ok( $res = $client->_get("/sessions/global/$id"), 'Get UTF-8' );
expectOK($res);
ok( $res = eval { JSON::from_json( $res->[2]->[0] ) }, ' GET JSON' )
or print STDERR $@;
ok( defined $res->{hGroups}->{extgroup}, 'Group extgroup found in session');
ok( !defined $res->{hGroups}->{mygroup}, 'Group mygroup not found in session');
}
count($maintests);
clean_sessions();
done_testing( count() );

@ -120,7 +120,7 @@ SKIP: {
);
ok(
$res->[2]->[0] =~
/<span trspan="passwordPolicySpecialChar">Allowed special characters:<\/span> &%#/,
/<span trspan="passwordPolicySpecialChar">Allowed special characters:<\/span> &amp;%#/,
' Found password special char list'
);
$query .= '&newpassword=zZ11#&confirmpassword=zZ11#';

@ -172,3 +172,10 @@ objectClass: groupOfNames
objectClass: top
cn: mygroup
member: uid=dwho,ou=users,dc=example,dc=com
dn: cn=extgroup,ou=groups,dc=example,dc=com
objectClass: extensibleObject
objectClass: device
objectClass: top
cn: extgroup
member: uid=dwho,ou=users,dc=example,dc=com

Loading…
Cancel
Save