Merge branch 'v2.0'
This commit is contained in:
commit
9ac5834bfe
|
@ -24,7 +24,7 @@ use constant MANAGERSECTION => "manager";
|
|||
use constant SESSIONSEXPLORERSECTION => "sessionsExplorer";
|
||||
use constant APPLYSECTION => "apply";
|
||||
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node)|S(?:erviceMetaDataAuthnContext|torageOptions))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars)|c(?:as(?:S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions)|A(?:ppMetaData(?:(?:ExportedVar|Option)s|Node)|ttributes))|(?:ustomAddParam|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
|
||||
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|howLanguages|slByAjax)|o(?:idc(?:ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|RPMetaDataOptions(?:LogoutSessionRequired|BypassConsent|RequirePKCE|Public)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:ErrorOn(?:ExpiredSession|MailNotFound)|DisplayRe(?:setPassword|gister)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl)|oginHistoryEnabled)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|orsEnabled|da)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|no(?:tif(?:ication(?:Server)?|y(?:Deleted|Other))|AjaxHook)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|rest(?:(?:Session|Config)Server|ExportSecretKeys)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs)|dbiDynamicHashEnabled|bruteForceProtection)$/;
|
||||
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|howLanguages|slByAjax)|o(?:idc(?:ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|RPMetaDataOptions(?:LogoutSessionRequired|BypassConsent|RequirePKCE|Public)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:ErrorOn(?:ExpiredSession|MailNotFound)|DisplayRe(?:setPassword|gister)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl)|oginHistoryEnabled)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|orsEnabled|da)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|no(?:tif(?:ication(?:Server)?|y(?:Deleted|Other))|AjaxHook)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|rest(?:(?:Session|Config)Server|ExportSecretKeys)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs)|dbiDynamicHashEnabled|bruteForceProtection)$/;
|
||||
|
||||
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ sub defaultValues {
|
|||
'casAccessControlPolicy' => 'none',
|
||||
'casAuthnLevel' => 1,
|
||||
'checkTime' => 600,
|
||||
'checkUserHiddenAttributes' => '_2fDevices _loginHistory hGroups',
|
||||
'checkUserHiddenAttributes' => '_loginHistory hGroups',
|
||||
'checkUserIdRule' => 1,
|
||||
'checkXSS' => 1,
|
||||
'confirmFormMethod' => 'post',
|
||||
|
@ -78,7 +78,7 @@ sub defaultValues {
|
|||
'groups' => {},
|
||||
'handlerInternalCache' => 15,
|
||||
'handlerServiceTokenTTL' => 30,
|
||||
'hiddenAttributes' => '_password',
|
||||
'hiddenAttributes' => '_password _2fDevices',
|
||||
'httpOnly' => 1,
|
||||
'https' => -1,
|
||||
'impersonationHiddenAttributes' => '_2fDevices _loginHistory',
|
||||
|
@ -279,43 +279,47 @@ sub defaultValues {
|
|||
'samlSPSSODescriptorWantAssertionsSigned' => 1,
|
||||
'securedCookie' => 0,
|
||||
'sfEngine' => '::2F::Engines::Default',
|
||||
'sfRemovedMsg' => 0,
|
||||
'sfRequired' => 0,
|
||||
'showLanguages' => 1,
|
||||
'slaveAuthnLevel' => 2,
|
||||
'slaveExportedVars' => {},
|
||||
'SMTPServer' => '',
|
||||
'SMTPTLS' => '',
|
||||
'SSLAuthnLevel' => 5,
|
||||
'SSLVar' => 'SSL_CLIENT_S_DN_Email',
|
||||
'SSLVarIf' => {},
|
||||
'successLoginNumber' => 5,
|
||||
'timeout' => 72000,
|
||||
'timeoutActivity' => 0,
|
||||
'timeoutActivityInterval' => 60,
|
||||
'totp2fActivation' => 0,
|
||||
'totp2fDigits' => 6,
|
||||
'totp2fInterval' => 30,
|
||||
'totp2fRange' => 1,
|
||||
'totp2fSelfRegistration' => 0,
|
||||
'totp2fUserCanRemoveKey' => 1,
|
||||
'twitterAuthnLevel' => 1,
|
||||
'twitterUserField' => 'screen_name',
|
||||
'u2fActivation' => 0,
|
||||
'u2fSelfRegistration' => 0,
|
||||
'u2fUserCanRemoveKey' => 1,
|
||||
'upgradeSession' => 1,
|
||||
'userControl' => '^[\\w\\.\\-@]+$',
|
||||
'userDB' => 'Same',
|
||||
'useRedirectOnError' => 1,
|
||||
'useSafeJail' => 1,
|
||||
'utotp2fActivation' => 0,
|
||||
'viewerHiddenKeys' => 'samlIDPMetaDataNodes samlSPMetaDataNodes',
|
||||
'webIDAuthnLevel' => 1,
|
||||
'webIDExportedVars' => {},
|
||||
'whatToTrace' => 'uid',
|
||||
'yubikey2fActivation' => 0,
|
||||
'yubikey2fPublicIDSize' => 12,
|
||||
'sfRemovedMsgRule' => 0,
|
||||
'sfRemovedNotifMsg' =>
|
||||
'_removedSF_ expired second factor(s) has/have been removed!',
|
||||
'sfRemovedNotifRef' => 'RemoveSF',
|
||||
'sfRemovedNotifTitle' => 'Second factor notification',
|
||||
'sfRequired' => 0,
|
||||
'showLanguages' => 1,
|
||||
'slaveAuthnLevel' => 2,
|
||||
'slaveExportedVars' => {},
|
||||
'SMTPServer' => '',
|
||||
'SMTPTLS' => '',
|
||||
'SSLAuthnLevel' => 5,
|
||||
'SSLVar' => 'SSL_CLIENT_S_DN_Email',
|
||||
'SSLVarIf' => {},
|
||||
'successLoginNumber' => 5,
|
||||
'timeout' => 72000,
|
||||
'timeoutActivity' => 0,
|
||||
'timeoutActivityInterval' => 60,
|
||||
'totp2fActivation' => 0,
|
||||
'totp2fDigits' => 6,
|
||||
'totp2fInterval' => 30,
|
||||
'totp2fRange' => 1,
|
||||
'totp2fSelfRegistration' => 0,
|
||||
'totp2fUserCanRemoveKey' => 1,
|
||||
'twitterAuthnLevel' => 1,
|
||||
'twitterUserField' => 'screen_name',
|
||||
'u2fActivation' => 0,
|
||||
'u2fSelfRegistration' => 0,
|
||||
'u2fUserCanRemoveKey' => 1,
|
||||
'upgradeSession' => 1,
|
||||
'userControl' => '^[\\w\\.\\-@]+$',
|
||||
'userDB' => 'Same',
|
||||
'useRedirectOnError' => 1,
|
||||
'useSafeJail' => 1,
|
||||
'utotp2fActivation' => 0,
|
||||
'viewerHiddenKeys' => 'samlIDPMetaDataNodes samlSPMetaDataNodes',
|
||||
'webIDAuthnLevel' => 1,
|
||||
'webIDExportedVars' => {},
|
||||
'whatToTrace' => 'uid',
|
||||
'yubikey2fActivation' => 0,
|
||||
'yubikey2fPublicIDSize' => 12,
|
||||
'yubikey2fSelfRegistration' => 0,
|
||||
'yubikey2fUserCanRemoveKey' => 1
|
||||
};
|
||||
|
|
|
@ -786,7 +786,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
'type' => 'bool'
|
||||
},
|
||||
'checkUserHiddenAttributes' => {
|
||||
'default' => '_2fDevices _loginHistory hGroups',
|
||||
'default' => '_loginHistory hGroups',
|
||||
'type' => 'text'
|
||||
},
|
||||
'checkUserIdRule' => {
|
||||
|
@ -1216,7 +1216,7 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
|
|||
'type' => 'int'
|
||||
},
|
||||
'hiddenAttributes' => {
|
||||
'default' => '_password',
|
||||
'default' => '_password _2fDevices',
|
||||
'type' => 'text'
|
||||
},
|
||||
'hideOldPassword' => {
|
||||
|
@ -3197,10 +3197,27 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
'default' => '::2F::Engines::Default',
|
||||
'type' => 'text'
|
||||
},
|
||||
'sfRemovedMsg' => {
|
||||
'sfRemovedMsgRule' => {
|
||||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'sfRemovedNotifMsg' => {
|
||||
'default' =>
|
||||
'_removedSF_ expired second factor(s) has/have been removed!',
|
||||
'type' => 'text'
|
||||
},
|
||||
'sfRemovedNotifRef' => {
|
||||
'default' => 'RemoveSF',
|
||||
'type' => 'text'
|
||||
},
|
||||
'sfRemovedNotifTitle' => {
|
||||
'default' => 'Second factor notification',
|
||||
'type' => 'text'
|
||||
},
|
||||
'sfRemovedUseNotif' => {
|
||||
'default' => 0,
|
||||
'type' => 'bool'
|
||||
},
|
||||
'sfRequired' => {
|
||||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
|
|
|
@ -435,7 +435,7 @@ sub attributes {
|
|||
},
|
||||
checkUserHiddenAttributes => {
|
||||
type => 'text',
|
||||
default => '_2fDevices _loginHistory hGroups',
|
||||
default => '_loginHistory hGroups',
|
||||
documentation => 'Attributes to hide in CheckUser plugin',
|
||||
flags => 'p',
|
||||
},
|
||||
|
@ -716,7 +716,7 @@ sub attributes {
|
|||
},
|
||||
hiddenAttributes => {
|
||||
type => 'text',
|
||||
default => '_password',
|
||||
default => '_password _2fDevices',
|
||||
documentation => 'Name of attributes to hide in logs',
|
||||
},
|
||||
key => {
|
||||
|
@ -2587,11 +2587,36 @@ sub attributes {
|
|||
help => 'secondfactor.html',
|
||||
documentation => 'Second factor required',
|
||||
},
|
||||
sfRemovedMsg => {
|
||||
type => 'boolOrExpr',
|
||||
sfRemovedMsgRule => {
|
||||
type => 'boolOrExpr',
|
||||
default => 0,
|
||||
help => 'secondfactor.html',
|
||||
documentation =>
|
||||
'Display a message if at leat one expired SF has been removed',
|
||||
},
|
||||
sfRemovedUseNotif => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
documentation => 'Use Notifications plugin to display message',
|
||||
},
|
||||
sfRemovedNotifRef => {
|
||||
type => 'text',
|
||||
default => 'RemoveSF',
|
||||
help => 'secondfactor.html',
|
||||
documentation => 'Display a message if at leat one expired SF has been removed',
|
||||
documentation => 'Notification reference',
|
||||
},
|
||||
sfRemovedNotifTitle => {
|
||||
type => 'text',
|
||||
default => 'Second factor notification',
|
||||
help => 'secondfactor.html',
|
||||
documentation => 'Notification title',
|
||||
},
|
||||
sfRemovedNotifMsg => {
|
||||
type => 'text',
|
||||
default =>
|
||||
'_removedSF_ expired second factor(s) has/have been removed!',
|
||||
help => 'secondfactor.html',
|
||||
documentation => 'Notification message',
|
||||
},
|
||||
available2F => {
|
||||
type => 'text',
|
||||
|
@ -2692,7 +2717,6 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||
documentation => 'LDAP password encoding',
|
||||
},
|
||||
ldapUsePasswordResetAttribute => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
default => 1,
|
||||
documentation => 'LDAP store reset flag in an attribute',
|
||||
|
|
|
@ -763,7 +763,17 @@ sub tree {
|
|||
'yubikey2fTTL',
|
||||
],
|
||||
},
|
||||
'sfRequired', 'sfRemovedMsg',
|
||||
{
|
||||
title => 'sfRemovedNotification',
|
||||
help => 'secondfactor.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'sfRemovedMsgRule', 'sfRemovedUseNotif',
|
||||
'sfRemovedNotifRef', 'sfRemovedNotifTitle',
|
||||
'sfRemovedNotifMsg',
|
||||
],
|
||||
},
|
||||
'sfRequired',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -734,6 +734,12 @@
|
|||
"sessionTitle":"محتوى الجلسة",
|
||||
"sfaTitle":"Second Factors Authentication",
|
||||
"sfRequired":"Require 2FA",
|
||||
"sfRemovedNotification":"Display a message if an expired SF is removed",
|
||||
"sfRemovedMsgRule":"تفعيل",
|
||||
"sfRemovedUseNotif":"Use Notifications plugin",
|
||||
"sfRemovedNotifMsg":"Notification message",
|
||||
"sfRemovedNotifRef":"Notification reference",
|
||||
"sfRemovedNotifTitle":"Notification title",
|
||||
"sfRemovedMsg":"Display a message if an expired SF is removed",
|
||||
"show":"عرض",
|
||||
"showHelp":"عرض المساعدة",
|
||||
|
|
|
@ -733,6 +733,12 @@
|
|||
"sessionTitle":"Session content",
|
||||
"sfaTitle":"Second Factors Authentication",
|
||||
"sfRequired":"Require 2FA",
|
||||
"sfRemovedNotification":"Display a message if an expired SF is removed",
|
||||
"sfRemovedMsgRule":"Activation",
|
||||
"sfRemovedUseNotif":"Use Notifications plugin",
|
||||
"sfRemovedNotifMsg":"Notification message",
|
||||
"sfRemovedNotifRef":"Notification reference",
|
||||
"sfRemovedNotifTitle":"Notification title",
|
||||
"sfRemovedMsg":"Display a message if an expired SF is removed",
|
||||
"show":"Show",
|
||||
"showHelp":"Show help",
|
||||
|
|
|
@ -733,6 +733,12 @@
|
|||
"sessionTitle":"Session content",
|
||||
"sfaTitle":"Second Factors Authentication",
|
||||
"sfRequired":"Require 2FA",
|
||||
"sfRemovedNotification":"Display a message if an expired SF is removed",
|
||||
"sfRemovedMsgRule":"Activation",
|
||||
"sfRemovedUseNotif":"Use Notifications plugin",
|
||||
"sfRemovedNotifMsg":"Notification message",
|
||||
"sfRemovedNotifRef":"Notification reference",
|
||||
"sfRemovedNotifTitle":"Notification title",
|
||||
"sfRemovedMsg":"Display a message if an expired SF is removed",
|
||||
"show":"Show",
|
||||
"showHelp":"Show help",
|
||||
|
|
|
@ -733,6 +733,12 @@
|
|||
"sessionTitle":"Contenu de la session",
|
||||
"sfaTitle":"Seconds Facteurs d'Authentification",
|
||||
"sfRequired":"Exiger 2FA",
|
||||
"sfRemovedNotification":"Afficher un message si un SF expiré a été supprimé",
|
||||
"sfRemovedMsgRule":"Activation",
|
||||
"sfRemovedUseNotif":"Utiliser les notifications",
|
||||
"sfRemovedNotifMsg":"Message de la notification",
|
||||
"sfRemovedNotifRef":"Référence de la notification",
|
||||
"sfRemovedNotifTitle":"Titre de la notification",
|
||||
"sfRemovedMsg":"Afficher un message si un SF expiré est supprimé",
|
||||
"show":"Montrer",
|
||||
"showHelp":"Montrer l'aide",
|
||||
|
|
|
@ -733,6 +733,12 @@
|
|||
"sessionTitle":"Contenuto della sessione",
|
||||
"sfaTitle":"Autenticazione a due fattori",
|
||||
"sfRequired":"Richiedi 2FA",
|
||||
"sfRemovedNotification":"Display a message if an expired SF is removed",
|
||||
"sfRemovedMsgRule":"Attivazione",
|
||||
"sfRemovedUseNotif":"Use Notifications plugin",
|
||||
"sfRemovedNotifMsg":"Notification message",
|
||||
"sfRemovedNotifRef":"Notification reference",
|
||||
"sfRemovedNotifTitle":"Notification title",
|
||||
"sfRemovedMsg":"Display a message if an expired SF is removed",
|
||||
"show":"Mostra",
|
||||
"showHelp":"Mostra aiuto",
|
||||
|
|
|
@ -148,7 +148,7 @@
|
|||
"cspConnect":"Đích cúa Ajax",
|
||||
"cspFont":"Nguồn phông chữ",
|
||||
"crossOrigineResourceSharing":"Cross-Origin Resource Sharing",
|
||||
"corsEnabled":"Activation",
|
||||
"corsEnabled":"Kích hoạt",
|
||||
"corsAllow_Credentials":"Access-Control-Allow-Credentials",
|
||||
"corsAllow_Headers":"Access-Control-Allow-Headers",
|
||||
"corsAllow_Methods":"Access-Control-Allow-Methods",
|
||||
|
@ -733,6 +733,12 @@
|
|||
"sessionTitle":"Nội dung phiên",
|
||||
"sfaTitle":"Second Factors Authentication",
|
||||
"sfRequired":"Require 2FA",
|
||||
"sfRemovedNotification":"Display a message if an expired SF is removed",
|
||||
"sfRemovedMsgRule":"Kích hoạt",
|
||||
"sfRemovedUseNotif":"Use Notifications plugin",
|
||||
"sfRemovedNotifMsg":"Notification message",
|
||||
"sfRemovedNotifRef":"Notification reference",
|
||||
"sfRemovedNotifTitle":"Notification title",
|
||||
"sfRemovedMsg":"Display a message if an expired SF is removed",
|
||||
"show":"Hiển thị",
|
||||
"showHelp":"Hiển thị trợ giúp",
|
||||
|
|
|
@ -733,6 +733,12 @@
|
|||
"sessionTitle":"Session content",
|
||||
"sfaTitle":"Second Factors Authentication",
|
||||
"sfRequired":"Require 2FA",
|
||||
"sfRemovedNotification":"Display a message if an expired SF is removed",
|
||||
"sfRemovedMsgRule":"Activation",
|
||||
"sfRemovedUseNotif":"Use Notifications plugin",
|
||||
"sfRemovedNotifMsg":"Notification message",
|
||||
"sfRemovedNotifRef":"Notification reference",
|
||||
"sfRemovedNotifTitle":"Notification title",
|
||||
"sfRemovedMsg":"Display a message if an expired SF is removed",
|
||||
"show":"Show",
|
||||
"showHelp":"Show help",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -12,6 +12,7 @@ package Lemonldap::NG::Portal::2F::Engines::Default;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use JSON qw(from_json to_json);
|
||||
use POSIX qw(strftime);
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_ERROR
|
||||
PE_NOTOKEN
|
||||
|
@ -30,7 +31,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
|
|||
has sfModules => ( is => 'rw', default => sub { [] } );
|
||||
has sfRModules => ( is => 'rw', default => sub { [] } );
|
||||
has sfReq => ( is => 'rw' );
|
||||
has sfMsg => ( is => 'rw' );
|
||||
has sfRule => ( is => 'rw' );
|
||||
|
||||
has ott => (
|
||||
is => 'rw',
|
||||
|
@ -107,9 +108,11 @@ sub init {
|
|||
}
|
||||
|
||||
unless (
|
||||
$self->sfMsg(
|
||||
$self->sfRule(
|
||||
$self->p->HANDLER->buildSub(
|
||||
$self->p->HANDLER->substitute( $self->conf->{sfRemovedMsg} )
|
||||
$self->p->HANDLER->substitute(
|
||||
$self->conf->{sfRemovedMsgRule}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -199,23 +202,20 @@ sub run {
|
|||
$self->p->updatePersistentSession( $req,
|
||||
{ _2fDevices => to_json($_2fDevices) } );
|
||||
|
||||
# Display message if required
|
||||
if ( $self->sfMsg->( $req, $req->sessionInfo ) ) {
|
||||
$req->info(
|
||||
$self->loadTemplate(
|
||||
'simpleInfo',
|
||||
(
|
||||
$removed > 1
|
||||
? (
|
||||
params => {
|
||||
trspan => "expired2Fremoved, $removed"
|
||||
}
|
||||
)
|
||||
: ( params => { trspan => "oneExpired2Fremoved" } )
|
||||
)
|
||||
)
|
||||
);
|
||||
return PE_INFO;
|
||||
# Display notification or message if required
|
||||
my $res = 0;
|
||||
if ( $self->sfRule->( $req, $req->sessionInfo ) ) {
|
||||
my $notifEngine = $self->p->loadedModules->{
|
||||
'Lemonldap::NG::Portal::Plugins::Notifications'};
|
||||
if ( $notifEngine && $self->conf->{sfRemovedUseNotif} ) {
|
||||
$self->logger->debug("Notifications plugin enabled");
|
||||
$res =
|
||||
$self->_sendNotification( $req, $notifEngine, $removed );
|
||||
}
|
||||
else {
|
||||
$res = $self->_sendInfo( $req, $removed );
|
||||
}
|
||||
return $res if $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -494,4 +494,57 @@ sub restoreSession {
|
|||
: $self->_displayRegister( $req, @path );
|
||||
}
|
||||
|
||||
sub _sendInfo {
|
||||
my ( $self, $req, $removed ) = @_;
|
||||
$self->logger->debug("Return simpleInfo template");
|
||||
$req->info(
|
||||
$self->loadTemplate(
|
||||
'simpleInfo',
|
||||
(
|
||||
$removed > 1
|
||||
? (
|
||||
params => {
|
||||
trspan => "expired2Fremoved, $removed"
|
||||
}
|
||||
)
|
||||
: ( params => { trspan => "oneExpired2Fremoved" } )
|
||||
)
|
||||
)
|
||||
);
|
||||
return PE_INFO;
|
||||
}
|
||||
|
||||
sub _sendNotification {
|
||||
my ( $self, $req, $notifEngine, $removed ) = @_;
|
||||
my $uid = $req->user;
|
||||
my $date = strftime "%Y-%m-%d", localtime;
|
||||
my $ref = $self->conf->{sfRemovedNotifRef} || 'RemoveSF';
|
||||
my $title =
|
||||
$self->conf->{sfRemovedNotifTitle} || 'Second factor notification';
|
||||
my $msg = $self->conf->{sfRemovedNotifMsg}
|
||||
|| "$removed expired second factor(s) has/have been removed!";
|
||||
$msg =~ s/_removedSF_/$removed/;
|
||||
|
||||
# Prepare notification
|
||||
my $content =
|
||||
$self->conf->{oldNotifFormat}
|
||||
? '<?xml version="1.0" encoding="UTF-8"?><root><notification uid="_uid_" date="_date_" reference="_ref_"><title>_title_</title><text>_msg_</text></notification></root>'
|
||||
: '[{"uid":"_uid_","date":"_date_","title":"_title_","reference":"_ref_","text":"_msg_"}]';
|
||||
$content =~ s/_uid_/$uid/;
|
||||
$content =~ s/_ref_/$ref/;
|
||||
$content =~ s/_date_/$date/;
|
||||
$content =~ s/_title_/$title/;
|
||||
$content =~ s/_msg_/$msg/;
|
||||
|
||||
if ( $notifEngine->module->notifObject->newNotification($content) ) {
|
||||
$self->logger->debug("Notification SF successfully appended");
|
||||
$self->userLogger->notice("Notification SF successfully appended");
|
||||
return PE_OK;
|
||||
}
|
||||
else {
|
||||
$self->logger->debug("Notification NOT created!");
|
||||
return $self->_sendInfo( $req, $removed );
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -42,7 +42,8 @@ sub authenticate {
|
|||
# Set the dn unless done before
|
||||
unless ( $req->data->{dn} ) {
|
||||
if ( my $tmp = $self->getUser($req) ) {
|
||||
$self->setSecurity($req);
|
||||
eval { $self->setSecurity($req) };
|
||||
$self->logger->warn($@) if ($@);
|
||||
return $tmp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package Lemonldap::NG::Portal::Lib::LDAP;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Lib::Net::LDAP;
|
||||
use Lemonldap::NG::Portal::Main::Constants
|
||||
qw(PE_OK PE_LDAPCONNECTFAILED PE_LDAPERROR PE_BADCREDENTIALS);
|
||||
|
||||
extends 'Lemonldap::NG::Common::Module';
|
||||
|
||||
|
@ -16,6 +18,17 @@ has ldap => (
|
|||
builder => 'newLdap',
|
||||
);
|
||||
|
||||
has attrs => (
|
||||
is => 'rw',
|
||||
lazy => 1,
|
||||
builder => sub {
|
||||
return [
|
||||
values %{ $_[0]->{conf}->{exportedVars} },
|
||||
values %{ $_[0]->{conf}->{ldapExportedVars} }
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
sub newLdap {
|
||||
my $self = $_[0];
|
||||
my $ldap;
|
||||
|
@ -98,6 +111,38 @@ sub init {
|
|||
|
||||
# RUNNING METHODS
|
||||
|
||||
sub getUser {
|
||||
my ( $self, $req, %args ) = @_;
|
||||
return PE_LDAPCONNECTFAILED unless $self->ldap and $self->bind();
|
||||
my $mesg = $self->ldap->search(
|
||||
base => $self->conf->{ldapBase},
|
||||
scope => 'sub',
|
||||
filter => (
|
||||
$args{useMail}
|
||||
? $self->mailFilter->($req)
|
||||
: $self->filter->($req)
|
||||
),
|
||||
defer => $self->conf->{ldapSearchDeref} || 'find',
|
||||
attrs => $self->attrs,
|
||||
);
|
||||
if ( $mesg->code() != 0 ) {
|
||||
$self->logger->error( 'LDAP Search error: ' . $mesg->error );
|
||||
return PE_LDAPERROR;
|
||||
}
|
||||
if ( $mesg->count() > 1 ) {
|
||||
$self->logger->error('More than one entry returned by LDAP directory');
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
unless ( $req->data->{entry} = $mesg->entry(0) ) {
|
||||
$self->userLogger->warn("$req->{user} was not found in LDAP directory");
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
$req->data->{dn} = $req->data->{entry}->dn();
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
# Test LDAP connection before trying to bind
|
||||
sub bind {
|
||||
my $self = shift;
|
||||
|
|
|
@ -3,8 +3,7 @@ package Lemonldap::NG::Portal::UserDB::LDAP;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use utf8;
|
||||
use Lemonldap::NG::Portal::Main::Constants
|
||||
qw(PE_OK PE_LDAPCONNECTFAILED PE_LDAPERROR PE_BADCREDENTIALS);
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK);
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Lib::LDAP';
|
||||
|
||||
|
@ -25,50 +24,9 @@ has ldapGroupAttributeNameSearch => (
|
|||
}
|
||||
);
|
||||
|
||||
has attrs => (
|
||||
is => 'rw',
|
||||
lazy => 1,
|
||||
builder => sub {
|
||||
return [
|
||||
values %{ $_[0]->{conf}->{exportedVars} },
|
||||
values %{ $_[0]->{conf}->{ldapExportedVars} }
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
# RUNNING METHODS
|
||||
|
||||
sub getUser {
|
||||
my ( $self, $req, %args ) = @_;
|
||||
return PE_LDAPCONNECTFAILED unless $self->ldap and $self->bind();
|
||||
my $mesg = $self->ldap->search(
|
||||
base => $self->conf->{ldapBase},
|
||||
scope => 'sub',
|
||||
filter => (
|
||||
$args{useMail}
|
||||
? $self->mailFilter->($req)
|
||||
: $self->filter->($req)
|
||||
),
|
||||
defer => $self->conf->{ldapSearchDeref} || 'find',
|
||||
attrs => $self->attrs,
|
||||
);
|
||||
if ( $mesg->code() != 0 ) {
|
||||
$self->logger->error( 'LDAP Search error: ' . $mesg->error );
|
||||
return PE_LDAPERROR;
|
||||
}
|
||||
if ( $mesg->count() > 1 ) {
|
||||
$self->logger->error('More than one entry returned by LDAP directory');
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
unless ( $req->data->{entry} = $mesg->entry(0) ) {
|
||||
$self->userLogger->warn("$req->{user} was not found in LDAP directory");
|
||||
eval { $self->p->_authentication->setSecurity($req) };
|
||||
return PE_BADCREDENTIALS;
|
||||
}
|
||||
$req->data->{dn} = $req->data->{entry}->dn();
|
||||
PE_OK;
|
||||
}
|
||||
#
|
||||
# getUser is provided by Portal::Lib::LDAP
|
||||
|
||||
# Load all parameters included in exportedVars parameter.
|
||||
# Multi-value parameters are loaded in a single string with
|
||||
|
|
|
@ -162,4 +162,4 @@ div.oidc_consent_message > ul {
|
|||
|
||||
.progress-bar-animated {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,146 +1,124 @@
|
|||
<TMPL_INCLUDE NAME="header.tpl">
|
||||
|
||||
<div id="errorcontent" class="container">
|
||||
<!--
|
||||
<div class="message message-positive alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
|
||||
<!--
|
||||
<div class="message message-positive alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
|
||||
-->
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE"> alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
|
||||
<form id="checkuser" action="/checkuser" method="post" class="password" role="form">
|
||||
<div class="buttons">
|
||||
|
||||
<TMPL_IF NAME="TOKEN">
|
||||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
</TMPL_IF>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-user"></i> </span>
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE"> alert"><div class="text-center"><span trspan="<TMPL_VAR NAME="MSG">"></span></div></div>
|
||||
<form id="checkuser" action="/checkuser" method="post" class="password" role="form">
|
||||
<div class="buttons">
|
||||
<TMPL_IF NAME="TOKEN">
|
||||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
</TMPL_IF>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-user"></i> </span>
|
||||
</div>
|
||||
<input name="user" type="text" class="form-control" value="<TMPL_VAR NAME="LOGIN">" trplaceholder="user" aria-required="true"/>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-link"></i> </span>
|
||||
</div>
|
||||
<input name="url" type="text" class="form-control" value="<TMPL_VAR NAME="URL">" trplaceholder="URL / DNS" aria-required="true"/>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-search"></span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
</div>
|
||||
<input name="user" type="text" class="form-control" value="<TMPL_VAR NAME="LOGIN">" trplaceholder="user" aria-required="true"/>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-link"></i> </span>
|
||||
</form>
|
||||
<div>
|
||||
<TMPL_IF NAME="ALLOWED">
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE_AUTH">"><div class="text-center"><b><span trspan="<TMPL_VAR NAME="ALLOWED">"></span></b></div></div>
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="HEADERS">
|
||||
<div class="row">
|
||||
<div class="card col border-secondary">
|
||||
<div class="text-center bg-light text-dark"><b><span trspan="headers">HEADERS</span></b></div>
|
||||
<div class="font-weight-bold">
|
||||
<TMPL_LOOP NAME="HEADERS">
|
||||
<TMPL_VAR NAME="key">: <TMPL_VAR NAME="value"><br/>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
<div class="row">
|
||||
<TMPL_IF NAME="GROUPS">
|
||||
<div class="card col border-secondary">
|
||||
<div class="text-center bg-light text-dark"><b><span trspan="groups_sso">SSO GROUPS</span></b></div>
|
||||
<div class="row">
|
||||
<TMPL_LOOP NAME="GROUPS">
|
||||
<div class="w-100"></div>
|
||||
<div class="col"><TMPL_VAR NAME="value"></div>
|
||||
</TMPL_LOOP>
|
||||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<TMPL_IF NAME="ATTRIBUTES">
|
||||
<div class="card col border-secondary">
|
||||
<div class="text-center bg-light text-dark"><b><span trspan="attributes">ATTRIBUTES</span></b></div>
|
||||
<table class="table table-sm table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><span trspan="key">Key</span></th>
|
||||
<th scope="col"><span trspan="value">Value</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="ATTRIBUTES">
|
||||
<tr>
|
||||
<td scope="row"><TMPL_VAR NAME="key"></td>
|
||||
<td scope="row"><TMPL_VAR NAME="value"></td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="GROUPS"><div class="w-100"></div></TMPL_IF>
|
||||
<TMPL_IF NAME="MACROS">
|
||||
<div class="card col border-secondary">
|
||||
<div class="text-center bg-light text-dark"><b><span trspan="macros">MACROS</span></b></div>
|
||||
<table class="table table-sm table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><span trspan="key">Key</span></th>
|
||||
<th scope="col"><span trspan="value">Value</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="MACROS">
|
||||
<tr>
|
||||
<td scope="row"><TMPL_VAR NAME="key"></td>
|
||||
<td scope="row"><TMPL_VAR NAME="value"></td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input name="url" type="text" class="form-control" value="<TMPL_VAR NAME="URL">" trplaceholder="URL / DNS" aria-required="true"/>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-search"></span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<TMPL_IF NAME="ALLOWED">
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE_AUTH">"><b><span trspan="<TMPL_VAR NAME="ALLOWED">"></span></b></div>
|
||||
</TMPL_IF>
|
||||
<TMPL_IF NAME="HEADERS">
|
||||
<div class="card mb-3 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><b><span trspan="headers">HEADERS</span></b></tr>
|
||||
<tr>
|
||||
<th class="align-middle"><span trspan="key">Key</span></th>
|
||||
<th class="align-middle"><span trspan="value">Value</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="HEADERS">
|
||||
<tr>
|
||||
<td class="align-middle"><TMPL_VAR NAME="key"></td>
|
||||
<td class="align-middle"><TMPL_VAR NAME="value"></td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<TMPL_IF NAME="GROUPS">
|
||||
<div class="card col-md-2 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><b><span trspan="groups_sso">SSO GROUPS</span></b></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="GROUPS">
|
||||
<tr>
|
||||
<td class="align-middle"><TMPL_VAR NAME="value"></td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="buttons">
|
||||
<!--
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-sign-in"></span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
-->
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="MACROS">
|
||||
<div class="card col-md-4 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><b><span trspan="macros">MACROS</span></b></tr>
|
||||
<tr>
|
||||
<th class="align-middle"><span trspan="key">Key</span></th>
|
||||
<th class="align-middle"><span trspan="value">Value</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="MACROS">
|
||||
<tr>
|
||||
<td class="align-middle"><TMPL_VAR NAME="key"></td>
|
||||
<td class="align-middle"><TMPL_VAR NAME="value"></td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_IF NAME="ATTRIBUTES">
|
||||
<div class="card col-md-6 border-secondary">
|
||||
<div class="card-body table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr class="align-middle"><b><span trspan="attributes">ATTRIBUTES</span></b></tr>
|
||||
<tr>
|
||||
<th class="text-left"><span trspan="key">Key</span></th>
|
||||
<th class="text-left"><span trspan="value">Value</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<TMPL_LOOP NAME="ATTRIBUTES">
|
||||
<tr>
|
||||
<td class="text-left"><TMPL_VAR NAME="key"></td>
|
||||
<td class="text-left"><TMPL_VAR NAME="value"></td>
|
||||
</tr>
|
||||
</TMPL_LOOP>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</TMPL_IF>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<!--
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-sign-in"></span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
-->
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<TMPL_INCLUDE NAME="footer.tpl">
|
||||
|
|
|
@ -114,8 +114,8 @@ ok(
|
|||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
my %attributes = map /<td class="text-left">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( scalar keys %attributes == 16, 'Found 16 attributes' )
|
||||
my %attributes = map /<td scope="row">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( scalar keys %attributes == 17, 'Found 17 attributes' )
|
||||
or print STDERR "Missing attributes -> " . scalar keys %attributes;
|
||||
ok( $attributes{'_updateTime'} =~ /^\d{14}$/, 'Timestamp found' )
|
||||
or print STDERR Dumper( \%attributes );
|
||||
|
@ -182,8 +182,8 @@ ok(
|
|||
),
|
||||
'POST checkuser'
|
||||
);
|
||||
my %attributes2 = map /<td class="text-left">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( scalar keys %attributes2 == 16, 'Found 16 attributes' )
|
||||
my %attributes2 = map /<td scope="row">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( scalar keys %attributes2 == 17, 'Found 17 attributes' )
|
||||
or print STDERR "Missing attributes -> " . scalar keys %attributes2;
|
||||
ok( $attributes2{'_updateTime'} =~ /^\d{14}$/, 'Timestamp found' )
|
||||
or print STDERR Dumper( \%attributes2 );
|
||||
|
|
|
@ -110,7 +110,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUserComputeSession">%,
|
|||
or explain( $res->[2]->[0], 'trspan="checkUserComputeSession"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -118,23 +118,22 @@ ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%, 'Found rtyler' )
|
||||
ok( $res->[2]->[0] =~ m%: rtyler<br/>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(11);
|
||||
|
||||
$query =~ s/user=dwho/user=msmith/;
|
||||
|
@ -153,7 +152,7 @@ ok(
|
|||
);
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-danger"><b><span trspan="forbidden"></span></b></div>%,
|
||||
m%<div class="alert alert-danger"><div class="text-center"><b><span trspan="forbidden"></span></b></div></div>%,
|
||||
'Found trspan="forbidden"'
|
||||
) or explain( $res->[2]->[0], 'trspan="forbidden"' );
|
||||
count(2);
|
||||
|
|
|
@ -259,11 +259,9 @@ SKIP: {
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%,
|
||||
'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%,
|
||||
'Found attribute uid' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found attribute uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">french</td>%,
|
||||
'Found value french' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">french</td>%, 'Found value french' )
|
||||
or explain( $res->[2]->[0], 'Value french' );
|
||||
count(4);
|
||||
|
||||
|
@ -304,13 +302,11 @@ m%<div class="message message-positive alert"><span trspan="PE5"></span></div>%,
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%,
|
||||
'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%,
|
||||
'Found attribute uid' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found attribute uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">mail</td>%,
|
||||
'Found attribute mail' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">mail</td>%, 'Found attribute mail' )
|
||||
or explain( $res->[2]->[0], 'Attribute mail' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">davros\@badguy.org</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">davros\@badguy.org</td>%,
|
||||
'Found value davros@badguy.org' )
|
||||
or explain( $res->[2]->[0], 'Value davros@badguy.org' );
|
||||
count(5);
|
||||
|
|
|
@ -110,7 +110,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUserComputeSession">%,
|
|||
or explain( $res->[2]->[0], 'trspan="checkUserComputeSession"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -118,23 +118,22 @@ ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%, 'Found rtyler' )
|
||||
ok( $res->[2]->[0] =~ m%: rtyler%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(11);
|
||||
|
||||
$query =~ s/user=dwho/user=msmith/;
|
||||
|
@ -153,7 +152,7 @@ ok(
|
|||
);
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-danger"><b><span trspan="forbidden"></span></b></div>%,
|
||||
m%<div class="alert alert-danger"><div class="text-center"><b><span trspan="forbidden"></span></b></div></div>%,
|
||||
'Found trspan="forbidden"'
|
||||
) or explain( $res->[2]->[0], 'trspan="forbidden"' );
|
||||
count(2);
|
||||
|
|
|
@ -21,6 +21,11 @@ my $client = LLNG::Manager::Test->new( {
|
|||
checkUserIdRule => '$uid ne "msmith"',
|
||||
checkUserDisplayPersistentInfo => 1,
|
||||
checkUserDisplayEmptyValues => 1,
|
||||
totp2fSelfRegistration => 1,
|
||||
totp2fActivation => 1,
|
||||
totp2fDigits => 6,
|
||||
|
||||
#hiddenAttributes => 'test',
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -93,6 +98,92 @@ count(1);
|
|||
$id = expectCookie($res);
|
||||
expectRedirection( $res, 'http://auth.example.com/' );
|
||||
|
||||
# TOTP form
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/2fregisters',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Form registration'
|
||||
);
|
||||
expectRedirection( $res, qr#/2fregisters/totp$# );
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/2fregisters/totp',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Form registration'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' );
|
||||
|
||||
# JS query
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/2fregisters/totp/getkey', IO::String->new(''),
|
||||
cookie => "lemonldap=$id",
|
||||
length => 0,
|
||||
),
|
||||
'Get new key'
|
||||
);
|
||||
eval { $res = JSON::from_json( $res->[2]->[0] ) };
|
||||
ok( not($@), 'Content is JSON' )
|
||||
or explain( $res->[2]->[0], 'JSON content' );
|
||||
my ( $key, $token );
|
||||
ok( $key = $res->{secret}, 'Found secret' );
|
||||
ok( $token = $res->{token}, 'Found token' );
|
||||
$key = Convert::Base32::decode_base32($key);
|
||||
|
||||
# Post code
|
||||
my $code;
|
||||
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
|
||||
'Code' );
|
||||
ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
|
||||
my $s = "code=$code&token=$token";
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/2fregisters/totp/verify',
|
||||
IO::String->new($s),
|
||||
length => length($s),
|
||||
cookie => "lemonldap=$id",
|
||||
),
|
||||
'Post code'
|
||||
);
|
||||
eval { $res = JSON::from_json( $res->[2]->[0] ) };
|
||||
ok( not($@), 'Content is JSON' )
|
||||
or explain( $res->[2]->[0], 'JSON content' );
|
||||
ok( $res->{result} == 1, 'Key is registered' );
|
||||
count(12);
|
||||
|
||||
# Try to sign-in
|
||||
$client->logout($id);
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho&password=dwho'),
|
||||
length => 23,
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
my ( $host, $url, $query ) = expectForm( $res, undef, '/totp2fcheck', 'token' );
|
||||
|
||||
# Generate TOTP with LLNG
|
||||
|
||||
my $totp = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 );
|
||||
|
||||
$query =~ s/code=/code=$code/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/totp2fcheck',
|
||||
IO::String->new($query),
|
||||
length => length($query),
|
||||
),
|
||||
'Post code'
|
||||
);
|
||||
$id = expectCookie($res);
|
||||
|
||||
# CheckUser form -> granted
|
||||
# ------------------------
|
||||
|
||||
|
@ -104,20 +195,19 @@ ok(
|
|||
),
|
||||
'CheckUser form',
|
||||
);
|
||||
count(1);
|
||||
count(3);
|
||||
|
||||
my ( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/checkuser', 'user', 'url' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
||||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
count(1);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_user</td>%,
|
||||
'Found attribute _user' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_user</td>%, 'Found attribute _user' )
|
||||
or explain( $res->[2]->[0], 'Attribute _user' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">dwho</td>%, 'Found value dwho' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">dwho</td>%, 'Found value dwho' )
|
||||
or explain( $res->[2]->[0], 'Value dwho' );
|
||||
count(2);
|
||||
ok( $res->[2]->[0] !~ m%_2fDevices</td>%, '_2fDevices NOT Found!' )
|
||||
or explain( $res->[2]->[0], 'Value _2fDevices' );
|
||||
count(4);
|
||||
|
||||
$query =~ s/url=/url=http%3A%2F%2Ftest1.example.com/;
|
||||
ok(
|
||||
|
@ -138,15 +228,14 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
|||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
|
||||
count(2);
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
ok( $res->[2]->[0] =~ m%: dwho<br/>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">dwho</td>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Macro Value dwho' );
|
||||
count(3);
|
||||
|
||||
|
@ -189,7 +278,7 @@ ok(
|
|||
expectForm( $res, undef, '/checkuser', 'user', 'url' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-danger"><b><span trspan="forbidden"></span></b></div>%,
|
||||
m%<div class="alert alert-danger"><div class="text-center"><b><span trspan="forbidden"></span></b></div></div>%,
|
||||
'Found trspan="forbidden"'
|
||||
) or explain( $res->[2]->[0], 'trspan="forbidden"' );
|
||||
count(2);
|
||||
|
@ -222,7 +311,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
|||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -230,27 +319,26 @@ ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%, 'Found rtyler' )
|
||||
ok( $res->[2]->[0] =~ m%: rtyler<br/>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(11);
|
||||
|
||||
my @c = ( $res->[2]->[0] =~ /<td class="align-middle">rtyler/gs );
|
||||
ok( @c == 2, ' -> Two entries found' );
|
||||
my @c = ( $res->[2]->[0] =~ /<td scope="row">rtyler<\/td>/gs );
|
||||
ok( @c == 3, ' -> Three entries found' );
|
||||
count(1);
|
||||
|
||||
# Request with short VH url & user
|
||||
|
@ -282,7 +370,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
|||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -290,23 +378,22 @@ ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler</td>%, 'Found rtyler' )
|
||||
ok( $res->[2]->[0] =~ m%: rtyler<br/>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'Header Value: rtyler' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(11);
|
||||
|
||||
# Request a forbidden identity
|
||||
|
|
|
@ -205,7 +205,7 @@ SKIP: {
|
|||
or explain( $res->[2]->[0], 'trspan="checkUserMerged"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -213,26 +213,24 @@ m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_userDB</td>%,
|
||||
'Found _userDB' )
|
||||
or explain( $res->[2]->[0], '_userDB' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_userDB</td>%, 'Found _userDB' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value: _userDB' );
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
ok( $res->[2]->[0] =~ m%: dwho<br/>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(12);
|
||||
|
||||
$client->logout($id);
|
||||
|
|
|
@ -192,10 +192,10 @@ ok(
|
|||
);
|
||||
count(1);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">test_impersonation</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">test_impersonation</td>%,
|
||||
'Found macro test_impersonation' )
|
||||
or explain( $res->[2]->[0], 'test_impersonation' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">msmith/msmith</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">msmith/msmith</td>%,
|
||||
'Found msmith/msmith' )
|
||||
or explain( $res->[2]->[0], 'Found msmith/msmith' );
|
||||
count(2);
|
||||
|
@ -279,7 +279,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
|||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -294,39 +294,37 @@ ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_userDB</td>%, 'Found _userDB' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_userDB</td>%, 'Found _userDB' )
|
||||
or explain( $res->[2]->[0], '_userDB' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
ok( $res->[2]->[0] =~ m%: dwho%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">testPrefix_groups</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">testPrefix_groups</td>%,
|
||||
'Found testPrefix_groups' )
|
||||
or explain( $res->[2]->[0], 'testPrefix_groups' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">su; su_test; test_su</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">su; su_test; test_su</td>%,
|
||||
'Found "su; su_test; test_su"' )
|
||||
or explain( $res->[2]->[0], 'su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">testPrefix_uid</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">testPrefix_uid</td>%,
|
||||
'Found testPrefix_uid' )
|
||||
or explain( $res->[2]->[0], 'testPrefix_groups' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">rtyler</td>%, 'Found rtyler' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">rtyler</td>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">test_impersonation</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">test_impersonation</td>%,
|
||||
'Found macro test_impersonation' )
|
||||
or explain( $res->[2]->[0], 'test_impersonation' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler/dwho</td>%,
|
||||
'Found rtyler/dwo' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">rtyler/dwho</td>%, 'Found rtyler/dwo' )
|
||||
or explain( $res->[2]->[0], 'Found rtyler/dwo' );
|
||||
count(16);
|
||||
|
||||
my %attributes = map /<td class="text-left">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( scalar keys %attributes == 33, 'Found 33 attributes' )
|
||||
or print STDERR ( keys %attributes < 33 )
|
||||
my %attributes = map /<td scope="row">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( scalar keys %attributes == 35, 'Found 35 attributes' )
|
||||
or print STDERR ( keys %attributes < 35 )
|
||||
? "Missing attributes -> " . scalar keys %attributes
|
||||
: "Too much attributes -> " . scalar keys %attributes;
|
||||
ok( $attributes{'_auth'} eq 'Demo', '_auth' )
|
||||
|
|
|
@ -105,7 +105,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
|||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -118,29 +118,25 @@ ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_userDB</td>%, 'Found _userDB' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_userDB</td>%, 'Found _userDB' )
|
||||
or explain( $res->[2]->[0], '_userDB' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
ok( $res->[2]->[0] =~ m%: dwho<br/>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su_test</td>%,
|
||||
'Found su_test' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su_test</div>%, 'Found su_test' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su_test' );
|
||||
ok( $res->[2]->[0] !~ m%<td class="align-middle">_test_</td>%,
|
||||
'NOT found _test_' )
|
||||
ok( $res->[2]->[0] !~ m%<div class="col">_test_</div>%, 'NOT found _test_' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: _test_' );
|
||||
ok( $res->[2]->[0] !~ m%<td class="align-middle">test_su</td>%,
|
||||
'NOT found test_su' )
|
||||
ok( $res->[2]->[0] !~ m%<div class="col">test_su</td>%, 'NOT found test_su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: test_su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(15);
|
||||
|
||||
$client->logout($id);
|
||||
|
|
|
@ -106,7 +106,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUserMerged">%,
|
|||
or explain( $res->[2]->[0], 'trspan="checkUserMerged"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -114,42 +114,37 @@ ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="groups_sso">%,
|
||||
'Found trspan="groups_sso"' )
|
||||
or explain( $res->[2]->[0], 'trspan="groups_sso"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%,
|
||||
'Found SSO group "su"' )
|
||||
or explain( $res->[2]->[0], 'Found SSOO group "su"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su_test</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found SSO group "su"' )
|
||||
or explain( $res->[2]->[0], 'Found SSO group "su"' );
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su_test</div>%,
|
||||
'Found SSO group "su_test"' )
|
||||
or explain( $res->[2]->[0], 'Found SSO group "su_test"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">test_su</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">test_su</div>%,
|
||||
'Found SSO group "test_su"' )
|
||||
or explain( $res->[2]->[0], 'Found SSO group "test_su"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_userDB</td>%, 'Found _userDB' )
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
||||
or explain( $res->[2]->[0], 'trspan="macros"' );
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_userDB</td>%, 'Found _userDB' )
|
||||
or explain( $res->[2]->[0], '_userDB' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
ok( $res->[2]->[0] =~ m%: dwho<br/>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su</td>%, 'Found su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su</div>%, 'Found su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">su_test</td>%,
|
||||
'Found su_test' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">su_test</div>%, 'Found su_test' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: su_test' );
|
||||
ok( $res->[2]->[0] !~ m%<td class="align-middle">_test_</td>%,
|
||||
'NOT found _test_' )
|
||||
ok( $res->[2]->[0] !~ m%<div class="col">_test_</div>%, 'NOT found _test_' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: _test_' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">test_su</td>%,
|
||||
'Found test_su' )
|
||||
ok( $res->[2]->[0] =~ m%<div class="col">test_su</div>%, 'Found test_su' )
|
||||
or explain( $res->[2]->[0], 'SSO Groups: test_su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">uid</td>%, 'Found uid' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">uid</td>%, 'Found uid' )
|
||||
or explain( $res->[2]->[0], 'Attribute Value uid' );
|
||||
count(18);
|
||||
|
||||
|
|
|
@ -189,10 +189,10 @@ ok(
|
|||
);
|
||||
count(1);
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">test_impersonation</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">test_impersonation</td>%,
|
||||
'Found macro test_impersonation' )
|
||||
or explain( $res->[2]->[0], 'test_impersonation' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">msmith/msmith</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">msmith/msmith</td>%,
|
||||
'Found msmith/msmith' )
|
||||
or explain( $res->[2]->[0], 'Found msmith/msmith' );
|
||||
count(2);
|
||||
|
@ -277,7 +277,7 @@ ok( $res->[2]->[0] =~ m%<span trspan="checkUser">%, 'Found trspan="checkUser"' )
|
|||
or explain( $res->[2]->[0], 'trspan="checkUser"' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
m%<div class="alert alert-success"><b><span trspan="allowed"></span></b></div>%,
|
||||
m%<div class="alert alert-success"><div class="text-center"><b><span trspan="allowed"></span></b></div></div>%,
|
||||
'Found trspan="allowed"'
|
||||
) or explain( $res->[2]->[0], 'trspan="allowed"' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="headers">%, 'Found trspan="headers"' )
|
||||
|
@ -292,38 +292,36 @@ ok( $res->[2]->[0] =~ m%<span trspan="macros">%, 'Found trspan="macros"' )
|
|||
ok( $res->[2]->[0] =~ m%<span trspan="attributes">%,
|
||||
'Found trspan="attributes"' )
|
||||
or explain( $res->[2]->[0], 'trspan="attributes"' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">_userDB</td>%, 'Found _userDB' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_userDB</td>%, 'Found _userDB' )
|
||||
or explain( $res->[2]->[0], '_userDB' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">Auth-User</td>%,
|
||||
'Found Auth-User' )
|
||||
ok( $res->[2]->[0] =~ m%Auth-User: %, 'Found Auth-User' )
|
||||
or explain( $res->[2]->[0], 'Header Key: Auth-User' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">dwho</td>%, 'Found dwho' )
|
||||
ok( $res->[2]->[0] =~ m%: dwho<br/>%, 'Found dwho' )
|
||||
or explain( $res->[2]->[0], 'Header Value: dwho' );
|
||||
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">_whatToTrace</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">_whatToTrace</td>%,
|
||||
'Found _whatToTrace' )
|
||||
or explain( $res->[2]->[0], 'Macro Key _whatToTrace' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">testPrefix_groups</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">testPrefix_groups</td>%,
|
||||
'Found testPrefix_groups' )
|
||||
or explain( $res->[2]->[0], 'testPrefix_groups' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">su; su_test; test_su</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">su; su_test; test_su</td>%,
|
||||
'Found "su; su_test; test_su"' )
|
||||
or explain( $res->[2]->[0], 'su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">testPrefix_uid</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">testPrefix_uid</td>%,
|
||||
'Found testPrefix_uid' )
|
||||
or explain( $res->[2]->[0], 'testPrefix_groups' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="text-left">rtyler</td>%, 'Found rtyler' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">rtyler</td>%, 'Found rtyler' )
|
||||
or explain( $res->[2]->[0], 'su' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">test_impersonation</td>%,
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">test_impersonation</td>%,
|
||||
'Found macro test_impersonation' )
|
||||
or explain( $res->[2]->[0], 'test_impersonation' );
|
||||
ok( $res->[2]->[0] =~ m%<td class="align-middle">rtyler/dwho</td>%,
|
||||
'Found rtyler/dwo' )
|
||||
ok( $res->[2]->[0] =~ m%<td scope="row">rtyler/dwho</td>%, 'Found rtyler/dwo' )
|
||||
or explain( $res->[2]->[0], 'Found rtyler/dwo' );
|
||||
count(16);
|
||||
|
||||
my %attributes = map /<td class="text-left">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( keys %attributes == 31, 'Found 31 attributes' )
|
||||
my %attributes = map /<td scope="row">(.+)?<\/td>/g, $res->[2]->[0];
|
||||
ok( keys %attributes == 33, 'Found 33 attributes' )
|
||||
or print STDERR "Missing attributes -> " . scalar %attributes;
|
||||
ok( $attributes{'_auth'} eq 'Demo', '_auth' )
|
||||
or print STDERR Dumper( \%attributes );
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
use Test::More;
|
||||
use strict;
|
||||
use IO::String;
|
||||
|
||||
require 't/test-lib.pm';
|
||||
my $maintests = 20;
|
||||
my $file = '20190616_dwho_Tm90aWZpY2F0aW9uX1NG.json';
|
||||
|
||||
SKIP: {
|
||||
eval { require Convert::Base32 };
|
||||
if ($@) {
|
||||
skip 'Convert::Base32 is missing', $maintests;
|
||||
}
|
||||
require Lemonldap::NG::Common::TOTP;
|
||||
|
||||
my $client = LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => 'error',
|
||||
totp2fSelfRegistration => 1,
|
||||
totp2fActivation => 1,
|
||||
totp2fTTL => 2,
|
||||
sfRemovedMsgRule => '$uid eq "dwho"',
|
||||
sfRemovedUseNotif => 1,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
notification => 1,
|
||||
templatesDir => 'site/templates/',
|
||||
notificationStorage => 'File',
|
||||
notificationStorageOptions => { dirName => 't' },
|
||||
oldNotifFormat => 0,
|
||||
}
|
||||
}
|
||||
);
|
||||
my $res;
|
||||
|
||||
# Try to authenticate
|
||||
# -------------------
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho&password=dwho'),
|
||||
length => 23
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
my $id = expectCookie($res);
|
||||
|
||||
# TOTP form
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/2fregisters',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Form registration'
|
||||
);
|
||||
expectRedirection( $res, qr#/2fregisters/totp$# );
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/2fregisters/totp',
|
||||
cookie => "lemonldap=$id",
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Form registration'
|
||||
);
|
||||
ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' );
|
||||
ok(
|
||||
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
|
||||
'Found custom Main Logo'
|
||||
) or print STDERR Dumper( $res->[2]->[0] );
|
||||
|
||||
# JS query
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/2fregisters/totp/getkey', IO::String->new(''),
|
||||
cookie => "lemonldap=$id",
|
||||
length => 0,
|
||||
),
|
||||
'Get new key'
|
||||
);
|
||||
eval { $res = JSON::from_json( $res->[2]->[0] ) };
|
||||
ok( not($@), 'Content is JSON' )
|
||||
or explain( $res->[2]->[0], 'JSON content' );
|
||||
my ( $key, $token );
|
||||
ok( $key = $res->{secret}, 'Found secret' );
|
||||
ok( $token = $res->{token}, 'Found token' );
|
||||
$key = Convert::Base32::decode_base32($key);
|
||||
|
||||
# Post code
|
||||
my $code;
|
||||
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
|
||||
'Code' );
|
||||
ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
|
||||
my $s = "code=$code&token=$token&TOTPName=myTOTP";
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/2fregisters/totp/verify',
|
||||
IO::String->new($s),
|
||||
length => length($s),
|
||||
cookie => "lemonldap=$id",
|
||||
),
|
||||
'Post code'
|
||||
);
|
||||
eval { $res = JSON::from_json( $res->[2]->[0] ) };
|
||||
ok( not($@), 'Content is JSON' )
|
||||
or explain( $res->[2]->[0], 'JSON content' );
|
||||
ok( $res->{result} == 1, 'Key is registered' );
|
||||
|
||||
# Try to sign-in
|
||||
$client->logout($id);
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho&password=dwho'),
|
||||
length => 23,
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
my ( $host, $url, $query ) =
|
||||
expectForm( $res, undef, '/totp2fcheck', 'token' );
|
||||
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
|
||||
'Code' );
|
||||
$query =~ s/code=/code=$code/;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/totp2fcheck', IO::String->new($query),
|
||||
length => length($query),
|
||||
),
|
||||
'Post code'
|
||||
);
|
||||
$id = expectCookie($res);
|
||||
$client->logout($id);
|
||||
|
||||
diag 'Waiting';
|
||||
sleep 3;
|
||||
|
||||
# Try to sign-in
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
IO::String->new('user=dwho&password=dwho'),
|
||||
length => 23,
|
||||
accept => 'text/html',
|
||||
),
|
||||
'Auth query'
|
||||
);
|
||||
expectOK($res);
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
qr%<input type="hidden" name="reference1x1" value="RemoveSF">%,
|
||||
'Notification reference found'
|
||||
) or print STDERR Dumper( $res->[2]->[0] );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
qr%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%,
|
||||
'Notification message found'
|
||||
) or print STDERR Dumper( $res->[2]->[0] );
|
||||
$id = expectCookie($res);
|
||||
$client->logout($id);
|
||||
}
|
||||
count($maintests);
|
||||
system 'rm -f t/*_dwho_UmVtb3ZlU0Y=.json';
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
|
@ -4,6 +4,7 @@ use IO::String;
|
|||
|
||||
require 't/test-lib.pm';
|
||||
my $maintests = 20;
|
||||
my $file = '20190616_dwho_Tm90aWZpY2F0aW9uX1NG.json';
|
||||
|
||||
SKIP: {
|
||||
eval { require Convert::Base32 };
|
||||
|
@ -14,12 +15,18 @@ SKIP: {
|
|||
|
||||
my $client = LLNG::Manager::Test->new( {
|
||||
ini => {
|
||||
logLevel => 'error',
|
||||
totp2fSelfRegistration => 1,
|
||||
totp2fActivation => 1,
|
||||
totp2fTTL => 2,
|
||||
sfRemovedMsg => '$uid eq "dwho"',
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
logLevel => 'error',
|
||||
totp2fSelfRegistration => 1,
|
||||
totp2fActivation => 1,
|
||||
totp2fTTL => 2,
|
||||
sfRemovedMsgRule => '$uid eq "dwho"',
|
||||
sfRemovedUseNotif => 1,
|
||||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
notification => 1,
|
||||
templatesDir => 'site/templates/',
|
||||
notificationStorage => 'File',
|
||||
notificationStorageOptions => { dirName => 't' },
|
||||
oldNotifFormat => 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -140,15 +147,19 @@ SKIP: {
|
|||
expectOK($res);
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
qr%<h3 trspan="oneExpired2Fremoved">oneExpired2Fremoved</h3>%,
|
||||
'Found expired 2F message'
|
||||
qr%<input type="hidden" name="reference1x1" value="RemoveSF">%,
|
||||
'Notification reference found'
|
||||
) or print STDERR Dumper( $res->[2]->[0] );
|
||||
my $c = getCookies($res);
|
||||
ok( not(%$c), 'No cookie' );
|
||||
ok(
|
||||
$res->[2]->[0] =~
|
||||
qr%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%,
|
||||
'Notification message found'
|
||||
) or print STDERR Dumper( $res->[2]->[0] );
|
||||
$id = expectCookie($res);
|
||||
$client->logout($id);
|
||||
}
|
||||
count($maintests);
|
||||
|
||||
system 'rm -f t/*_dwho_UmVtb3ZlU0Y=.xml';
|
||||
clean_sessions();
|
||||
|
||||
done_testing( count() );
|
||||
|
|
@ -20,7 +20,7 @@ SKIP: {
|
|||
portalMainLogo => 'common/logos/logo_llng_old.png',
|
||||
totp2fTTL => 2,
|
||||
u2fTTL => 2,
|
||||
sfRemovedMsg => 1,
|
||||
sfRemovedMsgRule => 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue