Merge remote-tracking branch 'upstream/configuration-api' into configuration-api

This commit is contained in:
Soisik Froger 2019-12-17 10:00:41 +00:00
commit 29862ae678
75 changed files with 2466 additions and 118 deletions

View File

@ -16,7 +16,7 @@ ldapBindPassword = admin
checkXSS = 0
portalSkin = bootstrap
staticPrefix = /static
languages = fr, en, vi, it, ar
languages = fr, en, vi, it, ar, tr
templateDir = __pwd__/lemonldap-ng-portal/site/templates
portalStatus = 1
;totp2fActivation = 1
@ -33,7 +33,7 @@ useRedirectOnError = 0
enabledModules = conf, sessions, notifications, 2ndFA
protection = manager
staticPrefix = /static
languages = fr, en, vi, ar
languages = fr, en, vi, ar, tr
templateDir = __pwd__/lemonldap-ng-manager/site/templates
[node-handler]

View File

@ -13,7 +13,7 @@ dbiChain = dbi:SQLite:dbname=__pwd__/e2e-tests/conf/config.db
checkXSS = 0
portalSkin = bootstrap
staticPrefix = /static
languages = fr, en, vi, it, ar
languages = fr, en, vi, it, ar, tr
templateDir = __pwd__/lemonldap-ng-portal/site/templates
portalStatus = 1
;totp2fActivation = 1
@ -30,7 +30,7 @@ useRedirectOnError = 0
enabledModules = conf, sessions, notifications, 2ndFA
protection = manager
staticPrefix = /static
languages = fr, en, vi, ar
languages = fr, en, vi, ar, tr
templateDir = __pwd__/lemonldap-ng-manager/site/templates
[node-handler]

View File

@ -21,7 +21,7 @@ dirName=__pwd__/e2e-tests/conf
checkXSS = 0
portalSkin = bootstrap
staticPrefix = /static
languages = fr, en, vi, it, ar, de, zh, nl, es, pt, ro
languages = fr, en, vi, it, ar, de, zh, nl, es, pt, ro, tr
templateDir = __pwd__/lemonldap-ng-portal/site/templates
portalStatus = 1
totp2fActivation = 1
@ -46,7 +46,7 @@ viewerAllowBrowser = 1
viewerAllowDiff = 1
staticPrefix = /static
languages = fr, en, vi, ar, de, it, zh
languages = fr, en, vi, ar, de, it, zh, tr
templateDir = __pwd__/lemonldap-ng-manager/site/templates
[node-handler]

View File

@ -85,11 +85,12 @@ logLevel = warn
; CONFIGURATION CHECK
;
; By default, LLNG verify configuration at server start. If you use "reload"
; mechanism local cache will be updated. configuration is checked locally every
; LLNG verify configuration at server start. If you use "reload" mechanism,
; local cache will be updated. Configuration is checked locally every
; 10 minutes by each LLNG component. You can change this value using
; `checkTime` (time in seconds):
;checkTime = 600
; `checkTime` (time in seconds).
; To increase performances, you should comment this parameter and rely on cache.
checkTime = 1
[configuration]
@ -186,7 +187,7 @@ staticPrefix = __PORTALSTATICDIR__
templateDir = __PORTALTEMPLATESDIR__
; languages: available languages for portal interface
languages = en, fr, vi, it, ar, de, fi
languages = en, fr, vi, it, ar, de, fi, tr
; II - Optional parameters (overwrite configuration)
@ -371,7 +372,7 @@ staticPrefix = __MANAGERSTATICDIR__
templateDir = __MANAGERTEMPLATESDIR__
; languages: available languages for manager interface
languages = fr, en, it, vi, ar
languages = fr, en, it, vi, ar, tr
; Manager modules enabled
; Set here the list of modules you want to see in manager interface

View File

@ -23,8 +23,8 @@ use constant HANDLERSECTION => "handler";
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|fExtra)|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|fRemovedUseNotif|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|AllowOffline|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|o(?:ntextSwitchingStopWithLogout|rsEnabled)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?)?|y(?:Deleted|Other))|AjaxHook)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|d(?:isablePersistentStorage|biDynamicHashEnabled|ontCompactConf)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|rest(?:(?:Session|Config)Server|ExportSecretKeys)|br(?:owsersDontStorePassword|uteForceProtection)|(?:(?:globalLogout|active)Tim|wsdlServ)er|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs))$/;
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|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node)|S(?:erviceMetaDataAuthnContext|torageOptions))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|ingle(?:Session(?:UserByIP)?|(?:UserBy)?IP)|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|kipRenewConfirmation|fRemovedUseNotif|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|AllowOffline|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:setPassword|gister)|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|RequireOldPassword|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:User(?:Display(?:PersistentInfo|EmptyValues))?|State|XSS)|o(?:ntextSwitchingStopWithLogout|rsEnabled)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?)?|y(?:Deleted|Other))|AjaxHook)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Session|Config)Server|ExportSecretKeys)|freshSessions)|d(?:isablePersistentStorage|biDynamicHashEnabled|ontCompactConf)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|br(?:owsersDontStorePassword|uteForceProtection)|(?:(?:globalLogout|active)Tim|wsdlServ)er|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs))$/;
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );

View File

@ -269,7 +269,9 @@ sub _samlMetaDataNodes {
my ( $id, $resp ) = ( 1, [] );
# Return all exported attributes if asked
if ( $query =~ /^saml${type}MetaDataExportedAttributes$/ ) {
if ( $query =~
/^saml${type}MetaDataExportedAttributes|samlSPMetaDataMacros$/ )
{
my $pk =
eval { $self->getConfKey( $req, $query )->{$partner} } // {};
return $self->sendError( $req, undef, 400 ) if ( $req->error );
@ -380,7 +382,7 @@ sub _oidcMetaDataNodes {
# Return all exported attributes if asked
if ( $query =~
/^(?:oidc${type}MetaDataExportedVars|oidcRPMetaDataOptionsExtraClaims)$/
/^(?:oidc${type}MetaDataExportedVars|oidcRPMetaDataOptionsExtraClaims|oidcRPMetaDataMacros)$/
)
{
my $pk = eval { $self->getConfKey( $req, $query )->{$partner} } // {};
@ -478,7 +480,7 @@ sub _casMetaDataNodes {
# Return all exported attributes if asked
if ( $query =~
/^(?:cas${type}MetaDataExportedVars|casSrvMetaDataOptionsProxiedServices)$/
/^(?:cas${type}MetaDataExportedVars|casSrvMetaDataOptionsProxiedServices|casAppMetaDataMacros)$/
)
{
my $pk = eval { $self->getConfKey( $req, $query )->{$partner} } // {};
@ -549,7 +551,8 @@ sub authChoiceModules {
if ($@) {
$self->logger->error(
"Bad value in choice over parameters, deleted ($@)");
} else {
}
else {
$data->[5] = [ map { [ $_, $over->{$_} ] } keys %{$over} ];
}
}

View File

@ -14,22 +14,22 @@ our @EXPORT = ( @{ $EXPORT_TAGS{'all'} } );
our $specialNodeHash = {
virtualHosts => [qw(exportedHeaders locationRules post vhostOptions)],
samlIDPMetaDataNodes => [qw(samlIDPMetaDataXML samlIDPMetaDataExportedAttributes samlIDPMetaDataOptions)],
samlSPMetaDataNodes => [qw(samlSPMetaDataXML samlSPMetaDataExportedAttributes samlSPMetaDataOptions)],
samlSPMetaDataNodes => [qw(samlSPMetaDataXML samlSPMetaDataExportedAttributes samlSPMetaDataOptions samlSPMetaDataMacros)],
oidcOPMetaDataNodes => [qw(oidcOPMetaDataJSON oidcOPMetaDataJWKS oidcOPMetaDataOptions oidcOPMetaDataExportedVars)],
oidcRPMetaDataNodes => [qw(oidcRPMetaDataOptions oidcRPMetaDataExportedVars oidcRPMetaDataOptionsExtraClaims)],
oidcRPMetaDataNodes => [qw(oidcRPMetaDataOptions oidcRPMetaDataExportedVars oidcRPMetaDataOptionsExtraClaims oidcRPMetaDataMacros)],
casSrvMetaDataNodes => [qw(casSrvMetaDataOptions casSrvMetaDataExportedVars)],
casAppMetaDataNodes => [qw(casAppMetaDataOptions casAppMetaDataExportedVars)],
casAppMetaDataNodes => [qw(casAppMetaDataOptions casAppMetaDataExportedVars casAppMetaDataMacros)],
};
our $doubleHashKeys = 'issuerDBGetParameters';
our $simpleHashKeys = '(?:(?:l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|c(?:as(?:StorageOption|Attribute)|ustomAddParam|ombModule)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|macro)s|o(?:idcS(?:erviceMetaDataAuthnContext|torageOptions)|penIdExportedVars)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|S(?:MTPTLSOpts|SLVarIf))';
our $simpleHashKeys = '(?:(?:l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|ombModule)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|macro)s|o(?:idcS(?:erviceMetaDataAuthnContext|torageOptions)|penIdExportedVars)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|S(?:MTPTLSOpts|SLVarIf))';
our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s';
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:UserAttribut|Servic|Rul)e|ExportedVars)';
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:UserAttribut|Servic|Rul)e|(?:ExportedVar|Macro)s)';
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|ExportedVars)';
our $oidcOPMetaDataNodeKeys = 'oidcOPMetaData(?:Options(?:C(?:lient(?:Secret|ID)|heckJWTSignature|onfigurationURI)|S(?:toreIDToken|ortNumber|cope)|TokenEndpointAuthMethod|(?:JWKSTimeou|Promp)t|I(?:DTokenMaxAge|con)|U(?:iLocales|seNonce)|Display(?:Name)?|AcrValues|MaxAge)|ExportedVars|J(?:SON|WKS))';
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:(?:uthorizationCode|ccessToken)Expiration|llowOffline)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|ExportedVars)';
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:(?:uthorizationCode|ccessToken)Expiration|llowOffline)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|(?:ExportedVar|Macro)s)';
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|UserAttribut|DisplayNam)e|S(?:ignS[LS]OMessage|toreSAMLToken|[LS]OBinding|ortNumber)|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Re(?:questedAuthnContext|solutionRule|layStateURL)|Force(?:Authn|UTF8)|I(?:sPassive|con)|NameIDFormat)|ExportedAttributes|XML)';
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|S(?:essionNotOnOrAfterTimeout|ignS[LS]OMessage)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|ForceUTF8)|ExportedAttributes|XML)';
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|S(?:essionNotOnOrAfterTimeout|ignS[LS]OMessage)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|ForceUTF8)|(?:ExportedAttribute|Macro)s|XML)';
our $virtualHostKeys = '(?:vhost(?:A(?:uthnLevel|liases)|(?:Maintenanc|Typ)e|ServiceTokenTTL|Https|Port)|(?:exportedHeader|locationRule)s|post)';
our $authParameters = {

View File

@ -13,6 +13,7 @@ use Scalar::Util qw(weaken);
use constant UNPROTECT => 1;
use constant SKIP => 2;
use constant MAYSKIP => 3;
our @_onReload;
@ -546,6 +547,9 @@ sub conditionSub {
);
}
my $mayskip = 0;
$mayskip = MAYSKIP if $cond =~ /\bskip\b/;
# Replace some strings in condition
$cond = $class->substitute($cond);
my $sub;
@ -555,7 +559,7 @@ sub conditionSub {
}
# Return sub and protected flag
return ( $sub, 0 );
return ( $sub, $mayskip );
}
## @method arrayref aliasInit
@ -589,6 +593,7 @@ sub substitute {
$expr =~ s/\$(?!(?:ENV|env)\b)(_\w+|[a-zA-Z]\w*)/\$s->{$1}/sg;
$expr =~ s/\$ENV\{/\$r->{env}->\{/g;
$expr =~ s/\$env->\{/\$r->{env}->\{/g;
$expr =~ s/\bskip\b/q\{999_SKIP\}/g;
return $expr;
}

View File

@ -192,6 +192,11 @@ sub run {
$class->cleanHeaders($req);
return $class->OK;
}
elsif ( $protection == $class->MAYSKIP
and $class->grant( $req, $session, $uri, $cond ) eq '999_SKIP' )
{
return $class->OK;
}
else {
@ -440,7 +445,7 @@ sub fetchId {
my $value =
$lookForHttpCookie
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
if ( $value && $lookForHttpCookie && $class->tsv->{securedCookie} == 3 ) {
$value = $class->tsv->{cipher}->decryptHex( $value, "http" );

View File

@ -8,6 +8,7 @@ require 't/test-psgi-lib.pm';
init('Lemonldap::NG::Handler::PSGI');
my $res;
my $SKIPUSER = 0;
# Unauthentified query
# --------------------
@ -36,27 +37,42 @@ ok( $res->[0] == 200, 'Code is 200' ) or explain( $res, 200 );
count(2);
# Request an URI protected by custom function -> allowed
ok( $res = $client->_get( '/test-uri1/dwho', undef, undef, "lemonldap=$sessionId" ),
'Authentified query' );
ok(
$res =
$client->_get( '/test-uri1/dwho', undef, undef, "lemonldap=$sessionId" ),
'Authentified query'
);
ok( $res->[0] == 200, '/test-uri1 -> Code is 200' ) or explain( $res, 200 );
count(2);
# Request an URI protected by custom function -> allowed
ok( $res = $client->_get( '/test-uri2/dwho/dummy', undef, undef, "lemonldap=$sessionId" ),
'Authentified query' );
ok(
$res = $client->_get(
'/test-uri2/dwho/dummy', undef, undef, "lemonldap=$sessionId"
),
'Authentified query'
);
ok( $res->[0] == 200, '/test-uri2 -> Code is 200' ) or explain( $res, 200 );
count(2);
# Request an URI protected by custom function -> denied
ok( $res = $client->_get( '/test-uri1/dwho/', undef, undef, "lemonldap=$sessionId" ),
'Denied query' );
ok( $res->[0] == 403, '/test-uri1 -> Code is 403' ) or explain( $res->[0], 403 );
ok(
$res =
$client->_get( '/test-uri1/dwho/', undef, undef, "lemonldap=$sessionId" ),
'Denied query'
);
ok( $res->[0] == 403, '/test-uri1 -> Code is 403' )
or explain( $res->[0], 403 );
count(2);
# Request an URI protected by custom function -> denied
ok( $res = $client->_get( '/test-uri1/dwh', undef, undef, "lemonldap=$sessionId" ),
'Denied query' );
ok( $res->[0] == 403, '/test-uri1 -> Code is 403' ) or explain( $res->[0], 403 );
ok(
$res =
$client->_get( '/test-uri1/dwh', undef, undef, "lemonldap=$sessionId" ),
'Denied query'
);
ok( $res->[0] == 403, '/test-uri1 -> Code is 403' )
or explain( $res->[0], 403 );
count(2);
# Denied query
@ -136,14 +152,25 @@ ok(
);
count(3);
ok( $res = $client->_get( '/skipif/za', undef, 'test1.example.com' ),
'Test skip() rule 1' );
ok( $res->[0] == 302, 'Code is 302' ) or explain( $res, 302 );
$SKIPUSER = 1;
ok( $res = $client->_get( '/skipif/zz', undef, 'test1.example.com' ),
'Test skip() rule 2' );
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res, 200 );
count(4);
done_testing( count() );
clean();
sub Lemonldap::NG::Handler::PSGI::handler {
my ( $self, $req ) = @_;
ok( $req->env->{HTTP_AUTH_USER} eq 'dwho', 'Header is given to app' )
or explain( $req->env->{HTTP_AUTH_USER}, 'dwho' );
count(1);
unless ($SKIPUSER) {
ok( $req->env->{HTTP_AUTH_USER} eq 'dwho', 'Header is given to app' )
or explain( $req->env->{HTTP_AUTH_USER}, 'dwho' );
count(1);
}
return [ 200, [ 'Content-Type', 'text/plain' ], ['Hello'] ];
}

View File

@ -46,6 +46,7 @@
"^/test-uri1": "varIsInUri($ENV{REQUEST_URI}, '/test-uri1/', $uid, 1)",
"^/test-uri2": "varIsInUri($ENV{REQUEST_URI}, '/test-uri2/', $uid)",
"^/test-restricted_uri": "varIsInUri($ENV{REQUEST_URI}, '/test-restricted_uri/', \"$uid/\", 1)",
"^/skipif": "$ENV{REQUEST_URI} =~ /zz/ ? skip : 1",
"^/logout": "logout_sso",
"^/deny": "deny",
"default": "accept"

View File

@ -190,6 +190,7 @@ site/htdocs/static/languages/de.json
site/htdocs/static/languages/en.json
site/htdocs/static/languages/fr.json
site/htdocs/static/languages/it.json
site/htdocs/static/languages/tr.json
site/htdocs/static/languages/vi.json
site/htdocs/static/languages/zh.json
site/htdocs/static/logos/ar.png

View File

@ -674,6 +674,17 @@ sub attributes {
},
'type' => 'keyTextContainer'
},
'casAppMetaDataMacros' => {
'default' => {},
'test' => {
'keyMsgFail' => '__badMacroName__',
'keyTest' => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
'test' => sub {
return perlExpr(@_);
}
},
'type' => 'keyTextContainer'
},
'casAppMetaDataNodes' => {
'type' => 'casAppMetaDataNodeContainer'
},
@ -1031,6 +1042,12 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'customPassword' => {
'type' => 'text'
},
'customPlugins' => {
'type' => 'text'
},
'customPluginsParams' => {
'type' => 'keyTextContainer'
},
'customRegister' => {
'type' => 'text'
},
@ -1987,6 +2004,17 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
},
'type' => 'keyTextContainer'
},
'oidcRPMetaDataMacros' => {
'default' => {},
'test' => {
'keyMsgFail' => '__badMacroName__',
'keyTest' => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
'test' => sub {
return perlExpr(@_);
}
},
'type' => 'keyTextContainer'
},
'oidcRPMetaDataNodes' => {
'type' => 'oidcRPMetaDataNodeContainer'
},
@ -2587,6 +2615,9 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
],
'type' => 'select'
},
'refreshSessions' => {
'type' => 'bool'
},
'registerConfirmSubject' => {
'type' => 'text'
},
@ -3161,6 +3192,17 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'test' => qr/\w/,
'type' => 'samlAttributeContainer'
},
'samlSPMetaDataMacros' => {
'default' => {},
'test' => {
'keyMsgFail' => '__badMacroName__',
'keyTest' => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
'test' => sub {
return perlExpr(@_);
}
},
'type' => 'keyTextContainer'
},
'samlSPMetaDataNodes' => {
'type' => 'samlSPMetaDataNodeContainer'
},

