add RememberAuthChoice Plugin (references #2737)

This commit is contained in:
David Coutadeur 2022-04-06 16:48:37 +00:00
parent d2df7a314e
commit 901a6d3697
48 changed files with 5799 additions and 5422 deletions

View File

@ -30,3 +30,4 @@ Plugins
restservices
soapservices
stayconnected
rememberauthchoice

View File

@ -0,0 +1,27 @@
Remember auth choice plugin
===========================
This plugin enables automatic authentication, based upon the last user authentication choice.
For this plugin to work, you have to configure a set of :doc:`authentication modules<authchoice>`.
If you have multiple SAML, OIDC or CAS issuers, you should define a dedicated choice for each of these issuers, and set the corresponding URL to ``/?idp=youridp``.
Configuration
-------------
Once enabled (section "General Parameters > Plugins"), you can set these parameters.
- **Parameters**:
- **Activation**: Rule to enable/disable this plugin
- **Cookie name**: Name of the cookie storing the authentication choice
- **Cookie lifetime**: Duration of the cookie (seconds) storing the authentication choice
- **Check by default**: Is the checkbox "Remember my choice" checked by default?
- **Timer before automatic authentication**: Timer before automatic authentication happens, if user has previously authorized the storage of authentication choice in a cookie
.. tip::
For instance, you may allow users from 192.168.0.0/16 private network to have the "Remember authentication choice" checkbox:
- Rule: ``$env->{REMOTE_ADDR} =~ /^192\.168\./``

View File

@ -305,6 +305,7 @@ Name Description
:doc:`REST services<restservices>` |new| REST server for :doc:`Proxy<authproxy>`
:doc:`SOAP services<soapservices>` |deprecated| SOAP server for :doc:`Proxy<authproxy>`
:doc:`Stay connected<stayconnected>` |new| Enable persistent connection on same browser
:doc:`Remember auth choice<rememberauthchoice>` |new| Remember user last authentication choice
Upgrade session |new| This plugin explains to an already authenticated user that a higher authentication level is required to access the URL instead of reject him
==================================================================== ============================================================================================================================================

View File

@ -31,7 +31,7 @@ use constant DEFAULTCONFBACKENDOPTIONS => (
);
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|f(?:indUser(?:Exclud|Search)ingAttribute|acebookExportedVar)|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|ScopeRule|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)s)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $arrayParameters = qr/^mySessionAuthorizedRWKeys$/;
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)|t(?:ayConnectedBypassFG|orePassword)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:A(?:llow(?:(?:ClientCredentials|Password)Grant|Offline)|ccessToken(?:Claims|JWT))|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration|OnlyDeclaredScopes)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|c(?:a(?:sS(?:rvMetaDataOptions(?:Gateway|Renew)|trictMatching)|ptcha_(?:register|login|mail)_enabled)|heck(?:DevOps(?:D(?:isplayNormalizedHeaders|ownload)|CheckSessionAttributes)?|State|User|XSS)|o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|rowdsec|da)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|E(?:rrorOn(?:ExpiredSession|MailNotFound)|nablePasswordDisplay)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxy(?:AuthServiceImpersonation|UseSoap))|l(?:dap(?:(?:G(?:roup(?:DecodeSearchedValu|Recursiv)|etUserBeforePasswordChang)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|n(?:o(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|ewLocationWarning)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|to(?:tp2f(?:UserCanRemoveKey|EncryptSecret)|kenUseGlobalStorage)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|w(?:ebauthn2fUserCanRemoveKey|sdlServer)|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|findUser)$/;
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)|t(?:ayConnectedBypassFG|orePassword)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:A(?:llow(?:(?:ClientCredentials|Password)Grant|Offline)|ccessToken(?:Claims|JWT))|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration|OnlyDeclaredScopes)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|c(?:a(?:sS(?:rvMetaDataOptions(?:Gateway|Renew)|trictMatching)|ptcha_(?:register|login|mail)_enabled)|heck(?:DevOps(?:D(?:isplayNormalizedHeaders|ownload)|CheckSessionAttributes)?|State|User|XSS)|o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|rowdsec|da)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|E(?:rrorOn(?:ExpiredSession|MailNotFound)|nablePasswordDisplay)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxy(?:AuthServiceImpersonation|UseSoap))|l(?:dap(?:(?:G(?:roup(?:DecodeSearchedValu|Recursiv)|etUserBeforePasswordChang)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|n(?:o(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|ewLocationWarning)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|memberDefaultChecked|freshSessions)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|to(?:tp2f(?:UserCanRemoveKey|EncryptSecret)|kenUseGlobalStorage)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|w(?:ebauthn2fUserCanRemoveKey|sdlServer)|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|findUser)$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );

View File

@ -17,8 +17,7 @@ sub defaultValues {
},
'authChoiceParam' => 'lmAuth',
'authentication' => 'Demo',
'available2F' =>
'UTOTP,TOTP,U2F,REST,Mail2F,Ext2F,WebAuthn,Yubikey,Radius',
'available2F' => 'UTOTP,TOTP,U2F,REST,Mail2F,Ext2F,WebAuthn,Yubikey,Radius',
'available2FSelfRegistration' => 'TOTP,U2F,WebAuthn,Yubikey',
'bruteForceProtectionLockTimes' => '15, 30, 60, 300, 600',
'bruteForceProtectionMaxAge' => 300,
@ -32,10 +31,8 @@ sub defaultValues {
'casAuthnLevel' => 1,
'casTicketExpiration' => 0,
'certificateResetByMailCeaAttribute' => 'description',
'certificateResetByMailCertificateAttribute' =>
'userCertificate;binary',
'certificateResetByMailURL' =>
'http://auth.example.com/certificateReset',
'certificateResetByMailCertificateAttribute' => 'userCertificate;binary',
'certificateResetByMailURL' => 'http://auth.example.com/certificateReset',
'certificateResetByMailValidityDelay' => 0,
'checkDevOpsCheckSessionAttributes' => 1,
'checkDevOpsDisplayNormalizedHeaders' => 1,
@ -103,8 +100,7 @@ sub defaultValues {
'globalStorage' => 'Apache::Session::File',
'globalStorageOptions' => {
'Directory' => '/var/lib/lemonldap-ng/sessions/',
'generateModule' =>
'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
'generateModule' => 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
},
'gpgAuthnLevel' => 5,
@ -189,15 +185,17 @@ sub defaultValues {
'max2FDevices' => 10,
'max2FDevicesNameLength' => 20,
'multiValuesSeparator' => '; ',
'mySessionAuthorizedRWKeys' =>
[ '_appsListOrder', '_oidcConnectedRP', '_oidcConsents' ],
'mySessionAuthorizedRWKeys' => [
'_appsListOrder',
'_oidcConnectedRP',
'_oidcConsents'
],
'newLocationWarningLocationAttribute' => 'ipAddr',
'newLocationWarningLocationDisplayAttribute' => '',
'newLocationWarningMaxValues' => '0',
'notificationDefaultCond' => '',
'notificationServerPOST' => 1,
'notificationServerSentAttributes' =>
'uid reference date title subtitle text check',
'notificationServerSentAttributes' => 'uid reference date title subtitle text check',
'notificationsMaxRetrieve' => 3,
'notificationStorage' => 'File',
'notificationStorageOptions' => {
@ -250,8 +248,7 @@ sub defaultValues {
'passwordPolicyMinUpper' => 0,
'passwordPolicySpecialChar' => '__ALL__',
'passwordResetAllowedRetries' => 3,
'persistentSessionAttributes' =>
'_loginHistory _2fDevices notification_',
'persistentSessionAttributes' => '_loginHistory _2fDevices notification_',
'port' => -1,
'portal' => 'http://auth.example.com/',
'portalAntiFrame' => 1,
@ -261,8 +258,7 @@ sub defaultValues {
'portalDisplayGeneratePassword' => 1,
'portalDisplayLoginHistory' => 1,
'portalDisplayLogout' => 1,
'portalDisplayOidcConsents' =>
'$_oidcConsents && $_oidcConsents =~ /\\w+/',
'portalDisplayOidcConsents' => '$_oidcConsents && $_oidcConsents =~ /\\w+/',
'portalDisplayRefreshMyRights' => 1,
'portalDisplayRegister' => 1,
'portalErrorOnExpiredSession' => 1,
@ -283,10 +279,13 @@ sub defaultValues {
'registerTimeout' => 0,
'registerUrl' => 'http://auth.example.com/register',
'reloadTimeout' => 5,
'rememberAuthChoiceRule' => 0,
'rememberCookieName' => 'llngrememberauthchoice',
'rememberCookieTimeout' => 31536000,
'rememberTimer' => 5,
'remoteGlobalStorage' => 'Lemonldap::NG::Common::Apache::Session::SOAP',
'remoteGlobalStorageOptions' => {
'ns' =>
'http://auth.example.com/Lemonldap/NG/Common/PSGI/SOAPService',
'ns' => 'http://auth.example.com/Lemonldap/NG/Common/PSGI/SOAPService',
'proxy' => 'http://auth.example.com/sessions'
},
'requireToken' => 1,
@ -294,27 +293,19 @@ sub defaultValues {
'restAuthnLevel' => 2,
'restClockTolerance' => 15,
'sameSite' => '',
'samlAttributeAuthorityDescriptorAttributeServiceSOAP' =>
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;',
'samlAttributeAuthorityDescriptorAttributeServiceSOAP' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;',
'samlAuthnContextMapKerberos' => 4,
'samlAuthnContextMapPassword' => 2,
'samlAuthnContextMapPasswordProtectedTransport' => 3,
'samlAuthnContextMapTLSClient' => 5,
'samlEntityID' => '#PORTAL#/saml/metadata',
'samlIDPSSODescriptorArtifactResolutionServiceArtifact' =>
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'samlIDPSSODescriptorSingleLogoutServiceHTTPPost' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'samlIDPSSODescriptorSingleLogoutServiceSOAP' =>
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/singleLogoutSOAP;',
'samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/singleSignOnArtifact;',
'samlIDPSSODescriptorSingleSignOnServiceHTTPPost' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleSignOn;',
'samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleSignOn;',
'samlIDPSSODescriptorArtifactResolutionServiceArtifact' => '1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'samlIDPSSODescriptorSingleLogoutServiceHTTPPost' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'samlIDPSSODescriptorSingleLogoutServiceSOAP' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/singleLogoutSOAP;',
'samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/singleSignOnArtifact;',
'samlIDPSSODescriptorSingleSignOnServiceHTTPPost' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleSignOn;',
'samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleSignOn;',
'samlIDPSSODescriptorWantAuthnRequestsSigned' => 1,
'samlMetadataForceUTF8' => 1,
'samlNameIDFormatMapEmail' => 'mail',
@ -327,26 +318,19 @@ sub defaultValues {
'samlOverrideIDPEntityID' => '',
'samlRelayStateTimeout' => 600,
'samlServiceSignatureMethod' => 'RSA_SHA256',
'samlSPSSODescriptorArtifactResolutionServiceArtifact' =>
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact' =>
'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',
'samlSPSSODescriptorArtifactResolutionServiceArtifact' => '1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact' => '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,
'samlSPSSODescriptorSingleLogoutServiceHTTPPost' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'samlSPSSODescriptorSingleLogoutServiceHTTPRedirect' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'samlSPSSODescriptorSingleLogoutServiceSOAP' =>
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/proxySingleLogoutSOAP;',
'samlSPSSODescriptorSingleLogoutServiceHTTPPost' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'samlSPSSODescriptorSingleLogoutServiceHTTPRedirect' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'samlSPSSODescriptorSingleLogoutServiceSOAP' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/proxySingleLogoutSOAP;',
'samlSPSSODescriptorWantAssertionsSigned' => 1,
'securedCookie' => 0,
'sfEngine' => '::2F::Engines::Default',
'sfManagerRule' => 1,
'sfRemovedMsgRule' => 0,
'sfRemovedNotifMsg' =>
'_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
'sfRemovedNotifMsg' => '_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
'sfRemovedNotifRef' => 'RemoveSF',
'sfRemovedNotifTitle' => 'Second factor notification',
'sfRequired' => 0,

View File

@ -116,7 +116,7 @@ sub portalConsts {
}
# EXPORTER PARAMETERS
our @EXPORT_OK = ('portalConsts');
our @EXPORT_OK = ( 'portalConsts' );
our %EXPORT_TAGS = ( 'all' => [ @EXPORT_OK, 'import' ], );
1;

View File

@ -4,28 +4,17 @@ package Lemonldap::NG::Manager::Attributes;
our $VERSION = '2.0.14';
sub perlExpr {
my ( $val, $conf ) = @_;
my($val, $conf) = @_;
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from(
'Lemonldap::NG::Handler::Main::Jail',
[
'&encrypt', '&token',
@Lemonldap::NG::Handler::Main::Jail::builtCustomFunctions
]
);
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->share_from('MIME::Base64', ['&encode_base64']);
$cpt->share_from('Lemonldap::NG::Handler::Main::Jail', ['&encrypt', '&token', @Lemonldap::NG::Handler::Main::Jail::builtCustomFunctions]);
$cpt->share_from('Lemonldap::NG::Common::Safelib', $Lemonldap::NG::Common::Safelib::functions);
$cpt->reval("BEGIN { 'warnings'->unimport; } $val");
my $err = join(
'',
grep( { $_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_; }
split( /\n/, $@, 0 ) )
);
my $err = join('', grep({$_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_;} split(/\n/, $@, 0)));
return -1, "__badExpression__: $err" if $err and $conf->{'useSafeJail'};
return $val =~ qr/(?<=[^=<!>\|\?])=(?![>=~])/
&& $conf->{'avoidAssignment'} ? ( 1, '__badExpressionAssignment__' ) : 1;
}
return $val =~ qr/(?<=[^=<!>\|\?])=(?![>=~])/ && $conf->{'avoidAssignment'} ? (1, '__badExpressionAssignment__') : 1;
};
sub types {
return {
@ -67,8 +56,7 @@ sub types {
'hostname' => {
'form' => 'text',
'msgFail' => '__badHostname__',
'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]+)))?$/
'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' => {
'msgFail' => '__notAnInteger__',
@ -88,11 +76,10 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'lmAttrOrMacro' => {
'form' => 'text',
'test' => sub {
my ( $val, $conf ) = @_;
my($val, $conf) = @_;
return 1 if defined $conf->{'macros'}{$val} or $val =~ /^_/;
foreach $_ ( keys %$conf ) {
return 1
if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val};
foreach $_ (keys %$conf) {
return 1 if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val};
}
return 1, "__unknownAttrOrMacro__: $val";
}
@ -148,10 +135,10 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'test' => sub {
eval {
do {
qr/$_[0]/;
qr/$_[0]/
}
};
return $@ ? ( 0, "__badRegexp__: $@" ) : 1;
return $@ ? (0, "__badRegexp__: $@") : 1;
}
},
'PerlModule' => {
@ -176,26 +163,17 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
},
'RSAPrivateKey' => {
'test' => sub {
return $_[0] =~
m[^(?:(?:\-+\s*BEGIN\s+(?:(?:RSA|ENCRYPTED)\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\nDEK-Info:.*\r?\n[\r\n]*)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:(?:RSA|ENCRYPTED)\s+)?PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
return $_[0] =~ m[^(?:(?:\-+\s*BEGIN\s+(?:(?:RSA|ENCRYPTED)\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\nDEK-Info:.*\r?\n[\r\n]*)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:(?:RSA|ENCRYPTED)\s+)?PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$]s ? 1 : (1, '__badPemEncoding__');
}
},
'RSAPublicKey' => {
'test' => sub {
return $_[0] =~
m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
return $_[0] =~ m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$]s ? 1 : (1, '__badPemEncoding__');
}
},
'RSAPublicKeyOrCertificate' => {
'test' => sub {
return $_[0] =~
m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
return $_[0] =~ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$]s ? 1 : (1, '__badPemEncoding__');
}
},
'rule' => {
@ -231,11 +209,8 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\
'select' => {
'test' => sub {
return 0, 'Value is not a scalar' if ref $_[0];
my $test = grep( { $_ eq $_[0]; }
map( { $_->{'k'}; } @{ $_[2]{'select'}; } ) );
return $test
? 1
: ( 1, "Invalid value '$_[0]' for this select" );
my $test = grep({$_ eq $_[0];} map({$_->{'k'};} @{$_[2]{'select'};}));
return $test ? 1 : (1, "Invalid value '$_[0]' for this select");
}
},
'subContainer' => {
@ -257,8 +232,7 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\
'url' => {
'form' => 'text',
'msgFail' => '__badUrl__',
'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]))*)))?))?))/
'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]))*)))?))?))/
}
};
}
@ -274,7 +248,7 @@ sub attributes {
'keyTest' => sub {
eval {
do {
qr/$_[0]/;
qr/$_[0]/
}
};
return $@ ? 0 : 1;
@ -312,7 +286,9 @@ sub attributes {
'authChoiceModules' => {
'keyMsgFail' => '__badChoiceKey__',
'keyTest' => qr/^(\d*)?[a-zA-Z0-9_]+$/,
'select' => [ [ {
'select' => [
[
{
'k' => 'Apache',
'v' => 'Apache'
},
@ -413,7 +389,8 @@ sub attributes {
'v' => 'customModule'
}
],
[ {
[
{
'k' => 'AD',
'v' => 'Active Directory'
},
@ -478,7 +455,8 @@ sub attributes {
'v' => 'customModule'
}
],
[ {
[
{
'k' => 'AD',
'v' => 'Active Directory'
},
@ -519,7 +497,8 @@ sub attributes {
},
'authentication' => {
'default' => 'Demo',
'select' => [ {
'select' => [
{
'k' => 'Apache',
'v' => 'Apache'
},
@ -637,8 +616,7 @@ sub attributes {
'type' => 'keyTextContainer'
},
'available2F' => {
'default' =>
'UTOTP,TOTP,U2F,REST,Mail2F,Ext2F,WebAuthn,Yubikey,Radius',
'default' => 'UTOTP,TOTP,U2F,REST,Mail2F,Ext2F,WebAuthn,Yubikey,Radius',
'type' => 'text'
},
'available2FSelfRegistration' => {
@ -699,7 +677,8 @@ sub attributes {
},
'casAccessControlPolicy' => {
'default' => 'none',
'select' => [ {
'select' => [
{
'k' => 'none',
'v' => 'None'
},
@ -802,8 +781,7 @@ sub attributes {
},
'casSrvMetaDataOptionsUrl' => {
'msgFail' => '__badUrl__',
'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]))*)))?))?)/,
'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'
},
'casStorage' => {
@ -971,7 +949,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'combModules' => {
'keyTest' => qr/^\w+$/,
'select' => [ {
'select' => [
{
'k' => 'Apache',
'v' => 'Apache'
},
@ -1086,7 +1065,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'confirmFormMethod' => {
'default' => 'post',
'select' => [ {
'select' => [
{
'k' => 'get',
'v' => 'GET'
},
@ -1168,7 +1148,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'crowdsecAction' => {
'default' => 'reject',
'select' => [ {
'select' => [
{
'k' => 'reject',
'v' => 'Reject'
},
@ -1341,8 +1322,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'domain' => {
'default' => 'example.com',
'msgFail' => '__badDomainName__',
'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])[.]?))?$/,
'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'
},
'exportedAttr' => {
@ -1485,8 +1465,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/',
'generateModule' =>
'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
'generateModule' => 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
},
'type' => 'keyTextContainer'
@ -1579,7 +1558,8 @@ qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-
},
'infoFormMethod' => {
'default' => 'get',
'select' => [ {
'select' => [
{
'k' => 'get',
'v' => 'GET'
},
@ -1609,19 +1589,15 @@ qr/^(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-
'issuerDBGetParameters' => {
'default' => {},
'keyMsgFail' => '__badHostname__',
'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])[.]?)$/,
'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__',
'keyTest' => qr/^(?=[^\-])[\w\-]+(?<=[^-])$/,
'test' => sub {
my ( $val, $conf ) = @_;
return 1
if defined $conf->{'macros'}{$val} or $val eq '_timezone';
foreach $_ ( keys %$conf ) {
return 1
if $_ =~ /exportedvars$/i
and defined $conf->{$_}{$val};
my($val, $conf) = @_;
return 1 if defined $conf->{'macros'}{$val} or $val eq '_timezone';
foreach $_ (keys %$conf) {
return 1 if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val};
}
return 1, "__unknownAttrOrMacro__: $val";
}
@ -1809,7 +1785,8 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
},
'ldapSearchDeref' => {
'default' => 'find',
'select' => [ {
'select' => [
{
'k' => 'never',
'v' => 'never'
},
@ -1832,11 +1809,9 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
'default' => 'ldap://localhost',
'test' => sub {
my $l = shift();
my @s = split( /[\s,]+/, $l, 0 );
my @s = split(/[\s,]+/, $l, 0);
foreach my $s (@s) {
return 0, qq[__badLdapUri__: "$s"]
unless $s =~
m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?::\d{1,5})?/?.*)$]o;
return 0, qq[__badLdapUri__: "$s"] unless $s =~ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?::\d{1,5})?/?.*)$]o;
}
return 1;
},
@ -1856,7 +1831,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'ldapVerify' => {
'default' => 'require',
'select' => [ {
'select' => [
{
'k' => 'none',
'v' => 'None'
},
@ -1928,22 +1904,20 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'keyTest' => sub {
eval {
do {
qr/$_[0]/;
qr/$_[0]/
}
};
return $@ ? 0 : 1;
},
'msgFail' => '__badExpression__',
'test' => sub {
my ( $val, $conf ) = @_;
my($val, $conf) = @_;
my $s = $val;
if ( $s =~ s/^logout(?:_(?:sso|app(?:_sso)?))?\s*// ) {
return $s =~ m[^(?:https?://.*)?$]
? 1
: ( 0, '__badUrl__' );
if ($s =~ s/^logout(?:_(?:sso|app(?:_sso)?))?\s*//) {
return $s =~ m[^(?:https?://.*)?$] ? 1 : (0, '__badUrl__');
}
$s =~ s/\b(accept|deny|unprotect|skip)\b/1/g;
return &perlExpr( $s, $conf );
return &perlExpr($s, $conf);
}
},
'type' => 'ruleContainer'
@ -2080,8 +2054,11 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'type' => 'authParamsText'
},
'mySessionAuthorizedRWKeys' => {
'default' =>
[ '_appsListOrder', '_oidcConnectedRP', '_oidcConsents' ],
'default' => [
'_appsListOrder',
'_oidcConnectedRP',
'_oidcConsents'
],
'type' => 'array'
},
'newLocationWarning' => {
@ -2233,7 +2210,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'oidcOPMetaDataOptionsDisplay' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => ''
},
@ -2290,7 +2268,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'oidcOPMetaDataOptionsTokenEndpointAuthMethod' => {
'default' => 'client_secret_post',
'select' => [ {
'select' => [
{
'k' => 'client_secret_post',
'v' => 'client_secret_post'
},
@ -2352,7 +2331,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'oidcRPMetaDataOptionsAccessTokenSignAlg' => {
'default' => 'RS256',
'select' => [ {
'select' => [
{
'k' => 'RS256',
'v' => 'RS256'
},
@ -2418,7 +2398,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'oidcRPMetaDataOptionsIDTokenSignAlg' => {
'default' => 'HS512',
'select' => [ {
'select' => [
{
'k' => 'none',
'v' => 'None'
},
@ -2455,7 +2436,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'oidcRPMetaDataOptionsLogoutType' => {
'default' => 'front',
'select' => [ {
'select' => [
{
'k' => 'front',
'v' => 'Front Channel'
}
@ -2497,7 +2479,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'oidcRPMetaDataOptionsUserInfoSignAlg' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => 'JSON'
},
@ -2733,7 +2716,8 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
'passwordDB' => {
'default' => 'Demo',
'select' => [ {
'select' => [
{
'k' => 'AD',
'v' => 'Active Directory'
},
@ -2808,8 +2792,7 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'pdataDomain' => {
'default' => '',
'msgFail' => '__badDomainName__',
'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])[.]?))?$/,
'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'
},
'persistentSessionAttributes' => {
@ -2829,8 +2812,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' =>
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]))*)))?))?)/,
'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'
},
'portalAntiFrame' => {
@ -2926,7 +2908,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'portalSkin' => {
'default' => 'bootstrap',
'select' => [ {
'select' => [
{
'k' => 'bootstrap',
'v' => 'Bootstrap'
}
@ -2934,7 +2917,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'portalskin'
},
'portalSkinBackground' => {
'select' => [ {
'select' => [
{
'k' => '',
'v' => 'None'
},
@ -2943,8 +2927,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'v' => 'Anse'
},
{
'k' =>
'1280px-Autumn-clear-water-waterfall-landscape_-_Virginia_-_ForestWander.jpg',
'k' => '1280px-Autumn-clear-water-waterfall-landscape_-_Virginia_-_ForestWander.jpg',
'v' => 'Waterfall'
},
{
@ -2952,8 +2935,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'v' => 'Snowed Trees'
},
{
'k' =>
'1280px-Cedar_Breaks_National_Monument_partially.jpg',
'k' => '1280px-Cedar_Breaks_National_Monument_partially.jpg',
'v' => 'National Monument'
},
{
@ -3069,7 +3051,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'redirectFormMethod' => {
'default' => 'get',
'select' => [ {
'select' => [
{
'k' => 'get',
'v' => 'GET'
},
@ -3091,7 +3074,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'registerDB' => {
'default' => 'Null',
'select' => [ {
'select' => [
{
'k' => 'AD',
'v' => 'Active Directory'
},
@ -3133,13 +3117,33 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'int'
},
'reloadUrls' => {
'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+)?$/,
'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' =>
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]))*)))?))?)/,
'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'
},
'rememberAuthChoiceRule' => {
'default' => 0,
'type' => 'boolOrExpr'
},
'rememberCookieName' => {
'default' => 'llngrememberauthchoice',
'msgFail' => '__badCookieName__',
'test' => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
'type' => 'text'
},
'rememberCookieTimeout' => {
'default' => 31536000,
'type' => 'int'
},
'rememberDefaultChecked' => {
'default' => 0,
'type' => 'bool'
},
'rememberTimer' => {
'default' => 5,
'type' => 'int'
},
'remoteCookieName' => {
'msgFail' => '__badCookieName__',
'test' => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
@ -3151,8 +3155,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'remoteGlobalStorageOptions' => {
'default' => {
'ns' =>
'http://auth.example.com/Lemonldap/NG/Common/PSGI/SOAPService',
'ns' => 'http://auth.example.com/Lemonldap/NG/Common/PSGI/SOAPService',
'proxy' => 'http://auth.example.com/sessions'
},
'type' => 'keyTextContainer'
@ -3242,7 +3245,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'sameSite' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => ''
},
@ -3262,8 +3266,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'select'
},
'samlAttributeAuthorityDescriptorAttributeServiceSOAP' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/AA/SOAP;',
'type' => 'samlService'
},
'samlAuthnContextMapKerberos' => {
@ -3288,20 +3291,17 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlCommonDomainCookieDomain' => {
'msgFail' => '__badDomainName__',
'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])[.]?)$/,
'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' =>
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]))*)))?))?)/,
'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' =>
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]))*)))?))?)/,
'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'
},
'samlDiscoveryProtocolActivation' => {
@ -3317,8 +3317,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlDiscoveryProtocolURL' => {
'msgFail' => '__badUrl__',
'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]))*)))?))?)/,
'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'
},
'samlEntityID' => {
@ -3374,7 +3373,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlIDPMetaDataOptionsEncryptionMode' => {
'default' => 'none',
'select' => [ {
'select' => [
{
'k' => 'none',
'v' => 'None'
},
@ -3406,7 +3406,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlIDPMetaDataOptionsNameIDFormat' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => ''
},
@ -3455,7 +3456,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlIDPMetaDataOptionsRequestedAuthnContext' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => ''
},
@ -3484,7 +3486,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlIDPMetaDataOptionsSignatureMethod' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => 'default'
},
@ -3517,7 +3520,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlIDPMetaDataOptionsSLOBinding' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => ''
},
@ -3541,7 +3545,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlIDPMetaDataOptionsSSOBinding' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => ''
},
@ -3574,60 +3579,50 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
my @msg;
my $res = 1;
my %entityIds;
foreach my $idpId ( keys %$v ) {
unless ( $v->{$idpId}{'samlIDPMetaDataXML'} =~
/entityID="(.+?)"/is )
{
foreach my $idpId (keys %$v) {
unless ($v->{$idpId}{'samlIDPMetaDataXML'} =~ /entityID="(.+?)"/is) {
push @msg, "$idpId SAML metadata has no EntityID";
$res = 0;
next;
}
my $eid = $1;
if ( defined $entityIds{$eid} ) {
push @msg,
"$idpId and $entityIds{$eid} have the same SAML EntityID";
if (defined $entityIds{$eid}) {
push @msg, "$idpId and $entityIds{$eid} have the same SAML EntityID";
$res = 0;
next;
}
$entityIds{$eid} = $idpId;
}
return $res, join( ', ', @msg );
return $res, join(', ', @msg);
},
'type' => 'file'
},
'samlIDPSSODescriptorArtifactResolutionServiceArtifact' => {
'default' =>
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'default' => '1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'type' => 'samlAssertion'
},
'samlIDPSSODescriptorSingleLogoutServiceHTTPPost' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'type' => 'samlService'
},
'samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleLogout;#PORTAL#/saml/singleLogoutReturn',
'type' => 'samlService'
},
'samlIDPSSODescriptorSingleLogoutServiceSOAP' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/singleLogoutSOAP;',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/singleLogoutSOAP;',
'type' => 'samlService'
},
'samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/singleSignOnArtifact;',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/singleSignOnArtifact;',
'type' => 'samlService'
},
'samlIDPSSODescriptorSingleSignOnServiceHTTPPost' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleSignOn;',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/singleSignOn;',
'type' => 'samlService'
},
'samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleSignOn;',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/singleSignOn;',
'type' => 'samlService'
},
'samlIDPSSODescriptorWantAuthnRequestsSigned' => {
@ -3699,7 +3694,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlServiceSignatureMethod' => {
'default' => 'RSA_SHA256',
'select' => [ {
'select' => [
{
'k' => 'RSA_SHA1',
'v' => 'RSA SHA1'
},
@ -3766,7 +3762,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlSPMetaDataOptionsEncryptionMode' => {
'default' => 'none',
'select' => [ {
'select' => [
{
'k' => 'none',
'v' => 'None'
},
@ -3787,7 +3784,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlSPMetaDataOptionsNameIDFormat' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => ''
},
@ -3853,7 +3851,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'samlSPMetaDataOptionsSignatureMethod' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => 'default'
},
@ -3888,18 +3887,15 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'file'
},
'samlSPSSODescriptorArtifactResolutionServiceArtifact' => {
'default' =>
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'default' => '1;0;urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/artifact',
'type' => 'samlAssertion'
},
'samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact' => {
'default' =>
'0;1;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/proxySingleSignOnArtifact',
'default' => '0;1;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact;#PORTAL#/saml/proxySingleSignOnArtifact',
'type' => 'samlAssertion'
},
'samlSPSSODescriptorAssertionConsumerServiceHTTPPost' => {
'default' =>
'1;0;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleSignOnPost',
'default' => '1;0;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleSignOnPost',
'type' => 'samlAssertion'
},
'samlSPSSODescriptorAuthnRequestsSigned' => {
@ -3907,18 +3903,15 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'bool'
},
'samlSPSSODescriptorSingleLogoutServiceHTTPPost' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'type' => 'samlService'
},
'samlSPSSODescriptorSingleLogoutServiceHTTPRedirect' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect;#PORTAL#/saml/proxySingleLogout;#PORTAL#/saml/proxySingleLogoutReturn',
'type' => 'samlService'
},
'samlSPSSODescriptorSingleLogoutServiceSOAP' => {
'default' =>
'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/proxySingleLogoutSOAP;',
'default' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP;#PORTAL#/saml/proxySingleLogoutSOAP;',
'type' => 'samlService'
},
'samlSPSSODescriptorWantAssertionsSigned' => {
@ -3937,7 +3930,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'securedCookie' => {
'default' => 0,
'select' => [ {
'select' => [
{
'k' => '0',
'v' => 'unsecuredCookie'
},
@ -3988,7 +3982,8 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'sfExtra' => {
'keyTest' => qr/^\w+$/,
'select' => [ {
'select' => [
{
'k' => 'Mail2F',
'v' => 'E-Mail'
},
@ -4025,8 +4020,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'type' => 'boolOrExpr'
},
'sfRemovedNotifMsg' => {
'default' =>
'_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
'default' => '_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
'type' => 'text'
},
'sfRemovedNotifRef' => {
@ -4110,13 +4104,13 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
},
'SMTPServer' => {
'default' => '',
'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+)?)?$/,
'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'
},
'SMTPTLS' => {
'default' => '',
'select' => [ {
'select' => [
{
'k' => '',
'v' => 'none'
},
@ -4325,7 +4319,8 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
},
'userDB' => {
'default' => 'Same',
'select' => [ {
'select' => [
{
'k' => 'Same',
'v' => 'Same'
},
@ -4425,7 +4420,8 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
},
'vhostType' => {
'default' => 'Main',
'select' => [ {
'select' => [
{
'k' => 'AuthBasic',
'v' => 'AuthBasic'
},
@ -4502,7 +4498,8 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
},
'webauthn2fUserVerification' => {
'default' => 'preferred',
'select' => [ {
'select' => [
{
'k' => 'discouraged',
'v' => 'Discouraged'
},

View File

@ -435,6 +435,36 @@ sub attributes {
documentation => 'Separator for multiple values',
flags => 'hmp',
},
rememberAuthChoiceRule => {
type => 'boolOrExpr',
default => 0,
documentation => 'remember auth choice activation rule',
},
rememberCookieName => {
type => 'text',
test => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
msgFail => '__badCookieName__',
default => 'llngrememberauthchoice',
documentation => 'Name of the remember auth choice cookie',
flags => 'p',
},
rememberCookieTimeout => {
type => 'int',
default => 31536000,
documentation => 'lifetime of the remember auth choice cookie',
flags => 'm',
},
rememberDefaultChecked => {
type => 'bool',
default => 0,
documentation => 'Is remember auth choice checkbox enabled by default?',
},
rememberTimer => {
type => 'int',
default => 5,
documentation => 'timer before automatic authentication with the previous remembered authentication choice',
flags => 'm',
},
stayConnected => {
type => 'boolOrExpr',
default => 0,

View File

@ -863,6 +863,18 @@ sub tree {
'contextSwitchingStopWithLogout',
]
},
{
title => 'rememberAuthChoice',
help => 'rememberauthchoice.html',
form => 'simpleInputContainer',
nodes => [
'rememberAuthChoiceRule',
'rememberCookieName',
'rememberCookieTimeout',
'rememberDefaultChecked',
'rememberTimer',
]
},
{
title => 'decryptValue',
help => 'decryptvalue.html',

View File

@ -873,6 +873,12 @@
"reloadParams":"إعادة تحميل الإعدادات",
"reloadTimeout":"Reload timeout",
"reloadUrls":"Reload URLs",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"اسم ملف تعريف الارتباط",
"remoteGlobalStorage":"وحدة الجلسات",
"remoteGlobalStorageOptions":"خيارات وحدة الجلسات",

View File

@ -873,6 +873,12 @@
"reloadParams":"Configuration reload",
"reloadTimeout":"Reload timeout",
"reloadUrls":"Reload URLs",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Cookie name",
"remoteGlobalStorage":"Sessions module",
"remoteGlobalStorageOptions":"Sessions module options",

View File

@ -873,6 +873,12 @@
"reloadParams":"Recargar configuración",
"reloadTimeout":"Reload timeout",
"reloadUrls":"Recargar las URL",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Nombre de la cookie",
"remoteGlobalStorage":"Módulo de sesiones",
"remoteGlobalStorageOptions":"Opciones del módulo de sesiones",

View File

@ -873,6 +873,12 @@
"reloadParams":"Mise à jour de la configuration",
"reloadTimeout":"Délai de mise à jour",
"reloadUrls":"URLs de mise à jour",
"rememberAuthChoice":"Se souvenir du choix d'authentification",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Nom du cookie",
"rememberCookieTimeout":"Durée de vie du cookie",
"rememberDefaultChecked":"Cocher par défaut",
"rememberTimer":"Délai avant authentication automatique",
"remoteCookieName":"Nom du cookie",
"remoteGlobalStorage":"Module des sessions",
"remoteGlobalStorageOptions":"Options du module des sessions",

View File

@ -873,6 +873,12 @@
"reloadParams":"Configuration reload",
"reloadTimeout":"Reload timeout",
"reloadUrls":"רענון כתובות",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"שם עוגיה",
"remoteGlobalStorage":"מודול הפעלות",
"remoteGlobalStorageOptions":"אפשרויות מודול הפעלות",

View File

@ -873,6 +873,12 @@
"reloadParams":"Ricarica di configurazione",
"reloadTimeout":"Ricarica il timeout",
"reloadUrls":"Ricarica gli URL",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Nome del cookie",
"remoteGlobalStorage":"Modulo di sessioni",
"remoteGlobalStorageOptions":"Opzioni del modulo Sessioni",

View File

@ -873,6 +873,12 @@
"reloadParams":"Załaduj ponownie konfigurację",
"reloadTimeout":"Limit czasu przeładowania",
"reloadUrls":"Załaduj ponownie adresy URL",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Nazwa ciasteczka",
"remoteGlobalStorage":"Moduł sesji",
"remoteGlobalStorageOptions":"Opcje modułu sesji",

View File

@ -873,6 +873,12 @@
"reloadParams":"Yapılandırma yeniden yüklendi",
"reloadTimeout":"Yeniden yükleme zaman aşımı",
"reloadUrls":"URL'leri yeniden yükle",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Çerez adı",
"remoteGlobalStorage":"Oturumlar modülü",
"remoteGlobalStorageOptions":"Oturumlar modülü seçenekleri",

View File

@ -873,6 +873,12 @@
"reloadParams":"Tải lại cấu hình",
"reloadTimeout":"Reload timeout",
"reloadUrls":"Reload URLs",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Tên cookie",
"remoteGlobalStorage":"Mô-đun phiên",
"remoteGlobalStorageOptions":"Tùy chọn mô-đun phiên",

View File

@ -873,6 +873,12 @@
"reloadParams":"設定重新載入",
"reloadTimeout":"重新載入逾時",
"reloadUrls":"重新載入 URL",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Cookie 名称",
"remoteGlobalStorage":"工作階段模組",
"remoteGlobalStorageOptions":"工作階段模組選項",

View File

@ -873,6 +873,12 @@
"reloadParams":"設定重新載入",
"reloadTimeout":"重新載入逾時",
"reloadUrls":"重新載入 URL",
"rememberAuthChoice":"Remember authentication choice",
"rememberAuthChoiceRule":"Activation",
"rememberCookieName":"Cookie name",
"rememberCookieTimeout":"cookie lifetime",
"rememberDefaultChecked":"Check by default",
"rememberTimer":"Timer before automatic authentication",
"remoteCookieName":"Cookie 名稱",
"remoteGlobalStorage":"工作階段模組",
"remoteGlobalStorageOptions":"工作階段模組選項",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -7,8 +7,7 @@ use Exporter 'import';
our $VERSION = '2.0.14';
use constant HANDLER => 'Lemonldap::NG::Handler::PSGI::Main';
use constant URIRE =>
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]))*)))?))?)};
use constant URIRE => 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]))*)))?))?)};
use constant {
PE_IDPCHOICE => -5,
PE_SENDRESPONSE => -4,
@ -225,114 +224,7 @@ sub portalConsts {
}
# EXPORTER PARAMETERS
our @EXPORT_OK = (
'portalConsts',
'HANDLER',
'URIRE',
'PE_IDPCHOICE',
'PE_SENDRESPONSE',
'PE_INFO',
'PE_REDIRECT',
'PE_DONE',
'PE_OK',
'PE_SESSIONEXPIRED',
'PE_FORMEMPTY',
'PE_WRONGMANAGERACCOUNT',
'PE_USERNOTFOUND',
'PE_BADCREDENTIALS',
'PE_LDAPCONNECTFAILED',
'PE_LDAPERROR',
'PE_APACHESESSIONERROR',
'PE_FIRSTACCESS',
'PE_BADCERTIFICATE',
'PE_NO_PASSWORD_BE',
'PE_PP_ACCOUNT_LOCKED',
'PE_PP_PASSWORD_EXPIRED',
'PE_CERTIFICATEREQUIRED',
'PE_ERROR',
'PE_PP_CHANGE_AFTER_RESET',
'PE_PP_PASSWORD_MOD_NOT_ALLOWED',
'PE_PP_MUST_SUPPLY_OLD_PASSWORD',
'PE_PP_INSUFFICIENT_PASSWORD_QUALITY',
'PE_PP_PASSWORD_TOO_SHORT',
'PE_PP_PASSWORD_TOO_YOUNG',
'PE_PP_PASSWORD_IN_HISTORY',
'PE_PP_GRACE',
'PE_PP_EXP_WARNING',
'PE_PASSWORD_MISMATCH',
'PE_PASSWORD_OK',
'PE_NOTIFICATION',
'PE_BADURL',
'PE_NOSCHEME',
'PE_BADOLDPASSWORD',
'PE_MALFORMEDUSER',
'PE_SESSIONNOTGRANTED',
'PE_CONFIRM',
'PE_MAILFORMEMPTY',
'PE_BADMAILTOKEN',
'PE_MAILERROR',
'PE_MAILOK',
'PE_LOGOUT_OK',
'PE_SAML_ERROR',
'PE_SAML_LOAD_SERVICE_ERROR',
'PE_SAML_LOAD_IDP_ERROR',
'PE_SAML_SSO_ERROR',
'PE_SAML_UNKNOWN_ENTITY',
'PE_SAML_DESTINATION_ERROR',
'PE_SAML_CONDITIONS_ERROR',
'PE_SAML_IDPSSOINITIATED_NOTALLOWED',
'PE_SAML_SLO_ERROR',
'PE_SAML_SIGNATURE_ERROR',
'PE_SAML_ART_ERROR',
'PE_SAML_SESSION_ERROR',
'PE_SAML_LOAD_SP_ERROR',
'PE_SAML_ATTR_ERROR',
'PE_OPENID_EMPTY',
'PE_OPENID_BADID',
'PE_MISSINGREQATTR',
'PE_BADPARTNER',
'PE_MAILCONFIRMATION_ALREADY_SENT',
'PE_PASSWORDFORMEMPTY',
'PE_CAS_SERVICE_NOT_ALLOWED',
'PE_MAILFIRSTACCESS',
'PE_MAILNOTFOUND',
'PE_PASSWORDFIRSTACCESS',
'PE_MAILCONFIRMOK',
'PE_RADIUSCONNECTFAILED',
'PE_MUST_SUPPLY_OLD_PASSWORD',
'PE_FORBIDDENIP',
'PE_CAPTCHAERROR',
'PE_CAPTCHAEMPTY',
'PE_REGISTERFIRSTACCESS',
'PE_REGISTERFORMEMPTY',
'PE_REGISTERALREADYEXISTS',
'PE_NOTOKEN',
'PE_TOKENEXPIRED',
'PE_U2FFAILED',
'PE_UNAUTHORIZEDPARTNER',
'PE_RENEWSESSION',
'PE_WAIT',
'PE_MUSTAUTHN',
'PE_MUSTHAVEMAIL',
'PE_SAML_SERVICE_NOT_ALLOWED',
'PE_OIDC_SERVICE_NOT_ALLOWED',
'PE_OID_SERVICE_NOT_ALLOWED',
'PE_GET_SERVICE_NOT_ALLOWED',
'PE_IMPERSONATION_SERVICE_NOT_ALLOWED',
'PE_ISSUERMISSINGREQATTR',
'PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED',
'PE_BADOTP',
'PE_RESETCERTIFICATE_INVALID',
'PE_RESETCERTIFICATE_FORMEMPTY',
'PE_RESETCERTIFICATE_FIRSTACCESS',
'PE_PP_NOT_ALLOWED_CHARACTER',
'PE_PP_NOT_ALLOWED_CHARACTERS',
'PE_UPGRADESESSION',
'PE_NO_SECOND_FACTORS',
'PE_BAD_DEVOPS_FILE',
'PE_FILENOTFOUND',
'PE_OIDC_AUTH_ERROR'
);
our @EXPORT_OK = ( 'portalConsts', 'HANDLER', 'URIRE', 'PE_IDPCHOICE', 'PE_SENDRESPONSE', 'PE_INFO', 'PE_REDIRECT', 'PE_DONE', 'PE_OK', 'PE_SESSIONEXPIRED', 'PE_FORMEMPTY', 'PE_WRONGMANAGERACCOUNT', 'PE_USERNOTFOUND', 'PE_BADCREDENTIALS', 'PE_LDAPCONNECTFAILED', 'PE_LDAPERROR', 'PE_APACHESESSIONERROR', 'PE_FIRSTACCESS', 'PE_BADCERTIFICATE', 'PE_NO_PASSWORD_BE', 'PE_PP_ACCOUNT_LOCKED', 'PE_PP_PASSWORD_EXPIRED', 'PE_CERTIFICATEREQUIRED', 'PE_ERROR', 'PE_PP_CHANGE_AFTER_RESET', 'PE_PP_PASSWORD_MOD_NOT_ALLOWED', 'PE_PP_MUST_SUPPLY_OLD_PASSWORD', 'PE_PP_INSUFFICIENT_PASSWORD_QUALITY', 'PE_PP_PASSWORD_TOO_SHORT', 'PE_PP_PASSWORD_TOO_YOUNG', 'PE_PP_PASSWORD_IN_HISTORY', 'PE_PP_GRACE', 'PE_PP_EXP_WARNING', 'PE_PASSWORD_MISMATCH', 'PE_PASSWORD_OK', 'PE_NOTIFICATION', 'PE_BADURL', 'PE_NOSCHEME', 'PE_BADOLDPASSWORD', 'PE_MALFORMEDUSER', 'PE_SESSIONNOTGRANTED', 'PE_CONFIRM', 'PE_MAILFORMEMPTY', 'PE_BADMAILTOKEN', 'PE_MAILERROR', 'PE_MAILOK', 'PE_LOGOUT_OK', 'PE_SAML_ERROR', 'PE_SAML_LOAD_SERVICE_ERROR', 'PE_SAML_LOAD_IDP_ERROR', 'PE_SAML_SSO_ERROR', 'PE_SAML_UNKNOWN_ENTITY', 'PE_SAML_DESTINATION_ERROR', 'PE_SAML_CONDITIONS_ERROR', 'PE_SAML_IDPSSOINITIATED_NOTALLOWED', 'PE_SAML_SLO_ERROR', 'PE_SAML_SIGNATURE_ERROR', 'PE_SAML_ART_ERROR', 'PE_SAML_SESSION_ERROR', 'PE_SAML_LOAD_SP_ERROR', 'PE_SAML_ATTR_ERROR', 'PE_OPENID_EMPTY', 'PE_OPENID_BADID', 'PE_MISSINGREQATTR', 'PE_BADPARTNER', 'PE_MAILCONFIRMATION_ALREADY_SENT', 'PE_PASSWORDFORMEMPTY', 'PE_CAS_SERVICE_NOT_ALLOWED', 'PE_MAILFIRSTACCESS', 'PE_MAILNOTFOUND', 'PE_PASSWORDFIRSTACCESS', 'PE_MAILCONFIRMOK', 'PE_RADIUSCONNECTFAILED', 'PE_MUST_SUPPLY_OLD_PASSWORD', 'PE_FORBIDDENIP', 'PE_CAPTCHAERROR', 'PE_CAPTCHAEMPTY', 'PE_REGISTERFIRSTACCESS', 'PE_REGISTERFORMEMPTY', 'PE_REGISTERALREADYEXISTS', 'PE_NOTOKEN', 'PE_TOKENEXPIRED', 'PE_U2FFAILED', 'PE_UNAUTHORIZEDPARTNER', 'PE_RENEWSESSION', 'PE_WAIT', 'PE_MUSTAUTHN', 'PE_MUSTHAVEMAIL', 'PE_SAML_SERVICE_NOT_ALLOWED', 'PE_OIDC_SERVICE_NOT_ALLOWED', 'PE_OID_SERVICE_NOT_ALLOWED', 'PE_GET_SERVICE_NOT_ALLOWED', 'PE_IMPERSONATION_SERVICE_NOT_ALLOWED', 'PE_ISSUERMISSINGREQATTR', 'PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED', 'PE_BADOTP', 'PE_RESETCERTIFICATE_INVALID', 'PE_RESETCERTIFICATE_FORMEMPTY', 'PE_RESETCERTIFICATE_FIRSTACCESS', 'PE_PP_NOT_ALLOWED_CHARACTER', 'PE_PP_NOT_ALLOWED_CHARACTERS', 'PE_UPGRADESESSION', 'PE_NO_SECOND_FACTORS', 'PE_BAD_DEVOPS_FILE', 'PE_FILENOTFOUND', 'PE_OIDC_AUTH_ERROR' );
our %EXPORT_TAGS = ( 'all' => [ @EXPORT_OK, 'import' ], );
our @EXPORT = qw(import PE_OK);

View File

@ -15,6 +15,7 @@ has speChars => ( is => 'rw' );
has skinRules => ( is => 'rw' );
has stayConnected => ( is => 'rw', default => sub { 0 } );
has requireOldPwd => ( is => 'rw', default => sub { 1 } );
has rememberAuthChoice => ( is => 'rw', default => sub { 0 } );
sub displayInit {
my ($self) = @_;
@ -49,6 +50,14 @@ sub displayInit {
}
$self->stayConnected($rule);
$rule =
HANDLER->buildSub( HANDLER->substitute( $self->conf->{rememberAuthChoiceRule} ) );
unless ($rule) {
my $error = HANDLER->tsv->{jail}->error || 'Unable to compile rule';
$self->logger->error("Bad rememberAuthChoiceRule rule: $error");
}
$self->rememberAuthChoice($rule);
my $speChars =
$self->conf->{passwordPolicySpecialChar} eq '__ALL__'
? ''
@ -412,6 +421,14 @@ sub display {
? ( STAYCONNECTED => 1 )
: ()
),
(
$self->rememberAuthChoice->( $req, $req->sessionInfo )
? ( REMEMBERAUTHCHOICE => 1 )
: ()
),
REMEMBERAUTHCHOICEDEFAULTCHECKED => $self->conf->{rememberDefaultChecked} || 0,
REMEMBERAUTHCHOICECOOKIENAME => $self->conf->{rememberCookieName} || 'llngrememberauthchoice',
REMEMBERAUTHCHOICETIMER => $self->conf->{rememberTimer} || 5,
(
$req->data->{customScript}
? ( CUSTOM_SCRIPT => $req->data->{customScript} )

View File

@ -19,6 +19,7 @@ our @pList = (
portalStatus => '::Plugins::Status',
cda => '::Plugins::CDA',
notification => '::Plugins::Notifications',
rememberAuthChoiceRule => '::Plugins::RememberAuthChoice',
stayConnected => '::Plugins::StayConnected',
portalCheckLogins => '::Plugins::History',
bruteForceProtection => '::Plugins::BruteForceProtection',

View File

@ -0,0 +1,146 @@
# Plugin to remember which authentication method has been chosen,
# and laun it automatically
package Lemonldap::NG::Portal::Plugins::RememberAuthChoice;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_SENDRESPONSE
);
our $VERSION = '2.0.15';
extends 'Lemonldap::NG::Portal::Main::Plugin';
# INTERFACE
use constant endAuth => 'storeRememberedAuthChoice';
use constant beforeAuth => 'checkRememberedAuthChoice';
has rule => ( is => 'rw', default => sub { 0 } );
has rememberDefaultChecked => (
is => 'rw',
lazy => 1,
default => sub {
$_[0]->conf->{rememberDefaultChecked} || 0;
}
);
has rememberTimer => (
is => 'rw',
lazy => 1,
default => sub {
$_[0]->conf->{rememberTimer} || 5;
}
);
has rememberCookieName => (
is => 'rw',
lazy => 1,
default => sub {
$_[0]->conf->{rememberCookieName} || 'llngrememberauthchoice';
}
);
# Default timeout: 1 year
has rememberCookieTimeout => (
is => 'rw',
lazy => 1,
default => sub {
$_[0]->conf->{rememberCookieTimeout} || 31536000;
}
);
sub init
{
my ($self) = @_;
# Parse activation rule
$self->rule(
$self->p->buildRule( $self->conf->{rememberAuthChoiceRule}, 'rememberAuthChoiceRule' ) );
return 0 unless $self->rule;
return 1;
}
sub storeRememberedAuthChoice
{
my ( $self, $req ) = @_;
# Get directly authentication choice from sessionInfo
my $lmAuth = $req->sessionInfo->{_choice};
# Get rememberauthchoice tick from corresponding hash
# * req->pdata for Issuer auth modules (SAML, OIDC,...)
# * req->data for direct auth modules (LDAP)
my $rememberauthchoice = $req->pdata->{rememberauthchoice} ||
$req->data->{rememberauthchoice} ||
"";
if( $lmAuth )
{
# Store cookie to remember the authentication choice
if( $rememberauthchoice eq "true" )
{
$self->logger->warn("RememberAuthChoice: set cookie " .
$self->rememberCookieName .
" with authentication choice lmAuth=" .
$lmAuth
);
$req->addCookie(
$self->p->cookie(
name => $self->rememberCookieName,
value => $lmAuth,
max_age => $self->rememberCookieTimeout,
secure => $self->conf->{securedCookie},
HttpOnly => 0, # required for cookie to be read by js
)
);
}
# Remove cookie to forget previous authentication choice
else
{
$self->logger->warn("RememberAuthChoice: Remove cookie " .
$self->rememberCookieName );
$req->addCookie(
$self->p->cookie(
name => $self->rememberCookieName,
value => 0,
expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
secure => $self->conf->{securedCookie},
)
);
}
}
return PE_OK;
}
sub checkRememberedAuthChoice
{
my ( $self, $req ) = @_;
# Check if form has been sent with a rememberauthchoice tick
my $lmAuth = $req->param('lmAuth') || "" ;
my $rememberauthchoice = $req->param('rememberauthchoice') || "" ;
# If so, store rememberauthchoice tick for the endAuth endpoint
if( $lmAuth )
{
# For authentication method occurring in the same request
$req->data->{rememberauthchoice} = $rememberauthchoice;
# For authentication method occurring in a different request
$req->pdata->{rememberauthchoice} = $rememberauthchoice;
}
return PE_OK;
}
1;

View File

@ -216,3 +216,9 @@ div.input-group > p.form-control > label {
user-select: none;
cursor: pointer;
}
/* Hide "remember my authentication choice" timer */
div#remembertimer {
display: none;
}

View File

@ -1 +1 @@
html,body{height:100%;background:radial-gradient(circle at 50% 0,#fff 0,#ddd 100%) no-repeat scroll 0 0 #ddd}#wrap{min-height:100%;height:auto;margin:0 auto -80px;padding:20px 0 80px}#footer{height:80px;background-color:#fff;background-color:rgba(255,255,255,0.9);text-align:center;padding-top:10px;overflow:hidden}#header img{background-color:#fff;background-color:rgba(255,255,255,0.8);margin-bottom:20px}.card,.navbar-light{background-color:#fff;background-color:rgba(255,255,255,0.9);background-image:none}.login,.password{text-align:center;padding:20px}div.form{margin:0 auto;max-width:330px}div.actions{margin:10px 0 0 0}div.actions a{margin-top:10px}div.actions button{margin-top:10px}.buttons{text-align:center;margin:10px 0 0 0;cursor:pointer}.btn{white-space:normal}.btn span.fa{padding-right:8px}li.ui-state-active{background-color:#fafafa;background-color:rgba(250,250,250,0.9)}#appslist,#password,#loginHistory,#logout,#oidcConsents{margin-top:20px}div.category{margin:10px 0;cursor:grab}div.application{margin:5px 0;overflow:hidden}div.application a,div.application a:hover{text-decoration:none}p.notifCheck label{margin-left:5px;margin-top:3px;display:inline-block}.notif div.form{margin 0 auto;max-width:1024px}.notif .h2,h2{font-size:1.6rem;font-weght:bold;text-align:center}.notif .h3,h3{margin-top:30px;margin-bottom:30px;font-size:1.2rem}.notif .card-title{font-size:1.7rem}img.langicon{cursor:pointer}button.idploop{max-width:300px}button.idploop img{max-height:30px}div.oidc_consent_message>ul{text-align:left;list-style:circle}@media(min-width:768px){div.application{height:80px}div.application h4.appname{margin:0}#wrap{margin:0 auto -60px}#footer{height:60px}}.hiddenFrame{border:0;display:hidden;margin:0}.noborder{border:0}.max{width:100%}.link{cursor:pointer}.nodecor:hover,.nodecor:active,.nodecor:focus{text-decoration:none}.fa.icon-blue{color:blue}.progress-bar-animated{width:100%}input.key{font-family:'password';width:100px}@font-face{font-family:'password';src:url(/static/common/fonts/password.ttf)}.info.table caption{color:black;text-align:center;caption-side:bottom}div.input-group>p.form-control{height:auto}div.input-group>p.form-control>label{display:revert;user-select:none;cursor:pointer}
html,body{height:100%;background:radial-gradient(circle at 50% 0,#fff 0,#ddd 100%) no-repeat scroll 0 0 #ddd}#wrap{min-height:100%;height:auto;margin:0 auto -80px;padding:20px 0 80px}#footer{height:80px;background-color:#fff;background-color:rgba(255,255,255,0.9);text-align:center;padding-top:10px;overflow:hidden}#header img{background-color:#fff;background-color:rgba(255,255,255,0.8);margin-bottom:20px}.card,.navbar-light{background-color:#fff;background-color:rgba(255,255,255,0.9);background-image:none}.login,.password{text-align:center;padding:20px}div.form{margin:0 auto;max-width:330px}div.actions{margin:10px 0 0 0}div.actions a{margin-top:10px}div.actions button{margin-top:10px}.buttons{text-align:center;margin:10px 0 0 0;cursor:pointer}.btn{white-space:normal}.btn span.fa{padding-right:8px}li.ui-state-active{background-color:#fafafa;background-color:rgba(250,250,250,0.9)}#appslist,#password,#loginHistory,#logout,#oidcConsents{margin-top:20px}div.category{margin:10px 0;cursor:grab}div.application{margin:5px 0;overflow:hidden}div.application a,div.application a:hover{text-decoration:none}p.notifCheck label{margin-left:5px;margin-top:3px;display:inline-block}.notif div.form{margin 0 auto;max-width:1024px}.notif .h2,h2{font-size:1.6rem;font-weght:bold;text-align:center}.notif .h3,h3{margin-top:30px;margin-bottom:30px;font-size:1.2rem}.notif .card-title{font-size:1.7rem}img.langicon{cursor:pointer}button.idploop{max-width:300px}button.idploop img{max-height:30px}div.oidc_consent_message>ul{text-align:left;list-style:circle}@media(min-width:768px){div.application{height:80px}div.application h4.appname{margin:0}#wrap{margin:0 auto -60px}#footer{height:60px}}.hiddenFrame{border:0;display:hidden;margin:0}.noborder{border:0}.max{width:100%}.link{cursor:pointer}.nodecor:hover,.nodecor:active,.nodecor:focus{text-decoration:none}.fa.icon-blue{color:blue}.progress-bar-animated{width:100%}input.key{font-family:'password';width:100px}@font-face{font-family:'password';src:url(/static/common/fonts/password.ttf)}.info.table caption{color:black;text-align:center;caption-side:bottom}div.input-group>p.form-control{height:auto}div.input-group>p.form-control>label{display:revert;user-select:none;cursor:pointer}div#remembertimer{display: none;}

View File

@ -47,5 +47,78 @@ $(window).on("load", function() {
$('.nav-item').attr( "tabIndex", 0 );
});
// tick all checkboxes remembering the authentication choice
// when global checkbox is clicked
$("#globalrememberauthchoice").change(function() {
var checked = this.checked;
$( 'input[name="rememberauthchoice"]' ).each(function() {
$( this ).val(checked);
});
});
// if rememberStopped button has been clicked, stop the timer
// from lauching the previously remembered authentication
$("#buttonRememberStopped").click(function() {
var curval = $( "input#rememberStopped" ).val();
var newval;
if( curval != "stopped" )
{
newval = "stopped";
}
else
{
newval = "running";
window.setTimeout( launchAuthenticationChoice, 1000 );
}
// store the new value
$( "input#rememberStopped" ).val(newval);
});
// function running the previously remembered authentication choice
// when the timer is over
function launchAuthenticationChoice()
{
var timer = $( "div#remembertimer p span" ).text();
var isStopped = $( "input#rememberStopped" ).val();
if ( isStopped != "stopped" )
{
if ( timer > 0 )
{
timer--;
// display decremented timer in the appropriate html element
$( "div#remembertimer p span" ).text(timer);
// wait for another 1s
window.setTimeout( launchAuthenticationChoice, 1000 );
}
else
{
// launch authentication choice defined in cookie
var choiceform = "#" + $.cookie(rememberCookieName) + " form";
$( choiceform ).submit();
}
}
};
// Check rememberauthchoice cookie
var rememberCookieName = $( "#rememberCookieName" ).val();
var errorCode = $( "#errormsg div span" ).attr("trmsg");
// if this is first access
if( errorCode == 9 )
{
// if there is a rememberauthchoice cookie
if ( ! ( typeof rememberCookieName === 'undefined' ) &&
! ( typeof $.cookie(rememberCookieName) === 'undefined' )
)
{
// show timer
$( "div#remembertimer" ).show();
// launch remembered authentication choice when timer reaches 0
window.setTimeout( launchAuthenticationChoice, 1000 );
}
}
});

View File

@ -1 +1 @@
$(window).on("load",function(){$("div.message-positive").addClass("alert-success"),$("div.message-warning").addClass("alert-warning"),$("div.message-negative").addClass("alert-danger"),$("table.info").addClass("table"),$(".notifCheck").addClass("checkbox"),$('.collapse li[class!="dropdown"]').on("click",function(){$(".navbar-toggler").hasClass("collapsed")||$(".navbar-toggler").trigger("click")}),$("#authMenu .nav-link").on("click",function(a){window.datas.choicetab=a.target.hash.substr(1)}),$("#remove2fModal").on("show.bs.modal",function(a){var t=$(a.relatedTarget),e=t.attr("device"),n=t.attr("epoch"),i=$(this);i.find(".remove2f").attr("device",e),i.find(".remove2f").attr("epoch",n)}),$(".nav-item").click(function(){$(".nav-item").attr("tabIndex",0)}),$(".nav-item").focusin(function(){$(".nav-item").attr("tabIndex",0)}),$(".nav-item").focusout(function(){$(".nav-item").attr("tabIndex",0)})});
$(window).on("load",function(){function t(){var e=$("div#remembertimer p span").text();"stopped"!=$("input#rememberStopped").val()&&(0<e?(e--,$("div#remembertimer p span").text(e),window.setTimeout(t,1e3)):(e="#"+$.cookie(a)+" form",$(e).submit()))}$("div.message-positive").addClass("alert-success"),$("div.message-warning").addClass("alert-warning"),$("div.message-negative").addClass("alert-danger"),$("table.info").addClass("table"),$(".notifCheck").addClass("checkbox"),$('.collapse li[class!="dropdown"]').on("click",function(){$(".navbar-toggler").hasClass("collapsed")||$(".navbar-toggler").trigger("click")}),$("#authMenu .nav-link").on("click",function(e){window.datas.choicetab=e.target.hash.substr(1)}),$("#remove2fModal").on("show.bs.modal",function(e){var t=$(e.relatedTarget),a=t.attr("device"),e=t.attr("epoch"),t=$(this);t.find(".remove2f").attr("device",a),t.find(".remove2f").attr("epoch",e)}),$(".nav-item").click(function(){$(".nav-item").attr("tabIndex",0)}),$(".nav-item").focusin(function(){$(".nav-item").attr("tabIndex",0)}),$(".nav-item").focusout(function(){$(".nav-item").attr("tabIndex",0)}),$("#globalrememberauthchoice").change(function(){var e=this.checked;$('input[name="rememberauthchoice"]').each(function(){$(this).val(e)})}),$("#buttonRememberStopped").click(function(){var e;"stopped"!=$("input#rememberStopped").val()?e="stopped":(e="running",window.setTimeout(t,1e3)),$("input#rememberStopped").val(e)});var a=$("#rememberCookieName").val();9==$("#errormsg div span").attr("trmsg")&&void 0!==a&&void 0!==$.cookie(a)&&($("div#remembertimer").show(),window.setTimeout(t,1e3))});

View File

@ -1 +1 @@
{"version":3,"sources":["skin.js"],"names":["$","window","on","addClass","hasClass","trigger","e","datas","choicetab","target","hash","substr","event","button","relatedTarget","device","attr","epoch","modal","this","find","click","focusin","focusout"],"mappings":"AAAAA,EAAEC,QAAQC,GAAG,OAAQ,WAGnBF,EAAE,wBAAwBG,SAAS,iBACnCH,EAAE,uBAAuBG,SAAS,iBAClCH,EAAE,wBAAwBG,SAAS,gBAEnCH,EAAE,cAAcG,SAAS,SAEzBH,EAAE,eAAeG,SAAS,YAG1BH,EAAE,mCAAmCE,GAAG,QAAS,WAC1CF,EAAE,mBAAmBI,SAAS,cACjCJ,EAAE,mBAAmBK,QAAQ,WAKjCL,EAAE,uBAAuBE,GAAG,QAAS,SAAUI,GAC3CL,OAAOM,MAAMC,UAAYF,EAAEG,OAAOC,KAAKC,OAAO,KAIlDX,EAAE,kBAAkBE,GAAG,gBAAiB,SAAUU,GAClD,IAAIC,EAASb,EAAEY,EAAME,eACjBC,EAASF,EAAOG,KAAK,UACrBC,EAAQJ,EAAOG,KAAK,SACpBE,EAAQlB,EAAEmB,MAGdD,EAAME,KAAK,aAAaJ,KAAK,SAAUD,GACvCG,EAAME,KAAK,aAAaJ,KAAK,QAASC,KAOtCjB,EAAE,aAAaqB,MAAM,WACnBrB,EAAE,aAAagB,KAAM,WAAY,KAEnChB,EAAE,aAAasB,QAAQ,WACrBtB,EAAE,aAAagB,KAAM,WAAY,KAEnChB,EAAE,aAAauB,SAAS,WACtBvB,EAAE,aAAagB,KAAM,WAAY"}
{"version":3,"sources":["skin.js"],"names":["$","window","on","launchAuthenticationChoice","timer","text","val","setTimeout","choiceform","cookie","rememberCookieName","submit","addClass","hasClass","trigger","e","datas","choicetab","target","hash","substr","event","button","relatedTarget","device","attr","epoch","modal","this","find","click","focusin","focusout","change","checked","each","newval","show"],"mappings":"AAAAA,EAAEC,QAAQC,GAAG,OAAQ,WA8EnB,SAASC,IAGL,IAAIC,EAAQJ,EAAG,4BAA6BK,OAG1B,WAFFL,EAAG,yBAA0BM,QAI5B,EAARF,GAEDA,IAEAJ,EAAG,4BAA6BK,KAAKD,GAErCH,OAAOM,WAAYJ,EAA4B,OAK3CK,EAAa,IAAMR,EAAES,OAAOC,GAAsB,QACtDV,EAAGQ,GAAaG,WA/F5BX,EAAE,wBAAwBY,SAAS,iBACnCZ,EAAE,uBAAuBY,SAAS,iBAClCZ,EAAE,wBAAwBY,SAAS,gBAEnCZ,EAAE,cAAcY,SAAS,SAEzBZ,EAAE,eAAeY,SAAS,YAG1BZ,EAAE,mCAAmCE,GAAG,QAAS,WAC1CF,EAAE,mBAAmBa,SAAS,cACjCb,EAAE,mBAAmBc,QAAQ,WAKjCd,EAAE,uBAAuBE,GAAG,QAAS,SAAUa,GAC3Cd,OAAOe,MAAMC,UAAYF,EAAEG,OAAOC,KAAKC,OAAO,KAIlDpB,EAAE,kBAAkBE,GAAG,gBAAiB,SAAUmB,GAClD,IAAIC,EAAStB,EAAEqB,EAAME,eACjBC,EAASF,EAAOG,KAAK,UACrBC,EAAQJ,EAAOG,KAAK,SACpBE,EAAQ3B,EAAE4B,MAGdD,EAAME,KAAK,aAAaJ,KAAK,SAAUD,GACvCG,EAAME,KAAK,aAAaJ,KAAK,QAASC,KAOtC1B,EAAE,aAAa8B,MAAM,WACnB9B,EAAE,aAAayB,KAAM,WAAY,KAEnCzB,EAAE,aAAa+B,QAAQ,WACrB/B,EAAE,aAAayB,KAAM,WAAY,KAEnCzB,EAAE,aAAagC,SAAS,WACtBhC,EAAE,aAAayB,KAAM,WAAY,KAKnCzB,EAAE,6BAA6BiC,OAAO,WAClC,IAAIC,EAAUN,KAAKM,QACnBlC,EAAG,oCAAqCmC,KAAK,WACzCnC,EAAG4B,MAAOtB,IAAI4B,OAMtBlC,EAAE,0BAA0B8B,MAAM,WAC9B,IACIM,EACU,WAFDpC,EAAG,yBAA0BM,MAItC8B,EAAS,WAITA,EAAS,UACTnC,OAAOM,WAAYJ,EAA4B,MAGnDH,EAAG,yBAA0BM,IAAI8B,KAiCrC,IAAI1B,EAAqBV,EAAG,uBAAwBM,MAGnC,GAFDN,EAAG,sBAAuByB,KAAK,eAKH,IAAvBf,QACiC,IAAjCV,EAAES,OAAOC,KAItBV,EAAG,qBAAsBqC,OAEzBpC,OAAOM,WAAYJ,EAA4B"}

View File

@ -263,6 +263,7 @@
"register":"Register",
"registerRequestAlreadyIssued":"تم إصدار طلب تسجيل لهذا الحساب من قبل",
"rememberChoice":"تذكر اختياري",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"إزالة الجلسات الأخرى",
"renewSession":"Renew session",

View File

@ -263,6 +263,7 @@
"register":"Registrieren",
"registerRequestAlreadyIssued":"Eine Registrierungsanforderung für dieses Konto wurde bereits gestellt am",
"rememberChoice":"Meine Auswahl merken",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"Andere Sitzungen löschen",
"renewSession":"Renew session",

View File

@ -263,6 +263,7 @@
"register":"Register",
"registerRequestAlreadyIssued":"A register request for this account was already issued on ",
"rememberChoice":"Remember my choice",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"Remove other sessions",
"renewSession":"Renew session",

View File

@ -263,6 +263,7 @@
"register":"Registrar",
"registerRequestAlreadyIssued":"Ya fue expedida una solicitud de registro para esta cuenta",
"rememberChoice":"Recordar mi elección",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"Suprimir las otras sesiones",
"renewSession":"Renew session",

View File

@ -263,6 +263,7 @@
"register":"Rekisteröidy",
"registerRequestAlreadyIssued":"Tämän käyttäjätilin rekisteröintipyyntö lähetettiin jo laitteelta ",
"rememberChoice":"Muista valintani",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"Tätä toimenpidettä ei voi perua",
"removeOtherSessions":"Poista muut istunnot",
"renewSession":"Uudista istunto",

View File

@ -263,6 +263,7 @@
"register":"Enregistrer",
"registerRequestAlreadyIssued":"Une demande de création pour ce compte a déjà été faite le ",
"rememberChoice":"Se souvenir de mon choix",
"rememberTimerLabel":"s avant authentification automatique",
"remove2fWarning":"Cette action est définitive",
"removeOtherSessions":"Fermer les autres sessions",
"renewSession":"Renouveller la session",

View File

@ -263,6 +263,7 @@
"register":"הרשמה",
"registerRequestAlreadyIssued":"כבר הוגשה בקשה לרישום החשבון הזה ב־",
"rememberChoice":"שמירת הבחירה שלי",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"פעולה זו אינה הפיכה",
"removeOtherSessions":"הסרת הפעלות אחרות",
"renewSession":"חידוש הפעלה",

View File

@ -263,6 +263,7 @@
"register":"Registra",
"registerRequestAlreadyIssued":"Una richiesta di registrazione per questo conto é già stata rilasciata il",
"rememberChoice":"Ricordarsi della mia scelta",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"Rimuovere altre sessioni",
"renewSession":"Renew session",

View File

@ -263,6 +263,7 @@
"register":"Zarejestruj",
"registerRequestAlreadyIssued":"Wniosek o rejestrację tego konta został już złożony w dniu ",
"rememberChoice":"Zapamiętaj mój wybór",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"Tej operacji nie można cofnąć",
"removeOtherSessions":"Usuń inne sesje",
"renewSession":"Odnów sesję",

View File

@ -263,6 +263,7 @@
"register":"Registrar",
"registerRequestAlreadyIssued":"Um pedido de registro para esta conta já foi emitido em",
"rememberChoice":"Lembre-se da minha escolha",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"Esta operação não pode ser desfeita",
"removeOtherSessions":"Remover outras sessões",
"renewSession":"Renovar sessão",

View File

@ -263,6 +263,7 @@
"register":"Registrar",
"registerRequestAlreadyIssued":"Um pedido de registro para esta conta já foi emitido em",
"rememberChoice":"Lembre-se da minha escolha",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"Esta operação não pode ser desfeita",
"removeOtherSessions":"Remover outras sessões",
"renewSession":"Renovar sessão",

View File

@ -263,6 +263,7 @@
"register":"Kaydol",
"registerRequestAlreadyIssued":"Bu hesap için kayıt olma isteği zaten şu tarihte alındı:",
"rememberChoice":"Seçimimi hatırla",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"Bu işlem geri alınamaz",
"removeOtherSessions":"Diğer oturumları sil",
"renewSession":"Oturumu yenile",

View File

@ -263,6 +263,7 @@
"register":"Đăng ký",
"registerRequestAlreadyIssued":"Yêu cầu đăng ký cho tài khoản này đã được cấp phát",
"rememberChoice":"Hãy nhớ sự lựa chọn của tôi",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"Xóa các phiên khác",
"renewSession":"Renew session",

View File

@ -263,6 +263,7 @@
"register":"注册",
"registerRequestAlreadyIssued":"此账户已存在一个注册请求",
"rememberChoice":"记住我的选择",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"移除其他会话",
"renewSession":"更新工作階段",

View File

@ -263,6 +263,7 @@
"register":"註冊",
"registerRequestAlreadyIssued":"此帳號的註冊請求已發出",
"rememberChoice":"記住我的選擇",
"rememberTimerLabel":"s before automatic authentication",
"remove2fWarning":"This operation cannot be undone",
"removeOtherSessions":"移除其他工作階段",
"renewSession":"更新工作階段",

View File

@ -66,6 +66,12 @@
<TMPL_IF NAME="sslform">
<TMPL_INCLUDE NAME="sslformChoice.tpl">
<!-- Remember my authentication choice for this module -->
<TMPL_IF NAME="REMEMBERAUTHCHOICE">
<input type="hidden" id="rememberauthchoice" name="rememberauthchoice" value="<TMPL_IF NAME="REMEMBERAUTHCHOICEDEFAULTCHECKED">true</TMPL_IF>" />
</TMPL_IF>
</TMPL_IF>
<TMPL_IF NAME="gpgform">
@ -92,6 +98,11 @@
</div>
<!-- Remember my authentication choice for this module -->
<TMPL_IF NAME="REMEMBERAUTHCHOICE">
<input type="hidden" id="rememberauthchoice" name="rememberauthchoice" value="<TMPL_IF NAME="REMEMBERAUTHCHOICEDEFAULTCHECKED">true</TMPL_IF>" />
</TMPL_IF>
</TMPL_IF>
</form>
@ -104,6 +115,30 @@
</div> <!-- end authMenu -->
<TMPL_IF NAME="REMEMBERAUTHCHOICE">
<!-- Timer + stop button for triggering the remembered authentication choice -->
<div id="remembertimer" class="col-md-6 offset-md-3">
<p class="form-control">
<span><TMPL_VAR NAME="REMEMBERAUTHCHOICETIMER"></span>
<label id="rememberTimerLabel" trspan="rememberTimerLabel">s before automatic authentication</label>
<button id="buttonRememberStopped" class="btn"><i class="fa fa-stop-circle-o"></i> Stop</button>
<input id="rememberStopped" name="rememberStopped" type="hidden" value="">
</p>
</div>
<!-- Global checkbox for remembering the authentication choice for all modules -->
<div class="input-group col-md-6 offset-md-3">
<div class="input-group-prepend">
<div class="input-group-text">
<input type="checkbox" id="globalrememberauthchoice" name="globalrememberauthchoice" aria-describedby="globalrememberauthchoiceLabel" <TMPL_IF NAME="REMEMBERAUTHCHOICEDEFAULTCHECKED">checked</TMPL_IF> />
<input id="rememberCookieName" name="rememberCookieName" type="hidden" value="<TMPL_VAR NAME="REMEMBERAUTHCHOICECOOKIENAME">">
</div>
</div>
<p class="form-control">
<label id="globalrememberauthchoiceLabel" for="globalrememberauthchoice" trspan="rememberChoice">Remember my choice</label>
</p>
</div>
</TMPL_IF>
</TMPL_IF>
<TMPL_IF NAME="DISPLAY_FORM">

View File

@ -0,0 +1,74 @@
use Test::More;
use strict;
use IO::String;
require 't/test-lib.pm';
my $res;
my $maintests = 7;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
authentication => 'Choice',
userDB => 'Same',
passwordDB => 'Choice',
authChoiceParam => 'lmAuth',
authChoiceModules => {
slavechoice => 'Slave;Demo;Demo',
},
slaveUserHeader => 'userid',
slaveDisplayLogo => 1,
rememberAuthChoiceRule => 1,
rememberCookieName => "llngrememberauthchoice",
rememberCookieTimeout => 31536000,
rememberDefaultChecked => 0,
rememberTimer => 10,
}
}
);
# Check web form
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get authentication portal' );
my @form = ( $res->[2]->[0] =~ m#<form.*?</form>#sg );
ok( @form == 1, 'Display 1 choice' ) or explain( scalar(@form), 1 );
expectForm( [ $res->[0], $res->[1], [ $form[0] ] ], undef, undef, 'lmAuth' );
ok( $form[0] =~ /input type="hidden" id="rememberauthchoice"/ );
# authentication with rememberauthchoice enabled
ok(
$res = $client->_get( '/',
'accept' => 'text/html',
'query' => 'lmAuth=slavechoice&rememberauthchoice=true',
'custom' => { 'HTTP_USERID' => 'dwho' }
),
'Auth query with rememberauthchoice enabled'
);
my $id = expectCookie( $res );
my $remember = expectCookie( $res, "llngrememberauthchoice" );
ok( $remember eq "slavechoice", 'Get cookie with authentication' );
$client->logout($id);
# authentication with rememberauthchoice disabled
ok(
$res = $client->_get( '/',
'accept' => 'text/html',
'query' => 'lmAuth=slavechoice&rememberauthchoice=false',
'custom' => { 'HTTP_USERID' => 'dwho' }
),
'Auth query with rememberauthchoice disabled'
);
$id = expectCookie( $res );
$remember = expectCookie( $res, "llngrememberauthchoice" );
ok( $remember eq "0", 'Get cookie removal' );
$client->logout($id);
count($maintests);
clean_sessions();
done_testing( count() );