Commit ff095ca1 authored by Christophe Maudoux's avatar Christophe Maudoux 🐛

Merge branch 'v2.0'

parents d544eae5 39f93b0e
......@@ -23,7 +23,7 @@ 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))|(?:ustom(?:Plugins|Add)Param|ombModule)s)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|a(?:ut(?:hChoiceMod|oSigninR)ules|pplicationList)|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
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' );
......
......@@ -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} ];
}
}
......
......@@ -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)|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 = {
......
......@@ -2,6 +2,7 @@ package Lemonldap::NG::Common::Notifications;
use strict;
use Mouse;
use JSON qw(to_json);
our $VERSION = '2.1.0';
......@@ -32,8 +33,14 @@ has notifField => (
sub getNotifications {
my ( $self, $uid ) = @_;
my $forAll = $self->get( $self->conf->{notificationWildcard} );
if ( $uid and $uid eq '_all_' ) {
$self->logger->info("Retrieve ALL pending notifications");
my $all = $self->getAll();
$all = { map { $_ => to_json( $all->{$_} ) } keys %$all };
return { %$all, %$forAll };
}
my $forUser = $self->get($uid);
my $forAll = $self->get( $self->conf->{notificationWildcard} );
if ( $forUser and $forAll ) {
return { %$forUser, %$forAll };
}
......
......@@ -34,6 +34,9 @@ sub newNotification {
$self->logger->error("$err");
return ( 0, "$err" );
}
# Prevent to store time. Keep date only
$tmp =~ s/^(\d{4}-\d{2}-\d{2}).*$/$1/;
push @data, $tmp;
}
......@@ -44,6 +47,7 @@ sub newNotification {
}
push @data, ( $notif->{condition} );
$notif->{date} =~ s/^(\d{4}-\d{2}-\d{2}).*$/$1/;
my $body = to_json($notif);
push @notifs, [ @data, $body ];
}
......
......@@ -45,6 +45,9 @@ sub newNotification {
$self->logger->error("$err");
return 0;
}
# Prevent to store time. Keep date only
$tmp =~ s/^(\d{4}-\d{2}-\d{2}).*$/$1/;
push @data, $tmp;
}
......
......@@ -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'
},
......@@ -2032,6 +2043,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'
},
......@@ -3214,6 +3236,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'
},
......
......@@ -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
)
)
......
......@@ -2202,6 +2202,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
......@@ -2801,6 +2813,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 => {
......@@ -3888,6 +3912,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',
},
};
}
......
......@@ -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',
],
};
}
......
......@@ -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');
......
......@@ -200,7 +200,7 @@ sub notifications {
result => 1,
count => $count,
values => $res,
total => $total
total => $total
}
);
}
......@@ -220,8 +220,15 @@ sub notifications {
@r = sort { $a->{$f} cmp $b->{$f} } @r;
}
}
return $self->sendJSONresponse( $req,
{ result => 1, count => scalar(@r), values => \@r, total => $total } );
return $self->sendJSONresponse(
$req,
{
result => 1,
count => scalar(@r),
values => \@r,
total => $total
}
);
}
}
......
......@@ -217,7 +217,7 @@ llapp.controller 'TreeCtrl', [
$scope.getKey($scope.currentNode)
# NODES MANAGEMENT
id = 1
idinc = 1
$scope._findContainer = ->
return $scope._findScopeContainer().$modelValue
$scope._findScopeContainer = ->
......@@ -237,7 +237,7 @@ llapp.controller 'TreeCtrl', [
l = node.nodes.length
n = if l > 0 then l - 1 else 0
node.nodes.push
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: 'New rule'
re: 'Message'
comment: 'New rule'
......@@ -250,7 +250,7 @@ llapp.controller 'TreeCtrl', [
l = node.nodes.length
n = if l > 0 then l - 1 else 0
node.nodes.splice n, 0,
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: 'New rule'
re: '^/new'
comment: 'New rule'
......@@ -261,7 +261,7 @@ llapp.controller 'TreeCtrl', [
$scope.newPost = ->
node = $scope._findContainer()
node.nodes.push
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: "/absolute/path/to/form"
data: {}
type: "post"
......@@ -274,7 +274,7 @@ llapp.controller 'TreeCtrl', [
$scope.newAuthChoice = ->
node = $scope._findContainer()
node.nodes.push
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: "1_Key"
data: ['Null', 'Null', 'Null']
type: "authChoice"
......@@ -284,7 +284,7 @@ llapp.controller 'TreeCtrl', [
$scope.newHashEntry = ->
node = $scope._findContainer()
node.nodes.push
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: 'new'
data: ''
type: "keyText"
......@@ -295,7 +295,7 @@ llapp.controller 'TreeCtrl', [
if cs.$modelValue.type == 'menuApp'
cs = cs.$parentNodeScope
cs.$modelValue.nodes.push
id: "#{cs.$modelValue.id}/n#{id++}"
id: "#{cs.$modelValue.id}/n#{idinc++}"
title: "New category"
type: "menuCat"
nodes: []
......@@ -306,7 +306,7 @@ llapp.controller 'TreeCtrl', [
if cs.$modelValue.type == 'menuApp'
cs = cs.$parentNodeScope
cs.$modelValue.nodes.push
id: "#{cs.$modelValue.id}/n#{id++}"
id: "#{cs.$modelValue.id}/n#{idinc++}"
title: "New application"
type: "menuApp"
data:
......@@ -319,7 +319,7 @@ llapp.controller 'TreeCtrl', [
$scope.newCmbMod = ->
node = $scope._findContainer()
node.nodes.push
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: 'new'
type: 'cmbModule'
data:
......@@ -331,7 +331,7 @@ llapp.controller 'TreeCtrl', [
$scope.newSfExtra = ->
node = $scope._findContainer()
node.nodes.push
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: 'new'
type: 'sfExtra'
data:
......@@ -345,18 +345,18 @@ llapp.controller 'TreeCtrl', [
$scope.newSfOver = ->
d = $scope.currentNode.data
d.over = [] unless d.over
d.over.push ["new#{id++}", '']
d.over.push ["new#{idinc++}", '']
$scope.newCmbOver = ->
d = $scope.currentNode.data
d.over = [] unless d.over
d.over.push ["new#{id++}", '']
d.over.push ["new#{idinc++}", '']
$scope.newChoiceOver = ->
d = $scope.currentNode.data
console.log "data", d
d[5] = [] unless d[5]
d[5].push ["new#{id++}", '']
d[5].push ["new#{idinc++}", '']
# Add host
$scope.addHost = () ->
......@@ -370,7 +370,7 @@ llapp.controller 'TreeCtrl', [
$scope.addSamlAttribute = ->
node = $scope._findContainer()
node.nodes.push
id: "#{node.id}/n#{id++}"
id: "#{node.id}/n#{idinc++}"
title: 'new'
type: 'samlAttribute'
data: ['0', 'New', '', '']
......
/**
* @license AngularJS v1.7.8
* @license AngularJS v1.7.9
* (c) 2010-2018 Google, Inc. http://angularjs.org
* License: MIT
*/
......@@ -4252,7 +4252,7 @@ angular.module('ngAnimate', [], function initAngularHelpers() {
isFunction = angular.isFunction;
isElement = angular.isElement;
})
.info({ angularVersion: '1.7.8' })
.info({ angularVersion: '1.7.9' })
.directive('ngAnimateSwap', ngAnimateSwapDirective)
.directive('ngAnimateChildren', $$AnimateChildrenDirective)
......
/*
AngularJS v1.7.8
AngularJS v1.7.9
(c) 2010-2018 Google, Inc. http://angularjs.org
License: MIT
*/
......@@ -11,7 +11,7 @@ f=!a[b]||a[b+"-remove"]):-1===c&&(d="removeClass",f=a[b]||a[b+"-add"]);f&&(k[d].
b:a:b}function Ka(a,b,c){var d=Object.create(null),f=a.getComputedStyle(b)||{};s(c,function(a,c){var b=f[a];if(b){var L=b.charAt(0);if("-"===L||"+"===L||0<=L)b=Va(b);0===b&&(b=null);d[c]=b}});return d}function Va(a){var b=0;a=a.split(/\s*,\s*/);s(a,function(a){"s"===a.charAt(a.length-1)&&(a=a.substring(0,a.length-1));a=parseFloat(a)||0;b=b?Math.max(a,b):a});return b}function ya(a){return 0===a||null!=a}function La(a,b){var c=M,d=a+"s";b?c+="Duration":d+=" linear all";return[c,d]}function Ma(a,b,c){s(c,
function(c){a[c]=za(a[c])?a[c]:b.style.getPropertyValue(c)})}var M,Aa,ca,Ba;void 0===Y.ontransitionend&&void 0!==Y.onwebkittransitionend?(M="WebkitTransition",Aa="webkitTransitionEnd transitionend"):(M="transition",Aa="transitionend");void 0===Y.onanimationend&&void 0!==Y.onwebkitanimationend?(ca="WebkitAnimation",Ba="webkitAnimationEnd animationend"):(ca="animation",Ba="animationend");var qa=ca+"Delay",Ca=ca+"Duration",na=M+"Delay",Na=M+"Duration",Pa=z.$$minErr("ng"),ra={blockTransitions:function(a,
b){var c=b?"-"+b+"s":"";ma(a,[na,c]);return[na,c]}},Wa={transitionDuration:Na,transitionDelay:na,transitionProperty:M+"Property",animationDuration:Ca,animationDelay:qa,animationIterationCount:ca+"IterationCount"},Xa={transitionDuration:Na,transitionDelay:na,animationDuration:Ca,animationDelay:qa},Da,wa,s,Z,za,sa,Ea,ta,G,R,A,N;z.module("ngAnimate",[],function(){N=z.noop;Da=z.copy;wa=z.extend;A=z.element;s=z.forEach;Z=z.isArray;G=z.isString;ta=z.isObject;R=z.isUndefined;za=z.isDefined;Ea=z.isFunction;
sa=z.isElement}).info({angularVersion:"1.7.8"}).directive("ngAnimateSwap",["$animate",function(a){return{restrict:"A",transclude:"element",terminal:!0,priority:550,link:function(b,c,d,f,k){var e,Q;b.$watchCollection(d.ngAnimateSwap||d["for"],function(b){e&&a.leave(e);Q&&(Q.$destroy(),Q=null);(b||0===b)&&k(function(b,d){e=b;Q=d;a.enter(b,null,c)})})}}}]).directive("ngAnimateChildren",["$interpolate",function(a){return{link:function(b,c,d){function f(a){c.data("$$ngAnimateChildren","on"===a||"true"===
sa=z.isElement}).info({angularVersion:"1.7.9"}).directive("ngAnimateSwap",["$animate",function(a){return{restrict:"A",transclude:"element",terminal:!0,priority:550,link:function(b,c,d,f,k){var e,Q;b.$watchCollection(d.ngAnimateSwap||d["for"],function(b){e&&a.leave(e);Q&&(Q.$destroy(),Q=null);(b||0===b)&&k(function(b,d){e=b;Q=d;a.enter(b,null,c)})})}}}]).directive("ngAnimateChildren",["$interpolate",function(a){return{link:function(b,c,d){function f(a){c.data("$$ngAnimateChildren","on"===a||"true"===
a)}var k=d.ngAnimateChildren;G(k)&&0===k.length?c.data("$$ngAnimateChildren",!0):(f(a(k)(b)),d.$observe("ngAnimateChildren",f))}}}]).factory("$$rAFScheduler",["$$rAF",function(a){function b(a){d=d.concat(a);c()}function c(){if(d.length){for(var b=d.shift(),e=0;e<b.length;e++)b[e]();f||a(function(){f||c()})}}var d,f;d=b.queue=[];b.waitUntilQuiet=function(b){f&&f();f=a(function(){f=null;b();c()})};return b}]).provider("$$animateQueue",["$animateProvider",function(a){function b(a){return{addClass:a.addClass,
removeClass:a.removeClass,from:a.from,to:a.to}}function c(a){if(!a)return null;a=a.split(" ");var b=Object.create(null);s(a,function(a){b[a]=!0});return b}function d(a,b){if(a&&b){var d=c(b);return a.split(" ").some(function(a){return d[a]})}}function f(a,b,c){return e[a].some(function(a){return a(b,c)})}function k(a,b){var c=0<(a.addClass||"").length,d=0<(a.removeClass||"").length;return b?c&&d:c||d}var e=this.rules={skip:[],cancel:[],join:[]};e.join.push(function(a,b){return!a.structural&&k(a)});
e.skip.push(function(a,b){return!a.structural&&!k(a)});e.skip.push(function(a,b){return"leave"===b.event&&a.structural});e.skip.push(function(a,b){return b.structural&&2===b.state&&!a.structural});e.cancel.push(function(a,b){return b.structural&&a.structural});e.cancel.push(function(a,b){return 2===b.state&&a.structural});e.cancel.push(function(a,b){if(b.structural)return!1;var c=a.addClass,f=a.removeClass,k=b.addClass,e=b.removeClass;return R(c)&&R(f)||R(k)&&R(e)?!1:d(c,e)||d(f,k)});this.$get=["$$rAF",
......
/**
* @license AngularJS v1.7.8
* @license AngularJS v1.7.9
* (c) 2010-2018 Google, Inc. http://angularjs.org
* License: MIT
*/
......@@ -63,7 +63,7 @@
var ARIA_DISABLE_ATTR = 'ngAriaDisable';
var ngAriaModule = angular.module('ngAria', ['ng']).
info({ angularVersion: '1.7.8' }).
info({ angularVersion: '1.7.9' }).
provider('$aria', $AriaProvider);
/**
......
/*
AngularJS v1.7.8
AngularJS v1.7.9
(c) 2010-2018 Google, Inc. http://angularjs.org
License: MIT
*/
(function(t,l){'use strict';var c="BUTTON A INPUT TEXTAREA SELECT DETAILS SUMMARY".split(" "),m=function(a,e){if(-1!==e.indexOf(a[0].nodeName))return!0};l.module("ngAria",["ng"]).info({angularVersion:"1.7.8"}).provider("$aria",function(){function a(a,c,n,g){return function(d,f,b){if(!b.hasOwnProperty("ngAriaDisable")){var p=b.$normalize(c);!e[p]||m(f,n)||b[p]||d.$watch(b[a],function(b){b=g?!b:!!b;f.attr(c,b)})}}}var e={ariaHidden:!0,ariaChecked:!0,ariaReadonly:!0,ariaDisabled:!0,ariaRequired:!0,ariaInvalid:!0,