View File

@ -184,11 +184,11 @@ our \@EXPORT = ( \@{ \$EXPORT_TAGS{'all'} } );
our \$specialNodeHash = {
virtualHosts => [qw(exportedHeaders locationRules post vhostOptions)],
samlIDPMetaDataNodes => [qw(samlIDPMetaDataXML samlIDPMetaDataExportedAttributes samlIDPMetaDataOptions)],
samlSPMetaDataNodes => [qw(samlSPMetaDataXML samlSPMetaDataExportedAttributes samlSPMetaDataOptions)],
samlSPMetaDataNodes => [qw(samlSPMetaDataXML samlSPMetaDataExportedAttributes samlSPMetaDataOptions samlSPMetaDataMacros)],
oidcOPMetaDataNodes => [qw(oidcOPMetaDataJSON oidcOPMetaDataJWKS oidcOPMetaDataOptions oidcOPMetaDataExportedVars)],
oidcRPMetaDataNodes => [qw(oidcRPMetaDataOptions oidcRPMetaDataExportedVars oidcRPMetaDataOptionsExtraClaims)],
oidcRPMetaDataNodes => [qw(oidcRPMetaDataOptions oidcRPMetaDataExportedVars oidcRPMetaDataOptionsExtraClaims oidcRPMetaDataMacros)],
casSrvMetaDataNodes => [qw(casSrvMetaDataOptions casSrvMetaDataExportedVars)],
casAppMetaDataNodes => [qw(casAppMetaDataOptions casAppMetaDataExportedVars)],
casAppMetaDataNodes => [qw(casAppMetaDataOptions casAppMetaDataExportedVars casAppMetaDataMacros)],
};
EOF
@ -277,11 +277,13 @@ $defaultAttr}
exportedHeaders locationRules post vhostOptions
samlIDPMetaDataXML samlIDPMetaDataExportedAttributes
samlIDPMetaDataOptions samlSPMetaDataXML
samlSPMetaDataExportedAttributes samlSPMetaDataOptions
oidcOPMetaDataJSON oidcOPMetaDataJWKS oidcOPMetaDataOptions
samlSPMetaDataExportedAttributes samlSPMetaDataMacros
samlSPMetaDataOptions oidcOPMetaDataJSON
oidcOPMetaDataJWKS oidcOPMetaDataOptions
oidcOPMetaDataExportedVars oidcRPMetaDataOptions
oidcRPMetaDataExportedVars oidcRPMetaDataOptionsExtraClaims
casAppMetaDataExportedVars casAppMetaDataOptions
oidcRPMetaDataMacros casAppMetaDataExportedVars
casAppMetaDataOptions casAppMetaDataMacros
casSrvMetaDataExportedVars casSrvMetaDataOptions
)
)

View File

@ -554,6 +554,10 @@ sub attributes {
documentation =>
'Avoid asking confirmation when an Issuer asks to renew auth',
},
refreshSessions => {
type => 'bool',
documentation => 'Refresh sessions plugin',
},
forceGlobalStorageIssuerOTT => {
type => 'bool',
documentation =>
@ -2134,6 +2138,18 @@ sub attributes {
test => sub { return perlExpr(@_) },
documentation => 'CAS App rule',
},
casAppMetaDataMacros => {
type => 'keyTextContainer',
help =>
'exportedvars.html#extend_variables_using_macros_and_groups',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => sub { return perlExpr(@_) },
},
default => {},
documentation => 'Macros',
},
# Fake attribute: used by manager REST API to agglomerate all nodes
# related to a CAS SP partner
@ -2733,6 +2749,18 @@ sub attributes {
test => sub { return perlExpr(@_) },
documentation => 'Rule to grant access to this SP',
},
samlSPMetaDataMacros => {
type => 'keyTextContainer',
help =>
'exportedvars.html#extend_variables_using_macros_and_groups',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => sub { return perlExpr(@_) },
},
default => {},
documentation => 'Macros',
},
# AUTH, USERDB and PASSWORD MODULES
authentication => {
@ -3527,6 +3555,16 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
documentation => 'Custom additional parameters',
},
# Custom plugins
customPlugins => {
type => 'text',
documentation => 'Custom plugins',
},
customPluginsParams => {
type => 'keyTextContainer',
documentation => 'Custom plugins parameters',
},
# OpenID Connect auth params
oidcAuthnLevel => {
type => 'int',
@ -3814,6 +3852,18 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
test => sub { return perlExpr(@_) },
documentation => 'Rule to grant access to this RP',
},
oidcRPMetaDataMacros => {
type => 'keyTextContainer',
help =>
'exportedvars.html#extend_variables_using_macros_and_groups',
test => {
keyTest => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
keyMsgFail => '__badMacroName__',
test => sub { return perlExpr(@_) },
},
default => {},
documentation => 'Macros',
},
};
}

View File

@ -138,7 +138,8 @@ sub cTrees {
]
}
]
}
},
"samlSPMetaDataMacros",
],
oidcOPMetaDataNode => [
'oidcOPMetaDataJSON',
@ -224,6 +225,7 @@ sub cTrees {
'oidcRPMetaDataOptionsRule',
]
},
'oidcRPMetaDataMacros',
{
title => 'oidcRPMetaDataOptionsDisplay',
form => 'simpleInputContainer',
@ -266,6 +268,7 @@ sub cTrees {
'casAppMetaDataOptionsRule'
]
},
'casAppMetaDataMacros',
],
};
}

View File

@ -727,6 +727,12 @@ sub tree {
nodes =>
[ 'decryptValueRule', 'decryptValueFunctions', ]
},
{
title => 'customPluginsNode',
help => 'plugincustom.html',
nodes => [ 'customPlugins', 'customPluginsParams' ]
},
'refreshSessions',
]
},
{

View File

@ -334,7 +334,7 @@ sub _scanNodes {
hdebug(" SAML data is an array, serializing");
$leaf->{data} = join ';', @{ $leaf->{data} };
}
if ( $target =~ /^saml(?:S|ID)PMetaDataExportedAttributes$/ ) {
if ( $target =~ /^saml(?:S|ID)PMetaData(?:ExportedAttributes|Macros)$/ ) {
if ( $leaf->{cnodes} ) {
hdebug(" $target: unopened node");
$self->newConf->{$target}->{$key} =
@ -394,7 +394,7 @@ sub _scanNodes {
hdebug(" $target");
$self->set( $target, $key, $leaf->{data} );
}
elsif ( $target =~ /^oidc(?:O|R)PMetaDataExportedVars$/ ) {
elsif ( $target =~ /^oidc(?:O|R)PMetaData(?:ExportedVars|Macros)$/ ) {
hdebug(" $target");
if ( $leaf->{cnodes} ) {
hdebug(' unopened');
@ -463,7 +463,7 @@ sub _scanNodes {
$self->_scanNodes($subNodes);
$self->set( $target, $key, $leaf->{title}, $leaf->{data} );
}
elsif ( $target =~ /^cas(?:App|Srv)MetaDataExportedVars$/ ) {
elsif ( $target =~ /^cas(?:App|Srv)MetaData(?:ExportedVars|Macros)$/ ) {
hdebug(" $target");
if ( $leaf->{cnodes} ) {
hdebug(' unopened');

View File

@ -627,6 +627,19 @@ sub tests {
return 1;
},
# Warn if ldapPpolicyControl is used with AD (#2007)
ppolicyAd => sub {
if ( $conf->{ldapPpolicyControl}
and $conf->{authentication} eq "AD" )
{
return ( 1,
"LDAP password policy control should be disabled when using AD authentication"
);
}
return 1;
},
# Warn if bruteForceProtection enabled without History
bruteForceProtection => sub {
return 1 unless ( $conf->{bruteForceProtection} );

View File

@ -57,6 +57,14 @@ function templates(tpl,key) {
"id" : "casAppMetaDataOptions",
"title" : "casAppMetaDataOptions",
"type" : "simpleInputContainer"
},
{
"cnodes" : tpl+"s/"+key+"/"+"casAppMetaDataMacros",
"default" : [],
"help" : "exportedvars.html#extend_variables_using_macros_and_groups",
"id" : tpl+"s/"+key+"/"+"casAppMetaDataMacros",
"title" : "casAppMetaDataMacros",
"type" : "keyTextContainer"
}
]
;
@ -579,6 +587,14 @@ function templates(tpl,key) {
"id" : "oidcRPMetaDataOptions",
"title" : "oidcRPMetaDataOptions"
},
{
"cnodes" : tpl+"s/"+key+"/"+"oidcRPMetaDataMacros",
"default" : [],
"help" : "exportedvars.html#extend_variables_using_macros_and_groups",
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataMacros",
"title" : "oidcRPMetaDataMacros",
"type" : "keyTextContainer"
},
{
"_nodes" : [
{
@ -1120,6 +1136,14 @@ function templates(tpl,key) {
"help" : "idpsaml.html#options",
"id" : "samlSPMetaDataOptions",
"title" : "samlSPMetaDataOptions"
},
{
"cnodes" : tpl+"s/"+key+"/"+"samlSPMetaDataMacros",
"default" : [],
"help" : "exportedvars.html#extend_variables_using_macros_and_groups",
"id" : tpl+"s/"+key+"/"+"samlSPMetaDataMacros",
"title" : "samlSPMetaDataMacros",
"type" : "keyTextContainer"
}
]
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -118,6 +118,7 @@
"casAppMetaDataOptions":"خيارات",
"casAppMetaDataOptionsService":"خدمة أل يو أر ل",
"casAppMetaDataOptionsRule":"القاعدة",
"casAppMetaDataMacros":"ماكرو",
"casAppMetaDataOptionsUserAttribute":"خاصّيّة المستخدم",
"casAppName":"اسم التطبيق كاس",
"casAttr":"تسجيل الدخول كاس",
@ -205,6 +206,9 @@
"customModule":"وحدة مخصصة",
"customParams":"أسماء الوحدات المخصصة",
"customPassword":"وحدة كلمة المرورالمخصصة",
"customPlugins":"Modules list",
"customPluginsNode":"Custom plugins",
"customPluginsParams":"Additional parameters",
"customPortalSkin":"غلاف البوابة مخصص",
"customRegister":"وحدة تسجيل مخصص",
"customToTrace":"REMOTE_CUSTOM",
@ -553,6 +557,7 @@
"oidcRPMetaDataOptionsPublic":"Public client",
"oidcRPMetaDataOptionsRequirePKCE":"Require PKCE",
"oidcRPMetaDataOptionsRule":"قاعدة الدخول",
"oidcRPMetaDataMacros":"ماكرو",
"oidcOPMetaDataOptionsScope":"نطاق",
"oidcOPMetaDataOptionsStoreIDToken":"مخزن تعريف التوكن",
"oidcOPMetaDataOptionsTokenEndpointAuthMethod":"توكن نقطة النهاية لطريقة إثبات الهوية",
@ -726,6 +731,7 @@
"redirectFormMethod":"طريقة إعادة توجيه الإستمارة",
"redirection":"معالج إعادة التوجيه",
"reference":"مرجع",
"refreshSessions":"Refresh sessions API",
"regexp":"التعبير النمطي",
"regexps":"التعبير النمطي",
"register":"تسجيل حساب جديد",
@ -1017,6 +1023,7 @@
"samlSPMetaDataOptionsNotOnOrAfterTimeout":"ليس على أو بعد المدة",
"samlSPMetaDataOptionsForceUTF8":"فرضUTF-8 ",
"samlSPMetaDataOptionsRule":"قاعدة الدخول",
"samlSPMetaDataMacros":"ماكرو",
"samlIDPName":"اسم SAML IDP",
"samlServiceMetaData":"خدمة 2 SAML",
"samlEntityID":"معرف الكيان",

View File

@ -118,6 +118,7 @@
"casAppMetaDataOptions":"Optionen",
"casAppMetaDataOptionsService":"Service URL",
"casAppMetaDataOptionsRule":"Regel",
"casAppMetaDataMacros":"Macros",
"casAppMetaDataOptionsUserAttribute":"User attribute",
"casAppName":"CAS App Name",
"casAttr":"CAS login",
@ -205,6 +206,9 @@
"customModule":"Custom module",
"customParams":"Custom module names",
"customPassword":"Custom password module",
"customPlugins":"Modules list",
"customPluginsNode":"Custom plugins",
"customPluginsParams":"Additional parameters",
"customPortalSkin":"Custom portal skin",
"customRegister":"Custom register module",
"customToTrace":"REMOTE_CUSTOM",
@ -553,6 +557,7 @@
"oidcRPMetaDataOptionsPublic":"Public client",
"oidcRPMetaDataOptionsRequirePKCE":"Require PKCE",
"oidcRPMetaDataOptionsRule":"Access rule",
"oidcRPMetaDataMacros":"Macros",
"oidcOPMetaDataOptionsScope":"Scope",
"oidcOPMetaDataOptionsStoreIDToken":"Store ID Token",
"oidcOPMetaDataOptionsTokenEndpointAuthMethod":"Token endpoint authentication method",
@ -726,6 +731,7 @@
"redirectFormMethod":"Method for redirect form",
"redirection":"Handler redirections",
"reference":"Reference",
"refreshSessions":"Refresh sessions API",
"regexp":"Regular expression",
"regexps":"Regular expressions",
"register":"Register new account",
@ -1017,6 +1023,7 @@
"samlSPMetaDataOptionsNotOnOrAfterTimeout":"notOnOrAfter duration",
"samlSPMetaDataOptionsForceUTF8":"Force UTF-8",
"samlSPMetaDataOptionsRule":"Access rule",
"samlSPMetaDataMacros":"Macros",
"samlIDPName":"SAML IDP Name",
"samlServiceMetaData":"SAML2 Service",
"samlEntityID":"Entity Identifier",

View File

@ -118,6 +118,7 @@
"casAppMetaDataOptions":"Options",
"casAppMetaDataOptionsService":"Service URL",
"casAppMetaDataOptionsRule":"Rule",
"casAppMetaDataMacros":"Macros",
"casAppMetaDataOptionsUserAttribute":"User attribute",
"casAppName":"CAS App Name",
"casAttr":"CAS login",
@ -205,6 +206,9 @@
"customModule":"Custom module",
"customParams":"Custom module names",
"customPassword":"Custom password module",
"customPlugins":"Modules list",
"customPluginsNode":"Custom plugins",
"customPluginsParams":"Additional parameters",
"customPortalSkin":"Custom portal skin",
"customRegister":"Custom register module",
"customToTrace":"REMOTE_CUSTOM",
@ -553,6 +557,7 @@
"oidcRPMetaDataOptionsPublic":"Public client",
"oidcRPMetaDataOptionsRequirePKCE":"Require PKCE",
"oidcRPMetaDataOptionsRule":"Access rule",
"oidcRPMetaDataMacros":"Macros",
"oidcOPMetaDataOptionsScope":"Scope",
"oidcOPMetaDataOptionsStoreIDToken":"Store ID Token",
"oidcOPMetaDataOptionsTokenEndpointAuthMethod":"Token endpoint authentication method",
@ -726,6 +731,7 @@
"redirectFormMethod":"Method for redirect form",
"redirection":"Handler redirections",
"reference":"Reference",
"refreshSessions":"Refresh sessions API",
"regexp":"Regular expression",
"regexps":"Regular expressions",
"register":"Register new account",
@ -1017,6 +1023,7 @@
"samlSPMetaDataOptionsNotOnOrAfterTimeout":"notOnOrAfter duration",
"samlSPMetaDataOptionsForceUTF8":"Force UTF-8",
"samlSPMetaDataOptionsRule":"Access rule",
"samlSPMetaDataMacros":"Macros",
"samlIDPName":"SAML IDP Name",
"samlServiceMetaData":"SAML2 Service",
"samlEntityID":"Entity Identifier",

View File

@ -118,6 +118,7 @@
"casAppMetaDataOptions":"Options",
"casAppMetaDataOptionsService":"URL du service",
"casAppMetaDataOptionsRule":"Règle",
"casAppMetaDataMacros":"Macros",
"casAppMetaDataOptionsUserAttribute":"Attribut de l'utilisateur",
"casAppName":"Nom de l'application CAS",
"casAttr":"Identifiant CAS",
@ -205,6 +206,9 @@
"customModule":"Module personnalisé",
"customParams":"Nom des modules personnalisés",
"customPassword":"Module de mots-de-passe personnalisé",
"customPlugins":"Liste des modules",
"customPluginsNode":"Extensions personnalisées",
"customPluginsParams":"Paramètres supplémentaires",
"customPortalSkin":"Style personnalisé du portail",
"customRegister":"Module d'enregistrement personnalisé",
"customToTrace":"REMOTE_CUSTOM",
@ -553,6 +557,7 @@
"oidcRPMetaDataOptionsPublic":"Client public",
"oidcRPMetaDataOptionsRequirePKCE":"PKCE requis",
"oidcRPMetaDataOptionsRule":"Règle d'accès",
"oidcRPMetaDataMacros":"Macros",
"oidcOPMetaDataOptionsScope":"Étendue",
"oidcOPMetaDataOptionsStoreIDToken":"Conserver le jeton d'identité",
"oidcOPMetaDataOptionsTokenEndpointAuthMethod":"Méthode d'authentification pour l'accès aux jetons",
@ -726,6 +731,7 @@
"redirectFormMethod":"Méthode du formulaire de redirection",
"redirection":"Redirections du Handler",
"reference":"Référence",
"refreshSessions":"API de rafraîchissement des sessions",
"regexp":"Expression régulière",
"regexps":"Expressions régulières",
"register":"Créer un nouveau compte",
@ -1017,6 +1023,7 @@
"samlSPMetaDataOptionsNotOnOrAfterTimeout":"Durée notOnOrAfter",
"samlSPMetaDataOptionsForceUTF8":"Forcer l'UTF-8",
"samlSPMetaDataOptionsRule":"Règle d'accès",
"samlSPMetaDataMacros":"Macros",
"samlIDPName":"Nom du fournisseur d'identité SAML",
"samlServiceMetaData":"Service SAML 2",
"samlEntityID":"Identifiant d'entité",

View File

@ -118,6 +118,7 @@
"casAppMetaDataOptions":"Opzioni",
"casAppMetaDataOptionsService":"URL del servizio",
"casAppMetaDataOptionsRule":"Regola",
"casAppMetaDataMacros":"Macro",
"casAppMetaDataOptionsUserAttribute":"Attributo utente",
"casAppName":"Nome App CAS",
"casAttr":"Login CAS",
@ -205,6 +206,9 @@
"customModule":"Personalizza modulo",
"customParams":"Personalizza i nomi dei moduli",
"customPassword":"Personalizza il modulo password",
"customPlugins":"Modules list",
"customPluginsNode":"Custom plugins",
"customPluginsParams":"Additional parameters",
"customPortalSkin":"Personalizza faccia del portale ",
"customRegister":"Personalizza modulo di registro",
"customToTrace":"REMOTE_CUSTOM",
@ -553,6 +557,7 @@
"oidcRPMetaDataOptionsPublic":"Cliente pubblico",
"oidcRPMetaDataOptionsRequirePKCE":"Richiedi PKCE",
"oidcRPMetaDataOptionsRule":"Regola di accesso",
"oidcRPMetaDataMacros":"Macro",
"oidcOPMetaDataOptionsScope":"Scopo",
"oidcOPMetaDataOptionsStoreIDToken":"Immagazzina ID Token",
"oidcOPMetaDataOptionsTokenEndpointAuthMethod":"Metodo di autenticazione degli endpoint di token",
@ -726,6 +731,7 @@
"redirectFormMethod":"Metodo per il modulo di reindirizzamento",
"redirection":"Redirezioni del gestore",
"reference":"Riferimento",
"refreshSessions":"Refresh sessions API",
"regexp":"Espressione regolare",
"regexps":"Espressioni regolari",
"register":"Registra nuovo account",
@ -1017,6 +1023,7 @@
"samlSPMetaDataOptionsNotOnOrAfterTimeout":"Durata di notOnOrAfter ",
"samlSPMetaDataOptionsForceUTF8":"Forza UTF-8",
"samlSPMetaDataOptionsRule":"Regola di accesso",
"samlSPMetaDataMacros":"Macro",
"samlIDPName":"Nome di SAML IDP ",
"samlServiceMetaData":"Servizio SAML 2",
"samlEntityID":"Identificatore dell'entità",

File diff suppressed because it is too large Load Diff

View File

@ -118,6 +118,7 @@
"casAppMetaDataOptions":"Tùy chọn",
"casAppMetaDataOptionsService":"Dịch vụ URL",
"casAppMetaDataOptionsRule":"Quy tắc",
"casAppMetaDataMacros":"Macros",
"casAppMetaDataOptionsUserAttribute":"thuộc tính người dùng",
"casAppName":"Tên ứng dụng CAS",
"casAttr":"Đăng nhập CAS ",
@ -205,6 +206,9 @@
"customModule":"Mô đun tùy chỉnh",
"customParams":"Tên mô-đun tùy chỉnh",
"customPassword":"Mô đun mật khẩu tùy chỉnh",
"customPlugins":"Modules list",
"customPluginsNode":"Custom plugins",
"customPluginsParams":"Additional parameters",
"customPortalSkin":"Tùy chỉnh giao diện cổng thông tin",
"customRegister":"Module đăng ký tùy chỉnh",
"customToTrace":"REMOTE_CUSTOM",
@ -553,6 +557,7 @@
"oidcRPMetaDataOptionsPublic":"Public client",
"oidcRPMetaDataOptionsRequirePKCE":"Require PKCE",
"oidcRPMetaDataOptionsRule":"Quy tắc truy cập",
"oidcRPMetaDataMacros":"Macros",
"oidcOPMetaDataOptionsScope":"Phạm vi",
"oidcOPMetaDataOptionsStoreIDToken":"Mã thông báo Cửa hàng",
"oidcOPMetaDataOptionsTokenEndpointAuthMethod":"Phương pháp xác thực thiết bị đầu cuối Token",
@ -726,6 +731,7 @@
"redirectFormMethod":"Phương pháp chuyển hướng mẫu",
"redirection":"chuyển hướng trình điều khiển",
"reference":"Tham khảo",
"refreshSessions":"Refresh sessions API",
"regexp":"Biểu thức chính quy",
"regexps":"Biểu thức thông thường",
"register":"Đăng ký tài khoản mới",
@ -1017,6 +1023,7 @@
"samlSPMetaDataOptionsNotOnOrAfterTimeout":"Thời gian notOnOrAfter ",
"samlSPMetaDataOptionsForceUTF8":"Bắt buộc UTF-8",
"samlSPMetaDataOptionsRule":"Quy tắc truy cập",
"samlSPMetaDataMacros":"Macros",
"samlIDPName":"Tên SAML IDP ",
"samlServiceMetaData":"Dịch vụ SAML 2",
"samlEntityID":"Thực thể trình định danh",

View File

@ -118,6 +118,7 @@
"casAppMetaDataOptions":"选项",
"casAppMetaDataOptionsService":"服务 URL",
"casAppMetaDataOptionsRule":"规则",
"casAppMetaDataMacros":"Macros",
"casAppMetaDataOptionsUserAttribute":"User attribute",
"casAppName":"CAS App 名称",
"casAttr":"CAS 登录",
@ -205,6 +206,9 @@
"customModule":"定制模块",
"customParams":"定制模块名称",
"customPassword":"Custom password module",
"customPlugins":"Modules list",
"customPluginsNode":"Custom plugins",
"customPluginsParams":"Additional parameters",
"customPortalSkin":"Custom portal skin",
"customRegister":"Custom register module",
"customToTrace":"REMOTE_CUSTOM",
@ -553,6 +557,7 @@
"oidcRPMetaDataOptionsPublic":"Public client",
"oidcRPMetaDataOptionsRequirePKCE":"Require PKCE",
"oidcRPMetaDataOptionsRule":"Access rule",
"oidcRPMetaDataMacros":"Macros",
"oidcOPMetaDataOptionsScope":"Scope",
"oidcOPMetaDataOptionsStoreIDToken":"Store ID Token",
"oidcOPMetaDataOptionsTokenEndpointAuthMethod":"Token endpoint authentication method",
@ -726,6 +731,7 @@
"redirectFormMethod":"Method for redirect form",
"redirection":"Handler redirections",
"reference":"Reference",
"refreshSessions":"Refresh sessions API",
"regexp":"Regular expression",
"regexps":"Regular expressions",
"register":"Register new account",
@ -1017,6 +1023,7 @@
"samlSPMetaDataOptionsNotOnOrAfterTimeout":"notOnOrAfter duration",
"samlSPMetaDataOptionsForceUTF8":"Force UTF-8",
"samlSPMetaDataOptionsRule":"Access rule",
"samlSPMetaDataMacros":"Macros",
"samlIDPName":"SAML IDP Name",
"samlServiceMetaData":"SAML2 Service",
"samlEntityID":"Entity Identifier",

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -113,6 +113,7 @@ lib/Lemonldap/NG/Portal/Plugins/Impersonation.pm
lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm
lib/Lemonldap/NG/Portal/Plugins/Notifications.pm
lib/Lemonldap/NG/Portal/Plugins/PublicPages.pm
lib/Lemonldap/NG/Portal/Plugins/Refresh.pm
lib/Lemonldap/NG/Portal/Plugins/Register.pm
lib/Lemonldap/NG/Portal/Plugins/RESTServer.pm
lib/Lemonldap/NG/Portal/Plugins/SingleSession.pm
@ -363,6 +364,7 @@ site/htdocs/static/languages/it.json
site/htdocs/static/languages/nl.json
site/htdocs/static/languages/pt.json
site/htdocs/static/languages/ro.json
site/htdocs/static/languages/tr.json
site/htdocs/static/languages/vi.json
site/htdocs/static/languages/zh.json
site/templates/bootstrap/2fchoice.tpl
@ -434,6 +436,7 @@ site/templates/common/mail/fi.json
site/templates/common/mail/fr.json
site/templates/common/mail/it.json
site/templates/common/mail/ms.json
site/templates/common/mail/tr.json
site/templates/common/mail/vi.json
site/templates/common/mail/zh_CN.json
site/templates/common/mail_2fcode.tpl
@ -588,6 +591,7 @@ t/61-ForceAuthn.t
t/61-GrantSession.t
t/61-Session-ActivityTimeout.t
t/61-Session-Timeout.t
t/62-Refresh-plugin.t
t/62-SingleSession.t
t/62-UpgradeSession.t
t/63-History.t

View File

@ -6,7 +6,7 @@ use Lemonldap::NG::Common::Combination::Parser;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_ERROR PE_FIRSTACCESS);
use Scalar::Util 'weaken';
our $VERSION = '2.0.6';
our $VERSION = '2.0.7';
# TODO: See Lib::Wrapper
extends 'Lemonldap::NG::Portal::Main::Auth';
@ -152,16 +152,17 @@ sub authForce {
return 0;
}
#sub setSecurity {
# my $self = shift;
# my ($req) = @_;
# $self->getStack( $req, 'extractFormInfo' ) or return PE_ERROR;
# $req->userData->{_combinationTry} ||= 0;
# eval {
# $req->data->{combinationStack}->[ $req->userData->{_combinationTry} ]
# ->[0]->( 'setSecurity', @_ );
# };
#}
sub setSecurity {
my $self = shift;
my ($req) = @_;
$self->getStack( $req, 'extractFormInfo' ) or return;
eval {
$req->data->{combinationStack}
->[ $req->data->{dataKeep}->{combinationTry} ]->[0]
->( 'setSecurity', @_ );
};
$self->logger->debug($@) if ($@);
}
## UserDB steps
###############

View File

@ -801,9 +801,21 @@ sub _validate2 {
}
foreach my $casAttribute ( keys %$ev ) {
my $localSessionValue = $localSession->data->{ $ev->{$casAttribute} };
$attributes->{$casAttribute} = $localSessionValue
if defined $localSessionValue;
my $sessionAttr = $ev->{$casAttribute};
my $value;
# Lookup per-service macros first, and then local sessions
#
if ( $app and $self->spMacros->{$app}->{$sessionAttr} ) {
$value = $self->spMacros->{$app}->{$sessionAttr}
->( $req, $localSession->data );
}
else {
$value = $localSession->data->{$sessionAttr};
}
$attributes->{$casAttribute} = $value
if defined $value;
}
# Return success message

View File

@ -781,7 +781,7 @@ sub run {
# No access_token
# Claims must be set in id_token
my $claims =
$self->buildUserInfoResponseFromId(
$self->buildUserInfoResponseFromId( $req,
$oidc_request->{'scope'},
$rp, $req->id );
@ -926,7 +926,8 @@ sub run {
# No access_token
# Claims must be set in id_token
my $claims = $self->buildUserInfoResponseFromId(
my $claims =
$self->buildUserInfoResponseFromId( $req,
$oidc_request->{'scope'},
$rp, $req->id );
@ -1261,9 +1262,10 @@ sub token {
$id_token_payload_hash->{'at_hash'} = $at_hash if $at_hash;
if ( $self->force_id_claims($rp) ) {
my $claims =
$self->buildUserInfoResponseFromId( $codeSession->data->{'scope'},
$rp, $codeSession->data->{user_session_id} );
my $claims = $self->buildUserInfoResponseFromId(
$req, $codeSession->data->{'scope'},
$rp, $codeSession->data->{user_session_id}
);
foreach ( keys %$claims ) {
$id_token_payload_hash->{$_} = $claims->{$_}
@ -1481,7 +1483,8 @@ sub token {
# If we forced sending claims in ID token
if ( $self->force_id_claims($rp) ) {
my $claims =
$self->buildUserInfoResponse( $refreshSession->data->{scope},
$self->buildUserInfoResponse( $req,
$refreshSession->data->{scope},
$rp, $session );
foreach ( keys %$claims ) {
@ -1594,7 +1597,7 @@ sub userInfo {
}
my $userinfo_response =
$self->buildUserInfoResponse( $scope, $rp, $session );
$self->buildUserInfoResponse( $req, $scope, $rp, $session );
unless ($userinfo_response) {
return $self->returnBearerError( 'invalid_request', 'Invalid request',
401 );

View File

@ -610,8 +610,17 @@ sub run {
# Name is required
next unless $name;
# Error if corresponding attribute is not in user session
my $value = $req->{sessionInfo}->{$_};
# Lookup attribute value in SP macros or session
my $value;
if ( $self->spMacros->{$sp}->{$_} ) {
$value = $self->spMacros->{$sp}->{$_}
->( $req, $req->{sessionInfo} );
}
else {
$value = $req->{sessionInfo}->{$_};
}
# Check whether the value is required or not
unless ( defined $value ) {
if ($mandatory) {
$self->logger->error(
@ -1478,7 +1487,7 @@ sub sloRelayTerm {
my $session = $logout->get_session();
unless ($session) {
$self->logger->error( "Could not get session from logout" );
$self->logger->error("Could not get session from logout");
return PE_SAML_SLO_ERROR;
}

View File

@ -26,6 +26,7 @@ has ua => (
has casSrvList => ( is => 'rw', default => sub { {} }, );
has casAppList => ( is => 'rw', default => sub { {} }, );
has spRules => ( is => 'rw', default => sub { {} }, );
has spMacros => ( is => 'rw', default => sub { {} }, );
# RUNNING METHODS
@ -67,6 +68,22 @@ sub loadApp {
}
$self->spRules->{$_} = $rule;
}
# Load per-application macros
my $macros = $self->conf->{casAppMetaDataMacros}->{$_};
for my $macroAttr ( keys %{$macros} ) {
my $macroRule = $macros->{$macroAttr};
if ( length $macroRule ) {
$macroRule = $self->p->HANDLER->substitute($macroRule);
unless ( $macroRule = $self->p->HANDLER->buildSub($macroRule) )
{
$self->error( 'SAML SP macro error: '
. $self->p->HANDLER->tsv->{jail}->error );
return 0;
}
$self->spMacros->{$_}->{$macroAttr} = $macroRule;
}
}
}
return 1;
}

View File

@ -37,6 +37,7 @@ has oidcOPList => ( is => 'rw', default => sub { {} }, );
has oidcRPList => ( is => 'rw', default => sub { {} }, );
has rpAttributes => ( is => 'rw', default => sub { {} }, );
has spRules => ( is => 'rw', default => sub { {} } );
has spMacros => ( is => 'rw', default => sub { {} } );
# return LWP::UserAgent object
has ua => (
@ -132,6 +133,22 @@ sub loadRPs {
}
$self->spRules->{$rp} = $rule;
}
# Load per-RP macros
my $macros = $self->conf->{oidcRPMetaDataMacros}->{$rp};
for my $macroAttr ( keys %{$macros} ) {
my $macroRule = $macros->{$macroAttr};
if ( length $macroRule ) {
$macroRule = $self->p->HANDLER->substitute($macroRule);
unless ( $macroRule = $self->p->HANDLER->buildSub($macroRule) )
{
$self->error( 'OIDC RP macro error: '
. $self->p->HANDLER->tsv->{jail}->error );
return 0;
}
$self->spMacros->{$rp}->{$macroAttr} = $macroRule;
}
}
}
return 1;
}
@ -1299,11 +1316,11 @@ sub getAttributesListFromClaim {
# @param user_session_id User session identifier
# @return hashref UserInfo data
sub buildUserInfoResponseFromId {
my ( $self, $scope, $rp, $user_session_id ) = @_;
my ( $self, $req, $scope, $rp, $user_session_id ) = @_;
my $session = $self->p->getApacheSession($user_session_id);
return undef unless ($session);
return buildUserInfoResponse( $self, $scope, $rp, $session );
return buildUserInfoResponse( $self, $req, $scope, $rp, $session );
}
# Return Hash of UserInfo data
@ -1312,7 +1329,7 @@ sub buildUserInfoResponseFromId {
# @param session SSO or offline session
# @return hashref UserInfo data
sub buildUserInfoResponse {
my ( $self, $scope, $rp, $session ) = @_;
my ( $self, $req, $scope, $rp, $session ) = @_;
my $userinfo_response = {};
my $user_id_attribute =
@ -1335,7 +1352,19 @@ sub buildUserInfoResponse {
my $session_key =
$self->conf->{oidcRPMetaDataExportedVars}->{$rp}->{$attribute};
if ($session_key) {
my $session_value = $session->data->{$session_key};
my $session_value;
# Lookup attribute in macros first
if ( $self->spMacros->{$rp}->{$session_key} ) {
$session_value = $self->spMacros->{$rp}->{$session_key}
->( $req, $session->data );
# If not found, search in session
}
else {
$session_value = $session->data->{$session_key};
}
# Address is a JSON object
if ( $claim eq "address" ) {

View File

@ -30,6 +30,7 @@ has spList => ( is => 'rw', default => sub { {} } );
has idpList => ( is => 'rw', default => sub { {} } );
has idpRules => ( is => 'rw', default => sub { {} } );
has spRules => ( is => 'rw', default => sub { {} } );
has spMacros => ( is => 'rw', default => sub { {} } );
# return LWP::UserAgent object
has ua => (
@ -417,6 +418,22 @@ sub loadSPs {
$self->spRules->{$entityID} = $rule;
}
# Load per-SP macros
my $macros = $self->conf->{samlSPMetaDataMacros}->{$_};
for my $macroAttr ( keys %{$macros} ) {
my $macroRule = $macros->{$macroAttr};
if ( length $macroRule ) {
$macroRule = $self->p->HANDLER->substitute($macroRule);
unless ( $macroRule = $self->p->HANDLER->buildSub($macroRule) )
{
$self->error( 'SAML SP macro error: '
. $self->p->HANDLER->tsv->{jail}->error );
return 0;
}
$self->spMacros->{$entityID}->{$macroAttr} = $macroRule;
}
}
$self->logger->debug("SP $_ added");
}

View File

@ -2,7 +2,7 @@
# Display functions for LemonLDAP::NG Portal
package Lemonldap::NG::Portal::Main::Display;
our $VERSION = '2.0.6';
our $VERSION = '2.0.7';
package Lemonldap::NG::Portal::Main;
use strict;
@ -264,6 +264,7 @@ sub display {
or ( $self->conf->{authentication} eq 'Combination'
and $req->{error} > PE_OK
and $req->{error} != PE_FIRSTACCESS
and $req->{error} != PE_BADCREDENTIALS
and $req->{error} != PE_PP_PASSWORD_EXPIRED )
# and ( $req->{error} == PE_TOKENEXPIRED or $req->{error} == PE_NOTOKEN )

View File

@ -30,7 +30,8 @@ our @pList = (
impersonationRule => '::Plugins::Impersonation',
contextSwitchingRule => '::Plugins::ContextSwitching',
decryptValueRule => '::Plugins::DecryptValue',
globalLogoutRule => '::Plugins::GlobalLogout'
globalLogoutRule => '::Plugins::GlobalLogout',
refreshSessions => '::Plugins::Refresh',
);
##@method list enabledPlugins

View File

@ -164,7 +164,7 @@ sub refresh {
my ( $self, $req ) = @_;
$req->mustRedirect(1);
my %data = %{ $req->userData };
$req->user( $data{ $self->conf->{whatToTrace} } );
$req->user( $data{_user} || $data{ $self->conf->{whatToTrace} } );
$req->id( $data{_session_id} );
$self->userLogger->notice( 'Refresh request for ' . $req->user );
foreach ( keys %data ) {
@ -237,7 +237,7 @@ sub do {
}
# Remove userData if authentication fails
if ( $err == PE_BADCREDENTIALS or $err == PE_BADOTP) {
if ( $err == PE_BADCREDENTIALS or $err == PE_BADOTP ) {
$req->userData( {} );
}

View File

@ -0,0 +1,44 @@
package Lemonldap::NG::Portal::Plugins::Refresh;
use strict;
use Mouse;
our $VERSION = '2.0.7';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::OtherSessions';
sub init {
my ($self) = @_;
$self->addUnauthRoute( refreshsessions => 'run', ['POST'] );
}
sub run {
my ( $self, $req ) = @_;
return $self->p->sendError( $req, 'Not a JSON request', 400 )
unless $req->wantJSON;
my $info = $req->jsonBodyToObj;
return $self->p->sendError( $req, 'Bad content', 400 ) unless $info->{uid};
my $sessions =
$self->module->searchOn( $self->moduleOpts, $self->conf->{whatToTrace},
$info->{uid} );
my $c = 0;
my $nb = scalar( keys %$sessions );
foreach my $id ( keys %$sessions ) {
$req->userData(
{ _session_id => $id, $self->conf->{whatToTrace} => $info->{uid} }
);
$req->id($id);
$req->user( $info->{uid} );
eval { $self->p->refresh($req); };
$self->logger->debug("Refresh: $@") if $@;
$c++;
}
$req->userData( {} );
$req->$_(undef) foreach (qw(user id));
return $self->sendJSONresponse( $req,
{ updated => $c, errors => ( $nb - $c ) } );
}
1;

View File

@ -42,7 +42,7 @@ sub ask {
my ( $self, $req ) = @_;
# Check if auth is already running
if ( $req->param('upgrading') ) {
if ( $req->param('upgrading') or $req->param('kerberos') ) {
# verify token
return $self->confirm($req);
@ -69,12 +69,18 @@ sub confirm {
# Disabled due to #1821
#$req->pdata->{keepPdata} = 1;
my $upg;
if ( my $t = $req->param('upgrading') ) {
if ( $self->ott->getToken($t) ) {
$upg = 1;
}
else {
return $self->p->do( $req, [ sub { PE_TOKENEXPIRED } ] );
if ( $req->param('kerberos') ) {
$upg = 1;
}
else {
if ( my $t = $req->param('upgrading') ) {
if ( $self->ott->getToken($t) ) {
$upg = 1;
}
else {
return $self->p->do( $req, [ sub { PE_TOKENEXPIRED } ] );
}
}
}
$req->steps( ['controlUrl'] );

View File

@ -1,7 +1,7 @@
# Launch Kerberos request
$(document).ready ->
$.ajax portal + '?kerberos=1',
$.ajax (if window.location.href.match /\/upgradesession/ then window.location.href else portal )+ '?kerberos=1',
dataType: 'json'
# Called if browser can't find Kerberos ticket, will display
# PE_BADCREDENTIALS
@ -11,7 +11,10 @@ $(document).ready ->
# If request succeed cookie is set, posting form to get redirection
# or menu
success: (data) ->
$('#lform').submit()
if window.location.href.match /\/upgradesession/
document.location = portal
else
$('#lform').submit()
# Case else, will display PE_BADCREDENTIALS or fallback to next auth
# backend
error: () ->

View File

@ -1,7 +1,7 @@
// Generated by CoffeeScript 1.12.8
(function() {
$(document).ready(function() {
return $.ajax(portal + '?kerberos=1', {
return $.ajax((window.location.href.match(/\/upgradesession/) ? window.location.href : portal) + '?kerberos=1', {
dataType: 'json',
statusCode: {
401: function() {
@ -9,7 +9,11 @@
}
},
success: function(data) {
return $('#lform').submit();
if (window.location.href.match(/\/upgradesession/)) {
return document.location = portal;
} else {
return $('#lform').submit();
}
},
error: function() {
return $('#lform').submit();

View File

@ -1 +1 @@
(function(){$(document).ready(function(){return $.ajax(portal+"?kerberos=1",{dataType:"json",statusCode:{401:function(){return $("#lform").submit()}},success:function(r){return $("#lform").submit()},error:function(){return $("#lform").submit()}})})}).call(this);
(function(){$(document).ready(function(){return $.ajax((window.location.href.match(/\/upgradesession/)?window.location.href:portal)+"?kerberos=1",{dataType:"json",statusCode:{401:function(){return $("#lform").submit()}},success:function(o){return window.location.href.match(/\/upgradesession/)?document.location=portal:$("#lform").submit()},error:function(){return $("#lform").submit()}})})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/kerberos.js"],"names":["$","document","ready","ajax","portal","dataType","statusCode","401","submit","success","data","error","call","this"],"mappings":"CACA,WACEA,EAAEC,UAAUC,MAAM,WAChB,OAAOF,EAAEG,KAAKC,OAAS,cAAe,CACpCC,SAAU,OACVC,WAAY,CACVC,IAAK,WACH,OAAOP,EAAE,UAAUQ,WAGvBC,QAAS,SAASC,GAChB,OAAOV,EAAE,UAAUQ,UAErBG,MAAO,WACL,OAAOX,EAAE,UAAUQ,gBAKxBI,KAAKC"}
{"version":3,"sources":["lemonldap-ng-portal/site/htdocs/static/common/js/kerberos.js"],"names":["$","document","ready","ajax","window","location","href","match","portal","dataType","statusCode","401","submit","success","data","error","call","this"],"mappings":"CACA,WACEA,EAAEC,UAAUC,MAAM,WAChB,OAAOF,EAAEG,MAAMC,OAAOC,SAASC,KAAKC,MAAM,oBAAsBH,OAAOC,SAASC,KAAOE,QAAU,cAAe,CAC9GC,SAAU,OACVC,WAAY,CACVC,IAAK,WACH,OAAOX,EAAE,UAAUY,WAGvBC,QAAS,SAASC,GAChB,OAAIV,OAAOC,SAASC,KAAKC,MAAM,oBACtBN,SAASI,SAAWG,OAEpBR,EAAE,UAAUY,UAGvBG,MAAO,WACL,OAAOf,EAAE,UAAUY,gBAKxBI,KAAKC"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -129,8 +129,8 @@
"confirmPwd":"Confirmar contraseña",
"connect":"Conectar",
"connectedAs":"Conectado como ",
"contextSwitching_ON":"Impersonate another user",
"contextSwitching_OFF":"Stop impersonation",
"contextSwitching_ON":"Suplantar otro usuario",
"contextSwitching_OFF":"Parar suplantación",
"continue":"Continuar",
"createAccount":"Crear una cuenta",
"current":"Current",

View File

@ -92,9 +92,9 @@
"accountCreated":"Your account has been created, your temporary password has been sent to your mail address.",
"accountCreationSuccess":"Your account was successfully created.",
"action":"Action",
"activeSessions":"Active SSO sessions",
"all":"All",
"allowed":"Access ALLOWED",
"activeSessions":"Active SSO sessions",
"anotherInformation":"Another information:",
"areYouSure":"Are you sure?",
"askToRenew":"This application needs a more recent authentication. Do you want to reauthenticate?",

View File

@ -0,0 +1,291 @@
{
"PE0":"Kullanıcı doğrulandı",
"PE1":"Bağlantınızın süresi doldu, kimliğinizi yeniden doğrulamalısınız",
"PE2":"Kullanıcı adı ve parola alanları doldurulmalı",
"PE3":"Dizin yöneticisi hesabı veya parolası yanlış",
"PE4":"Kullanıcı dizinde bulunamadı",
"PE5":"Yanlış kimlik bilgileri",
"PE6":"LDAP sunucusuna bağlanılamadı",
"PE7":"LDAP sunucundan beklenmeyen bir hata alındı",
"PE8":"Apache::Session modülü hata verdi",
"PE9":"Kimlik doğrulama gerekli",
"PE10":"Geçersiz sertifika",
"PE21":"Hesabınız kilitli",
"PE22":"Parolanızın süresi doldu",
"PE23":"Sertifika gerekli",
"PE24":"Hata",
"PE25":"Parolanız sıfırlandı ve şimdi değiştirilmeli",
"PE26":"Parola değiştirilemez",
"PE27":"Parola değiştirilirken eski parola da girilmelidir",
"PE28":"Parola yeterince güçlü değil",
"PE29":"Parola çok kısa",
"PE30":"Parola oldukça yeni",
"PE31":"Parola çok yakın zamanda kullanıldı",
"PE32":"kimlik doğrulaması kaldı, parolanızı değiştirin!",
"PE33":"Parola süresinin dolmasına %d gün, %d saat, %ddakika ve %d saniye kaldı, parolayı değiştirin!",
"PE34":"Parolalar eşleşmedi",
"PE35":"Parola başarıyla değiştirildi",
"PE36":"Yeni bir mesajınız var",
"PE37":"Hatalı URL",
"PE38":"Şema mevcut değil",
"PE39":"Hatalı eski parola",
"PE40":"Hatalı kullanıcı adı",
"PE41":"Oturum açmaya izin verilmiyor",
"PE42":"Onay gerekli",
"PE43":"E-posta adresiniz zorunludur",
"PE44":"Onay anahtarı geçersiz veya çok eski",
"PE45":"E-posta gönderilirken bir hata oluşuyor",
"PE46":"Bir e-posta gönderildi",
"PE47":"Bağlantınız kesildi",
"PE48":"Tanımlanmamış SAML hatası",
"PE49":"SAML servisine bağlanılamadı",
"PE50":"Kimlik sağlayıcısı yüklenirken hata oluştu",
"PE51":"SAML ile tek oturum açma sırasında bir hata oluştu",
"PE52":"SAML varlığı bilinmiyor",
"PE53":"SAML mesaj hedefi doğru değil",
"PE54":"SAML mesaj koşullarına uygun değil",
"PE55":"Kimlik sağlayıcı tarafından başlatılan tek oturum açmaya izin verilmiyor",
"PE56":"SAML ile çıkış yapılırken bir hata oluştu",
"PE57":"SAML mesaj imzası yönetiminde hata",
"PE58":"SAML artefaktı kullanımı sırasında bir hata oluştu",
"PE59":"SAML oturumlarıyla iletişim hatası",
"PE60":"Servis sağlayıcısı yüklenirken hata oluştu",
"PE61":"SAML nitelikleri takas edilirken bir hata oluştu",
"PE62":"Bu bir OpenID endpoint sayfasıdır",
"PE63":"Size ait olmayan bir OpenID kimliğini kullanmayı deniyorsunuz",
"PE64":"Gerekli bir nitelik mevcut değil",
"PE65":"Federasyon güvenlik ilkesi tarafından yasaklandı",
"PE66":"Onay e-postası zaten gönderildi",
"PE67":"Parola alanı doldurulmuş olmalı",
"PE68":"CAS servisinde erişim sağlanamadı",
"PE69":"Lütfen e-posta adresinizi girin",
"PE70":"Eşleşen kullanıcı yok",
"PE71":"Lütfen yeni parolanızı girin",
"PE72":"Bir onay e-postası gönderildi",
"PE73":"Radius bağlantısı başarısız oldu",
"PE74":"Eski parolanız gerekli",
"PE75":"Tanınmayan bir IP adresinden geldiniz",
"PE76":"Captcha'yı girerken başarısız oldunuz",
"PE77":"Captcha'yı girmek zorundasınız",
"PE78":"Lütfen bilgilerinizi girin",
"PE79":"Bir bilgi eksik",
"PE80":"Bu adres zaten kullanılıyor",
"PE81":"Geçersiz kimlik doğrulama girişimi",
"PE82":"Kimlik doğrulama zaman aşımına uğradı",
"PE83":"U2F doğrulaması başarısız oldu. Tekrar deneyin veya yöneticinize başvurun",
"PE84":"Bu ana makineye erişmek için yetkili değilsiniz",
"PE85":"Uzak site daha yeni bir oturum istedi (ve UpgradeSession eklentisi yüklenmedi). Çıkış yap ve tekrar dene",
"PE86":"Hesabınız kilitlendi. Tekrar denemeden önce 30 saniye beklemelisiniz",
"PE87":"Portala erişmek için kimliğinizi yeniden doğrulamalısınız",
"PE88":"İki adımlı kimlik doğrulamayı kullanabilmeniz için hesabınıza ait bir e-posta adresi olmalıdır",
"PE89":"SAML servisine erişime izin verilmedi",
"PE90":"OIDC servisine erişime izin verilmedi",
"PE91":"OID servisine erişime izin verilmedi",
"PE92":"GET servisine erişime izin verilmedi",
"PE93":"IMPERSONATION servisine erişime izin verilmedi",
"PE94":"Gerekli bir nitelik mevcut değil",
"PE95":"DECRYPT servisine erişime izin verilmedi",
"PE96":"Geçersiz doğrulama kodu",
"2fRegRequired":"Bu servis iki adımlı kimlik doğrulama gerektiriyor. Şimdi bir cihaz ekleyin ve ardından portala geri dönün",
"accept":"Kabul Et",
"accessDenied":"Bu uygulamaya erişim yetkiniz yok",
"accountCreated":"Hesabınız oluşturuldu, geçici parolanız e-posta adresinize gönderildi.",
"accountCreationSuccess":"Hesabınız başarıyla oluşturuldu.",
"action":"Eylem",
"activeSessions":"Aktif TOA oturumları",
"all":"Hepsi",
"allowed":"Erişime izin verildi",
"anotherInformation":"Diğer bilgiler:",
"areYouSure":"Emin misiniz?",
"askToRenew":"Bu uygulama yeni bir kimlik doğrulama gerektiriyor. Tekrar doğrulamak ister misiniz?",
"askToUpgrade":"Bu uygulama daha yüksek bir doğrulama seviyesi gerektiriyor. Tekrar doğrulamak ister misiniz?",
"attributes":"NİTELİKLER",
"authLevel":"Kimlik doğrulama düzeyi",
"authPortal":"Kimlik doğrulama portalı",
"authRemaining":"%s kimlik doğrulaması kaldı, parolanızı değiştirin!",
"autoAccept":"30 saniye içerisinde otomatik olarak kabul et",
"autoGlobalLogout":"30 saniye içinde otomatik olarak global çıkış yap",
"back2CasUrl":ıkış yaptığınız uygulama, takip etmenizi istediği bir bağlantı sağladı",
"back2Portal":"Portala geri dön",
"badCode":"Hatalı kod",
"badName":"Hatalı isim",
"cancel":"İptal Et",
"captcha":"Captcha",
"changeKey":"Yeni anahtar üret",
"changePwd":"Parolanı değiştir",
"checkLastLogins":"Son girişlerimi kontrol et",
"checkUser":"Kullanıcı TOA profilini kontrol et",
"checkUserMerged":"Kullanıcı TOA profilini kontrol et. Bazı Gerçek ve Sahte TOA grupları birleştirildi!",
"checkUserComputeSession":"Hesaplanan oturum verisi!",
"choose2f":"İkinci faktörünüzü seçin",
"chooseApp":"Erişim yetkiniz olan bir uygulama seçin",
"cipheredValue":"Şifrelenmiş değer",
"clickHere":"Lütfen buraya tıklayın",
"clickOnYubikey":"Yubikey'e tıklayın",
"closeSSO":"TOA oturumunuzu kapatın",
"code":"Kod",
"confirmation":"Doğrulama",
"confirmLinkSent":"Bir onay linki gönderildi. Bu link şu zamana kadar geçerlidir",
"confirmPwd":"Parolayı doğrula",
"connect":"Bağlan",
"connectedAs":"Siz",
"contextSwitching_ON":"Başka bir kullanıcı gibi görün",
"contextSwitching_OFF":"Başka bir kullanıcı gibi davranmayı bırak",
"continue":"Devam Et",
"createAccount":"Hesap oluştur",
"current":"Geçerli",
"currentPwd":"Mevcut parola",
"date":"Tarih",
"decryptCipheredValue":"Şifrelenmiş değeri çöz",
"enterCred":"Lütfen kimlik bilgilerinizi giriniz",
"enterExt2fCode":"Size bir kod gönderildi. Lütfen onu giriniz",
"enterMail2fCode":"E-posta adresinize bir kod gönderildi. Lütfen onu giriniz",
"enterOpenIDLogin":"Lütfen OpenID giriş bilgilerinizi giriniz",
"enterRadius2fCode":"Lütfen OTP kodunuzu girin",
"enterRest2fCode":"Lütfen OTP kodunuzu girin",
"enterTotpCode":"TOTP kodunu gir",
"enterYubikey":"Lütfen Yubikey'inizi kullanın",
"errorMsg":"Hata Mesajı",
"expired2Fremoved":"Kullanım süresi dolan %s2F cihazı kaldırıldı!",
"ext2f":"Doğrulama Kodu",
"fillTheForm":"Formu doldur",
"firstName":"Ad",
"forbidden":"Erişim YASAKLI",
"forgotPwd":"Parolanızı mı unuttunuz?",
"generatePwd":"Parolayı otomatik olarak oluştur",
"globalLogout":"Global çıkış",
"gotNewMessages":"Yeni mesajlarınız var",
"goToPortal":"Portala git",
"gplSoft":"GPL lisansı kapsamında özgür yazılım",
"groups_sso":"TOA GRUPLARI",
"headers":"BAŞLIKLAR",
"id":"ID",
"imSure":"Eminim",
"info":"Bilgi",
"ipAddr":"IP adresi",
"key":"Anahtar",
"lastFailedLogins":"Son başarısız giriş denemeleri",
"lastLogins":"Son girişler",
"lastName":"Soyad",
"linkValidUntil":"Bu mesaj parolanızı sıfırlamak için bir bağlantı içerir, bu bağlantı şu zamana kadar geçerlidir",
"loginHistory":"Giriş geçmişi",
"login":"Giriş Yap",
"logout":ıkış Yap",
"logoutConfirm":ıkış yapmak ister misiniz?",
"logoutFromOtherApp":"Diğer uygulamalardan çıkış yap...",
"logoutFromSP":"Servis sağlayıcılardan çık...",
"macros":"MAKROLAR",
"mail":"E-posta",
"mail2f":"E-posta kodu",
"mailSent2":"E-posta adresinize bir mesaj gönderildi.",
"maintenanceMode":"Bu uygulama şuan bakımda, lütfen daha sonra bağlanmayı deneyin",
"maxNumberof2FDevicesReached":"Maksimum 2F cihaz sayısına ulaşıldı!",
"missingCode":"Kod eksik",
"name":"Ad",
"newMessages":"Yeni mesaj(lar)",
"newPassword":"Yeni parola",
"newPwdSentTo":"E-posta adresinize bir onay gönderildi.",
"noHistory":"Bu sizin ilk bağlantınız, hoş geldiniz!",
"notAnEncryptedValue":"Bu şifrelenmiş bir değer değil",
"notAuthorized":"Bunu yapmak için yetkili değilsiniz",
"notFound":"Bulunamadı: mevcut olmayan bir sayfaya erişmeyi deniyorsunuz",
"noTOTPFound":"TOTP bulunamadi",
"noU2FKeyFound":"U2F anahtarı bulunamadı",
"oidcConsent":"%s uygulaması şunları yapmak istiyor:",
"oidcConsents":"OIDC izinleri",
"oidcConsentsFull":"OpenID Connect izinleri",
"oneExpired2Fremoved":"Kullanım süresi dolan bir 2F cihazı kaldırıldı!",
"openidAp":"Aşağıdaki parametreleri sağlamayı kabul ediyor musunuz?",
"openIdExample":"örneğin: http://myopenid.org/toto",
"openidExchange":"%s üzerinde kimlik doğrulaması yapmak ister misiniz?",
"openidPA":"Veri kullanım ilkesi mevcut",
"openidRpns":"Federasyon için %s parametre isteği mevcut değil!",
"openSessionSpace":"Bu alan bir TOA oturumu açmanıza izin verir. Oturum açtığınızda profiliniz için yetkilendirilmiş tüm uygulamalara güvenli bir şekilde erişebilirsiniz.",
"openSSOSession":"TOA oturumunuzu açın",
"otherSessions":"Diğer aktif oturumlar",
"password":"Parola",
"passwordPolicy":"Lütfen aşağıdaki ilkeye uyun:",
"passwordPolicyMinSize":"Minimum parola uzunluğu",
"passwordPolicyMinLower":"Minimum küçük harf karakter sayısı:",
"passwordPolicyMinUpper":"Minimum büyük harf karakter sayısı:",
"passwordPolicyMinDigit":"Minimum rakam karakter sayısı",
"ppGrace":"kimlik doğrulaması kaldı, parolanızı değiştirin!",
"proxyError":"Kötü ağ geçidi: uzak sunucuya katılamıyor",
"pwdChange":"Parola değişimi",
"pwd":"Parola",
"pwdResetAlreadyIssued":"Parola sıfırlama istediği zaten şu tarihte alındı:",
"pwdWillExpire":"Parola süresinin dolmasına %s gün, %s saat, %s dakika ve %s saniye kaldı, parolayı değiştirin!",
"radius2f":"Radius",
"redirectedFrom":"Şuradan yeniden yönlendirildiniz: ",
"redirectedIn":"30 saniye içerisinde yönlendirileceksiniz",
"redirectionInProgress":"Yeniden yönlendirme işlemi devam ediyor...",
"redirectionToIdp":"Kimlik sağlayıcınıza yönlendirme",
"refreshrights":"Yetkilerimi yenile",
"refuse":"Reddet",
"register":"Kayıt Ol",
"registerRequestAlreadyIssued":"Bu hesap için kayıt olma isteği zaten şu tarihte alındı:",
"rememberChoice":"Seçimimi hatırla",
"removeOtherSessions":"Diğer oturumları sil",
"resendConfirmMail":"Doğrulama e-postasını tekrar gönder?",
"resentConfirm":"Onay e-postasının tekrar gönderilmesini ister misiniz?",
"resetPwd":"Parolamı sıfırla",
"rest2f":"Doğrulama kodu",
"rightsReloadNeedsLogout":"Yetkiler yeniden yüklendiğinde çıkış yapıp tekrar giriş yapmanız gerekir",
"scope":"Kapsam",
"search":"Ara",
"selectIdP":"Kimlik Sağlayıcısını seç",
"service":"Servis",
"sendPwd":"Bana bir bağlantı gönder",
"serverError":"Sunucuda hata oluşuyor",
"serviceProvidedBy":"Servis sağlayıcısı",
"sessionsDeleted":"Aşağıdaki oturumlar kapatıldı",
"sfaManager":"2ndFA Yöneticisi",
"spoofId":"Gizlenen ID",
"SSOSessionInactive":"TOA oturumu inaktif",
"startTime":"Oluşturulma tarihi",
"stayConnected":"Bu cihazda oturumu açık tut",
"submit":"Gönder",
"switchContext":"Bağlam değiştir",
"totp2f":"OTP Uygulaması",
"totpExistingKey":"Bir TOTP sırrı zaten mevcut",
"touchU2fDevice":"Lütfen şimdi yanıp sönen U2F cihazına dokunun.",
"touchU2fDeviceOrEnterTotp":"Lütfen şimdi yanıp sönen U2F cihazına dokunun veya TOTP kodunu girin.",
"type":"Tür",
"UA":"Kullanıcı ajanı",
"u2f":"U2F Anahtarı",
"u2fFailed":"U2F doğrulaması başarısız oldu. Tekrar deneyin veya yöneticinize başvurun",
"u2fPermission":"Sitenin güvenlik anahtarlarınıza erişmesine izin vermeniz istenebilir. İzin verdikten sonra, cihaz yanıp sönmeye başlayacaktır.",
"u2fWelcome":"U2F cihaz yönetimi",
"unableToGetKey":"Anahtarınıza erişilemiyor. Yeniden erişmeyi deneyin veya yöneticinize başvurun",
"unknownAction":"Bilinmeyen eylem",
"unregister":"Kaydını sil",
"updateCdc":"Ortak Etki Alanı Çerezini Güncelle",
"updateTime":"Güncelleme tarihi",
"upgradeSession":"Oturumu yükselt",
"user":"Kullanıcı",
"useYubikey":"Yubikey'inizi kullanın",
"utotp2f":"TOTP-veya-U2F",
"value":"Değer",
"verify":"Doğrula",
"VHnotFound":"Sanal Sunucu bulunamadı",
"wait":"Bekleyin",
"waitingmessage":"Kimlik doğrulama işlemi devam ediyor, lütfen bekleyin",
"warning":"Uyarı",
"welcomeOnPortal":"Güvenli kimlik doğrulama portalına hoş geldiniz.",
"yesResendMail":"Evet, tekrar e-posta gönder",
"yourAddress":"Adresini bil",
"yourApps":"Uygulamalarınız",
"yourEmail":"E-postanı bil",
"yourIdentity":"Kimliğini bil",
"yourIdentityIs":"Kimliğiniz",
"yourKeyIsRegistered":"Anahtarınız kaydedildi",
"yourKeyIsAlreadyRegistered":"Anahtarınız zaten kaydedilmiş!",
"yourKeyIsUnregistered":"Anahtarınız kaydedilmemiş",
"yourKeyIsVerified":"Anahtarınız doğrulandı",
"yourNewTotpKey":"Yeni TOTP anahtarınız, lütfen test edin ve kodu girin",
"yourOffline":"Çevrimdışıyken hesabına eriş",
"yourPhone":"Telefon numaranı bil",
"yourProfile":"Profilini bil",
"yourTotpKey":"TOTP anahtarınız",
"yubikey2f":"Yubikey"
}

View File

@ -153,8 +153,8 @@
"forbidden":"Access FORBIDDEN",
"forgotPwd":"忘记密码?",
"generatePwd":"自动生成密码",
"gotNewMessages":"您有一些新消息",
"globalLogout":"Global logout",
"gotNewMessages":"您有一些新消息",
"goToPortal":"回到首页",
"gplSoft":"受GPL协议保护的自由软件",
"groups_sso":"SSO GROUPS",

View File

@ -15,7 +15,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-lock"></i> </span>
</div>
<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
</div>
</div>
<div class="buttons">

View File

@ -15,7 +15,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-lock"></i> </span>
</div>
<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
</div>
</div>
<div class="buttons mb-3">

View File

@ -49,7 +49,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-lock"></i></span>
</div>
<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
</div>
</div>
<div class="buttons mb-3">

View File

@ -0,0 +1,18 @@
{
"accountCreated":"Hesabınız oluşturuldu, geçici parolanız e-posta adresinize gönderildi.",
"autoMail":"Bu e-posta otomatik olarak gönderilmiştir",
"click2Register":"Hesap açma işleminizi onaylamak için buraya tıklayın",
"click2Reset":"Parolanızı sıfırlamak için buraya tıklayın",
"hello":"Merhaba",
"mail2fSubject":"[LemonLDAP::NG] Giriş kodunuz",
"mailConfirmSubject":"[LemonLDAP::NG] Parola sıfırlama onayı",
"mailSubject":"[LemonLDAP::NG] Yeni parolanız",
"newPwdIs":"Yeni parolanız",
"pwdChanged":"Parolanız değiştirildi.",
"pwdIs":"Parolanız",
"registerConfirmSubject":"[LemonLDAP::NG] Hesap açma onayı",
"registerDoneSubject":"[LemonLDAP::NG] Yeni hesabınız",
"requestIssuedFromIP":"İstek IP'den gönderildi",
"yourLoginCodeIs":"Giriş kodunuz",
"yourLoginIs":"Giriş bilgileriniz"
}

View File

@ -0,0 +1,196 @@
use lib 'inc';
use Test::More;
use strict;
use IO::String;
use LWP::UserAgent;
use LWP::Protocol::PSGI;
use MIME::Base64;
use XML::LibXML;
BEGIN {
require 't/test-lib.pm';
require 't/saml-lib.pm';
}
my $debug = 'error';
my ( $issuer, $res );
SKIP: {
eval "use Lasso";
if ($@) {
skip 'Lasso not found';
}
# Initialization
ok( $issuer = issuer(), 'Issuer portal' );
ok(
$res = $issuer->_post(
'/', IO::String->new('user=french&password=french'),
length => 27
),
'Auth query'
);
expectOK($res);
my $idpId = expectCookie($res);
# Query IdP to access to SP
ok(
$res = $issuer->_get(
'/saml/singleSignOn',
query => 'IDPInitiated=1&spConfKey=sp.com',
cookie => "lemonldap=$idpId",
accept => 'test/html'
),
'Query IdP to access to SP'
);
expectOK($res);
ok(
$res->[2]->[0] =~
m#<form.+?action="http://auth.sp.com(.*?)".+?method="post"#,
'Form method is POST'
);
my $url = $1;
ok(
$res->[2]->[0] =~
/<input type="hidden".+?name="SAMLResponse".+?value="(.+?)"/s,
'Found SAML response'
);
my $s = decode_base64($1);
my $dom = XML::LibXML->load_xml( string => $s );
my $xpc = XML::LibXML::XPathContext->new($dom);
$xpc->registerNs( 'saml', 'urn:oasis:names:tc:SAML:2.0:assertion' );
foreach my $value (
$xpc->findnodes('//saml:Attribute[@Name="sn"]/saml:AttributeValue') )
{
is( $value->textContent, 'Accents', 'Check Attribute' );
}
}
clean_sessions();
done_testing();
sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',
userDB => 'Same',
issuerDBSAMLActivation => 1,
samlSPMetaDataMacros => {
'sp.com' => {
extracted_sn => '(split(/\s/, $cn))[1]'
}
},
samlSPMetaDataOptions => {
'sp.com' => {
samlSPMetaDataOptionsEncryptionMode => 'none',
samlSPMetaDataOptionsEnableIDPInitiatedURL => 1,
samlSPMetaDataOptionsSignSSOMessage => 1,
samlSPMetaDataOptionsSignSLOMessage => 1,
samlSPMetaDataOptionsCheckSSOMessageSignature => 1,
samlSPMetaDataOptionsCheckSLOMessageSignature => 1,
}
},
samlSPMetaDataExportedAttributes => {
'sp.com' => {
cn =>
'1;cn;urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
extracted_sn =>
'1;sn;urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
uid =>
'1;uid;urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
}
},
samlOrganizationDisplayName => "IDP",
samlOrganizationName => "IDP",
samlOrganizationURL => "http://www.idp.com/",
samlServicePrivateKeyEnc => "-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAnfKBDG/K0TnGT7Xu8q1N45sNWvIK91SqNg8nvN2uVeKoHADT
csus5Xn3id5+8Q9TuMFsW9kIEeXiaPKXQa9ryfSNDhWDWloNkpGEeWif2BnHUu46
Abu1UBWb0mH6VwcG1PR4qHruLis1odjQ1qnVDNfSEASVIppEBYjDX203ypmURIzU
6h53GRRRlf1BLWkbVn9ysmDeR57Xw5Rsx/+tBlcnMrkv/40DSUkehQIl2JmlFrl2
Caik+gU4pd20apA/pNLjBZF0OmGoS08AIR5NMd0KFa6CwZUUSHJqH5GFy5Y2yl4l
g8K0klAS9q7L7aXI+eFQZhkwidjpxXnHPyxIGQIDAQABAoIBAHnfqjX3eO8SfnP5
NURp90Td2mNHirCn0qLd9NKl1ySMPR1GgeH9SQ7Umu32EcteAUL5dOw2PiTZVmeW
cKINgsWVftXUQcOQ4xIqWKb51QUBdy0FhxrZRSFjWxXt5iYK1PmzHfsax/g1/S9C
RnqtFyjOy1bywkSt9jiy+9YBR2B7BDhLHlILbijWn5zaecaV4YA+L1UK4M/mehdb
+0FVPavbGpnlqBRTY+7YXfZ/mRPCfn5DvO9lW1O0pJMmNdBh9kmm3DxHf6AkK47a
43gO/dRWiWo2rZ/+Jw7uyqOb23U0MydP7kia0p3tzCUBPsrlgnichYG5RNFp0wqy
3VT1TYECgYEA0Y9vENy1jJd+s7WbGrsRtSKxfZgtJr0yjSlQVYrIlwbZSGn+ndxq
V2vVlwIgLX3pz6T40BMfk6SNx08jjy0Sgn6OAM0ILrinno8yWcSAMCmfCU0S/3O1
55bqtcnk4XTHBHzJ5OrnrPaW5ourvJz0lcWEKMg3BXxLzaF6ZRy85nECgYEAwPMD
LNAKLCDrUMyYFOpPyPLe7wvszcFvPipGgerSgFP1c6N7xaMUdHDYqBfuis1khPGF
YcMHeNBYmzX6yEGbp3lrB4PHpUySmTU3mv3u9I05aahInK21gXum3uRkCWyyIF6V
T/qeszl9mVOCp0CC4eG3IMVpaD0UKDEHVhERYCkCgYAjuTPRyA4a3Wh38ilysRkf
q75eDqcDx5Tqg3RyYKo5NK2troP9HSnzpSpQB8i8eI53G0RfFCN5479XjqIdMi3J
mRFUCZ+vd0L7wKVwsBK6Ix49U6o9adhElnGEc9pUpLeYiD1SjMjZr1+iBYVNLeRz
86vH1/mpMbsqXrCis/dvwQKBgGttomHr/w3s0jftget7PirrFrbP0+wHfDGHhjRF
kyhCFtJovrwefYALaIXGtVjw3LusYZA570oT7pGUb2naJZkMYEwR0jG1vZWx7KDO
K6JbkxDB0pPxn7JVL2bAkPYyX8boAohCSOQO6WBZ/8+xem3bp4OGhpa0EyoBik0g
OaVpAoGATj4SyYsE10hGT676iie8zy3fi5IPC3E+x4QlVuusaLtuY8LJA50stjtx
gUa/JAKlZZL+gvzvOviQIxyfIChXOdTt5uiOYkdHJDbAF3NSrji7hrXq4v8UZv75
8hBrwJZIpy6y01dRlrriHmPRtEq1pk7JX2uUg0sP5g4BEcsaCbc=
-----END RSA PRIVATE KEY-----
",
samlServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtR/wgDqWB4Maho5V6TjcL/NbNfjgIh7GcgkrB5RZcVT1GTej
JlMjUQdgBKBuZXQN+7/29P6UcGq1kYalURq6S8SpeJ1ofp5rBEoD/TIkvU0JOcid
65wp+fdzXGXsfiZvHraU74jSCgjP/wqfVGRyBIQzB0SIxSpnrsigqNsE1E94toDM
x4wovjHu/9ABAImREV7Sz83OeFF00/sghrjTEJOD/gHf04JCn9MgNOqvSTysr9LX
Wg/oUKQDEYeTq9ux6pq/oqv1MxwONbSZPtN5yD41mi+hT8Rh+W8Je8rsiML4VMxz
sb1l9303asw6suo5bLTISKNSbu1nt1NkpNxzywIDAQABAoIBAQCQkbvPPfP+bwC/
IeEk1IO7qkzFWa7czR+safD0jc6OjTdNN4F716Q6yt4zEzLKu8VliiW+C23EBQiD
7asKf4DvdTun0ExVtHDK7aEdeealSlXwz1ZtdypyILbtq1UGo/rR0v4x601rQPl0
IrBmFf6D6FkqleNtLJmxguXpoVfLdYKNwkxH2ux+GOA9r2o5pUCQmJGDap5YWRuQ
uB71ewJjVWujaL3e1ac/5cP7/tqWmgAiOaN8sYdD6+oWOR47bHj8JKcMBSl4y2QC
dL31cGmmf5KqBbtISki3RXfHHjT7E3Z85CbESkKTZlEb1ar3XmepY6Z7V5UO16oz
fFE5R6khAoGBAOl9Qb+qYVVO5ugE65ORjYVeuXykANhM9ssiY5a6zuAakWzw7Zv3
k6PXm9p7azlEXAlTnTXVwHYMyuuzZDvQ8LRV1iBOdPuIkUAmaQ5K9ASD7VcoHexh
k8DAKf9Ln7sTRaMdvgceRNczOmJOBIEpTZkssA/jVGXZsoyTWYl1en/ZAoGBAMaW
RnNbSNprEV2b8UeAJ6i77c4SXwu1I8X2NLtiLScb1ETBjfrdHmdlJglfyd/0gmhH
p/43Ku2iGUoY5KtuOI6QmahrJYQscRQhoj252VXadG6fNWWAlpgdCm9houhHb5BF
3zge/bTr0anUe9EA7Z/ymav12rEouoNjIlhI9C5DAoGATR85a2SMt8/TB0owwdJu
62GpZNkLCmcJkXkvaecUVAOSi2hdI4o4MwMRkK35cbX5rH74y4JqCtQY5pefgP53
sykzDAK+MyMdzxGg2764MRGegI5Yq+5jDmSquo+xF+q6srEtRk6iMG7UVwosBLmu
zuxqzySoiOfKSRKWnYe3SakCgYEAwWMkVkAmETXE4oDzFSsS8/mW2l//mPocTTK3
JWe1CunJ6+8FYbAlZJEW2ngismp8+CoXybNVpbZ+pC7buKoMf6EHUgCNt0pEEFO0
mCG9KSMk0XlPWXpArP9S4yaUq1itpzSz7QYZES+4rIcU0HLz9RgeWFyCTJWaFErc
7laVG9sCgYBKOtk5WlIOP4BxSd2y4cYzohgwTZIs1/2kTEn1u4eH73M1xvAlHHFB
wSF5QXgDKJ8pPAOhNWpdLO/PdtnQn91nOvTNc+ShJZzjdbneUdQVpWpoBf72uA+N
6rIVf1JBUL2p7HFHaGdUZC7KGQ+yv6ZHrE1+7202nuDvJdvGEEdFsQ==
-----END RSA PRIVATE KEY-----
",
samlServicePublicKeyEnc => "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnfKBDG/K0TnGT7Xu8q1N
45sNWvIK91SqNg8nvN2uVeKoHADTcsus5Xn3id5+8Q9TuMFsW9kIEeXiaPKXQa9r
yfSNDhWDWloNkpGEeWif2BnHUu46Abu1UBWb0mH6VwcG1PR4qHruLis1odjQ1qnV
DNfSEASVIppEBYjDX203ypmURIzU6h53GRRRlf1BLWkbVn9ysmDeR57Xw5Rsx/+t
BlcnMrkv/40DSUkehQIl2JmlFrl2Caik+gU4pd20apA/pNLjBZF0OmGoS08AIR5N
Md0KFa6CwZUUSHJqH5GFy5Y2yl4lg8K0klAS9q7L7aXI+eFQZhkwidjpxXnHPyxI
GQIDAQAB
-----END PUBLIC KEY-----
",
samlServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtR/wgDqWB4Maho5V6Tjc
L/NbNfjgIh7GcgkrB5RZcVT1GTejJlMjUQdgBKBuZXQN+7/29P6UcGq1kYalURq6
S8SpeJ1ofp5rBEoD/TIkvU0JOcid65wp+fdzXGXsfiZvHraU74jSCgjP/wqfVGRy
BIQzB0SIxSpnrsigqNsE1E94toDMx4wovjHu/9ABAImREV7Sz83OeFF00/sghrjT
EJOD/gHf04JCn9MgNOqvSTysr9LXWg/oUKQDEYeTq9ux6pq/oqv1MxwONbSZPtN5
yD41mi+hT8Rh+W8Je8rsiML4VMxzsb1l9303asw6suo5bLTISKNSbu1nt1NkpNxz
ywIDAQAB
-----END PUBLIC KEY-----
",
samlSPMetaDataXML => {
"sp.com" => {
samlSPMetaDataXML =>
samlSPMetaDataXML( 'sp', 'HTTP-Redirect' )
},
},
}
}
);
}

View File

@ -100,7 +100,7 @@ SKIP: {
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );

View File

@ -0,0 +1,115 @@
use lib 'inc';
use Test::More; # skip_all => 'CAS is in rebuild';
use strict;
use IO::String;
use LWP::UserAgent;
use LWP::Protocol::PSGI;
use MIME::Base64;
BEGIN {
require 't/test-lib.pm';
}
my $debug = 'error';
my ( $issuer, $res );
eval { require XML::Simple };
plan skip_all => "Missing dependencies: $@" if ($@);
ok( $issuer = issuer(), 'Issuer portal' );
count(1);
ok(
$res = $issuer->_get(
'/cas/login',
query => 'service=http://auth.sp.com/',
accept => 'text/html'
),
'Query CAS server'
);
count(1);
expectOK($res);
my $pdata = 'lemonldappdata=' . expectCookie( $res, 'lemonldappdata' );
# Try to authenticate to IdP
my $body = $res->[2]->[0];
$body =~ s/^.*?<form.*?>//s;
$body =~ s#</form>.*$##s;
my %fields =
( $body =~ /<input type="hidden".+?name="(.+?)".+?value="(.*?)"/sg );
$fields{user} = $fields{password} = 'french';
use URI::Escape;
my $s = join( '&', map { "$_=" . uri_escape( $fields{$_} ) } keys %fields );
ok(
$res = $issuer->_post(
'/cas/login',
IO::String->new($s),
cookie => $pdata,
accept => 'text/html',
length => length($s),
),
'Post authentication'
);
count(1);
my $idpId = expectCookie($res);
# Expect pdata to be cleared
$pdata = expectCookie( $res, 'lemonldappdata' );
ok( $pdata !~ 'issuerRequestsaml', 'SAML request cleared from pdata' );
count(1);
my ($query) =
expectRedirection( $res, qr#^http://auth.sp.com/\?(ticket=[^&]+)$# );
ok(
$res = $issuer->_get(
'/cas/p3/serviceValidate',
query => 'service=http://auth.sp.com/&' . $query,
accept => 'text/html'
),
'Query CAS server'
);
expectOK($res);
count(1);
ok( $res->[2]->[0] =~ m#<cas:sn>Accents</cas:sn>#, "Found macro attribute" );
count(1);
clean_sessions();
done_testing( count() );
sub issuer {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',
userDB => 'Same',
issuerDBCASActivation => 1,
casAttr => 'uid',
casAppMetaDataOptions => {
sp => {
casAppMetaDataOptionsService => 'http://auth.sp.com/',
},
},
casAppMetaDataExportedVars => {
sp => {
cn => 'cn',
sn => 'extracted_sn',
mail => 'mail',
uid => 'uid',
},
},
casAppMetaDataMacros => {
sp => {
extracted_sn => '(split(/\s/, $cn))[1]',
}
},
casAccessControlPolicy => 'error',
multiValuesSeparator => ';',
}
}
);
}

View File

@ -0,0 +1,192 @@
use lib 'inc';
use Test::More;
use strict;
use IO::String;
use LWP::UserAgent;
use LWP::Protocol::PSGI;
use MIME::Base64;
BEGIN {
require 't/test-lib.pm';
}
my $debug = 'error';
my $res;
my $url;
# Initialization
ok( my $op = op(), 'OP portal' );
ok( $res = $op->_get('/oauth2/jwks'), 'Get JWKS, endpoint /oauth2/jwks' );
expectOK($res);
my $jwks = $res->[2]->[0];
ok(
$res = $op->_get('/.well-known/openid-configuration'),
'Get metadata, endpoint /.well-known/openid-configuration'
);
expectOK($res);
my $metadata = $res->[2]->[0];
my $query =
"response_type=code&scope=openid%20profile%20email&client_id=rpid&state=af0ifjsldkj&redirect_uri=http%3A%2F%2Frp.com%2F";
# Push request to OP
ok(
$res =
$op->_get( "/oauth2/authorize", query => $query, accept => 'text/html' ),
"Start Authorization Code flow"
);
expectOK($res);
# Try to authenticate to OP
$query = "user=french&password=french&$query";
ok(
$res = $op->_post(
"/oauth2/authorize",
IO::String->new($query),
accept => 'text/html',
length => length($query),
),
"Post authentication, endpoint $url"
);
my $idpId = expectCookie($res);
my ($code) = expectRedirection( $res, qr#http://rp.com/\?.*code=([^&]+)# );
# Get access token
$query =
"grant_type=authorization_code&code=$code&redirect_uri=http%3A%2F%2Frp.com%2F";
ok(
$res = $op->_post(
"/oauth2/token",
IO::String->new($query),
accept => 'text/html',
length => length($query),
custom => {
HTTP_AUTHORIZATION => "Basic " . encode_base64("rpid:rpsecret"),
},
),
"Post token"
);
my $tokenresp = JSON::from_json( $res->[2]->[0] );
ok( my $access_token = $tokenresp->{access_token}, 'Found access token' );
# Get Userinfo
ok(
$res = $op->_get(
"/oauth2/userinfo",
accept => 'text/html',
custom => {
HTTP_AUTHORIZATION => "Bearer " . $access_token,
},
),
"Post token"
);
my $userinfo = JSON::from_json( $res->[2]->[0] );
is( $userinfo->{family_name}, 'Accents', 'Correct macro value' );
clean_sessions();
done_testing();
sub op {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
domain => 'idp.com',
portal => 'http://auth.op.com',
authentication => 'Demo',
userDB => 'Same',
issuerDBOpenIDConnectActivation => 1,
issuerDBOpenIDConnectRule => '$uid eq "french"',
oidcRPMetaDataExportedVars => {
rp => {
email => "mail",
family_name => "extract_sn",
name => "cn"
}
},
oidcServiceMetaDataIssuer => "http://auth.op.com",
oidcServiceMetaDataAuthorizeURI => "authorize",
oidcServiceMetaDataCheckSessionURI => "checksession.html",
oidcServiceMetaDataJWKSURI => "jwks",
oidcServiceMetaDataEndSessionURI => "logout",
oidcServiceMetaDataRegistrationURI => "register",
oidcServiceMetaDataTokenURI => "token",
oidcServiceMetaDataUserInfoURI => "userinfo",
oidcServiceAllowHybridFlow => 1,
oidcServiceAllowImplicitFlow => 1,
oidcServiceAllowDynamicRegistration => 1,
oidcServiceAllowAuthorizationCodeFlow => 1,
oidcRPMetaDataMacros => {
rp => {
extract_sn => '(split(/\s/, $cn))[1]',
}
},
oidcRPMetaDataOptions => {
rp => {
oidcRPMetaDataOptionsDisplayName => "RP",
oidcRPMetaDataOptionsIDTokenExpiration => 3600,
oidcRPMetaDataOptionsClientID => "rpid",
oidcRPMetaDataOptionsIDTokenSignAlg => "HS512",
oidcRPMetaDataOptionsBypassConsent => 1,
oidcRPMetaDataOptionsClientSecret => "rpsecret",
oidcRPMetaDataOptionsUserIDAttr => "",
oidcRPMetaDataOptionsAccessTokenExpiration => 3600,
}
},
oidcOPMetaDataOptions => {},
oidcOPMetaDataJSON => {},
oidcOPMetaDataJWKS => {},
oidcServiceMetaDataAuthnContext => {
'loa-4' => 4,
'loa-1' => 1,
'loa-5' => 5,
'loa-2' => 2,
'loa-3' => 3
},
oidcServicePrivateKeySig => "-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAs2jsmIoFuWzMkilJaA8//5/T30cnuzX9GImXUrFR2k9EKTMt
GMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8TrH1PHFmHpy8/qE/S5OhinIpIi7eb
ABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH1caJ8lmiERFj7IvNKqEhzAk0pyDr
8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdykX5rx0h5SslG3jVWYhZ/SOb2aIzO
r0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO8093X5VVk9vaPRg0zxJQ0Do0YLyzkR
isSAIFb0tdKuDnjRGK6y/N2j6At2HjkxntbtGQIDAQABAoIBADYq6LxJd977LWy3
0HT9nboFPIf+SM2qSEc/S5Po+6ipJBA4ZlZCMf7dHa6znet1TDpqA9iQ4YcqIHMH
6xZNQ7hhgSAzG9TrXBHqP+djDlrrGWotvjuy0IfS9ixFnnLWjrtAH9afRWLuG+a/
NHNC1M6DiiTE0TzL/lpt/zzut3CNmWzH+t19X6UsxUg95AzooEeewEYkv25eumWD
mfQZfCtSlIw1sp/QwxeJa/6LJw7KcPZ1wXUm1BN0b9eiKt9Cmni1MS7elgpZlgGt
xtfGTZtNLQ7bgDiM8MHzUfPBhbceNSIx2BeCuOCs/7eaqgpyYHBbAbuBQex2H61l
Lcc3Tz0CgYEA4Kx/avpCPxnvsJ+nHVQm5d/WERuDxk4vH1DNuCYBvXTdVCGADf6a
F5No1JcTH3nPTyPWazOyGdT9LcsEJicLyD8vCM6hBFstG4XjqcAuqG/9DRsElpHQ
yi1zc5DNP7Vxmiz9wII0Mjy0abYKtxnXh9YK4a9g6wrcTpvShhIcIb8CgYEAzGzG
lorVCfX9jXULIznnR/uuP5aSnTEsn0xJeqTlbW0RFWLdj8aIL1peirh1X89HroB9
GeTNqEJXD+3CVL2cx+BRggMDUmEz4hR59meZCDGUyT5fex4LIsceb/ESUl2jo6Sw
HXwWbN67rQ55N4oiOcOppsGxzOHkl5HdExKidycCgYEAr5Qev2tz+fw65LzfzHvH
Kj4S/KuT/5V6He731cFd+sEpdmX3vPgLVAFPG1Q1DZQT/rTzDDQKK0XX1cGiLG63
NnaqOye/jbfzOF8Z277kt51NFMDYhRLPKDD82IOA4xjY/rPKWndmcxwdob8yAIWh
efY76sMz6ntCT+xWSZA9i+ECgYBWMZM2TIlxLsBfEbfFfZewOUWKWEGvd9l5vV/K
D5cRIYivfMUw5yPq2267jPUolayCvniBH4E7beVpuPVUZ7KgcEvNxtlytbt7muil
5Z6X3tf+VodJ0Swe2NhTmNEB26uwxzLe68BE3VFCsbSYn2y48HAq+MawPZr18bHG
ZfgMxwKBgHHRg6HYqF5Pegzk1746uH2G+OoCovk5ylGGYzcH2ghWTK4agCHfBcDt
EYqYAev/l82wi+OZ5O8U+qjFUpT1CVeUJdDs0o5u19v0UJjunU1cwh9jsxBZAWLy
PAGd6SWf4S3uQCTw6dLeMna25YIlPh5qPA6I/pAahe8e3nSu2ckl
-----END RSA PRIVATE KEY-----
",
oidcServicePublicKeySig => "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2jsmIoFuWzMkilJaA8/
/5/T30cnuzX9GImXUrFR2k9EKTMtGMHCdKlWOl3BV+BTAU9TLz7Jzd/iJ5GJ6B8T
rH1PHFmHpy8/qE/S5OhinIpIi7ebABqnoVcwDdCa8ugzq8k8SWxhRNXfVIlwz4NH
1caJ8lmiERFj7IvNKqEhzAk0pyDr8hubveTC39xREujKlsqutpPAFPJ3f2ybVsdy
kX5rx0h5SslG3jVWYhZ/SOb2aIzOr0RMjhQmsYRwbpt3anjlBZ98aOzg7GAkbO80
93X5VVk9vaPRg0zxJQ0Do0YLyzkRisSAIFb0tdKuDnjRGK6y/N2j6At2Hjkxntbt
GQIDAQAB
-----END PUBLIC KEY-----
",
}
}
);
}

View File

@ -201,7 +201,7 @@ ok(
);
expectRedirection( $res, 'http://auth.example.com/' );
my $nbr = count_sessions();
$nbr = count_sessions();
ok( $nbr == 3, "Three sessions found" )
or explain("Number of session(s) found = $nbr");
count(4);

View File

@ -18,6 +18,7 @@ my $client = LLNG::Manager::Test->new( {
requireToken => 0,
securedCookie => 1,
https => 0,
whatToTrace => 'mail'
}
}
);

View File

@ -0,0 +1,59 @@
use Test::More;
use strict;
use IO::String;
BEGIN {
require 't/test-lib.pm';
}
my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
authentication => 'Demo',
userDB => 'Same',
refreshSessions => 1,
restSessionServer => 1,
}
}
);
my @ids;
foreach ( 1 .. 6 ) {
ok(
$res = $client->_post(
'/',
IO::String->new('user=dwho&password=dwho'),
length => 23,
),
"Auth query $_"
);
count(1);
push @ids, expectCookie($res);
}
$Lemonldap::NG::Portal::UserDB::Demo::demoAccounts{dwho}->{uid} = 'Dr Who';
ok(
$res = $client->_post(
'/refreshsessions', IO::String->new('{"uid":"dwho"}'),
length => 14,
type => 'application/json',
),
'Call refresh'
);
count(1);
expectOK($res);
my $c = @ids;
ok( $res->[2]->[0] =~ /"updated":$c/, "Count is $c" );
count(1);
foreach (@ids) {
ok( $res = $client->_get("/sessions/global/$_"), 'Get session content' );
ok( $res->[2]->[0] =~ /"uid":"Dr Who"/, ' Content is updated' );
count(2);
}
clean_sessions();
done_testing( count() );

View File

@ -97,7 +97,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);
@ -138,7 +138,7 @@ count(1);
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -40,7 +40,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -42,7 +42,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -81,7 +81,7 @@ ok(
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );

View File

@ -56,7 +56,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);
@ -141,7 +141,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -39,7 +39,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -38,7 +38,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -114,7 +114,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -327,6 +327,7 @@ Nginx support for LemonLDAP::NG.
Summary: LemonLDAP-NG Common Modules
Requires: perl(JSON::XS)
Requires: perl(String::Random)
Requires: perl(Cache::Cache)
%description -n perl-Lemonldap-NG-Common
This package installs the configuration libraries used by other LemonLDAP::NG