Merge branch 'issue1521-appmenu' into 'v2.0'

Preserve applicationList key names (#1521)

See merge request lemonldap-ng/lemonldap-ng!76
This commit is contained in:
Xavier Guimard 2019-05-28 22:10:53 +02:00
commit 8fd3f6be90
5 changed files with 108 additions and 37 deletions

View File

@ -645,7 +645,14 @@ sub _scanCatsAndApps {
my ( $self, $apps, $baseId ) = @_;
my @res;
foreach my $cat ( grep { not /^(?:catname|type)$/ } sort keys %$apps ) {
foreach my $cat (
sort {
( $apps->{$a}->{order} || 0 ) <=> ( $apps->{$b}->{order} || 0 )
or $a cmp $b
}
grep { not /^(?:catname|type|order)$/ } keys %$apps
)
{
my $item = { id => "$baseId/$cat" };
if ( $apps->{$cat}->{type} eq 'category' ) {
$item->{title} = $apps->{$cat}->{catname};

View File

@ -110,8 +110,8 @@ sub appListDiff {
my ( $self, @conf ) = @_;
my @res;
my @keys = (
[ sort grep { $_ !~ /^(?:catname|type)$/ } keys %{ $conf[0] } ],
[ sort grep { $_ !~ /^(?:catname|type)$/ } keys %{ $conf[1] } ]
[ sort grep { $_ !~ /^(?:catname|type|order)$/ } keys %{ $conf[0] } ],
[ sort grep { $_ !~ /^(?:catname|type|order)$/ } keys %{ $conf[1] } ]
);
while ( my $key = shift @{ $keys[0] } ) {

View File

@ -70,7 +70,7 @@ has confChanged => (
);
# Properties required during build
has refConf => ( is => 'ro', isa => 'HashRef', required => 1 );
has refConf => ( is => 'ro', isa => 'HashRef', required => 1 );
has req => ( is => 'ro', required => 1 );
has newConf => ( is => 'rw', isa => 'HashRef' );
has tree => ( is => 'rw', isa => 'ArrayRef' );
@ -160,7 +160,7 @@ sub _scanNodes {
hdebug("Looking to $name");
# subnode
my $subNodes = $leaf->{nodes} // $leaf->{_nodes};
my $subNodes = $leaf->{nodes} // $leaf->{_nodes};
my $subNodesCond = $leaf->{nodes_cond} // $leaf->{_nodes_cond};
##################################
@ -587,6 +587,22 @@ sub _scanNodes {
$cmp = $cmp->{$cat};
}
my $newapp = $app;
# Compute a nice name for new nodes, taking care of potential conflicts
# For some reason, the manager sends /nNaN sometimes
if ( $newapp =~ /^n(\d+|NaN)$/ ) {
# Remove all special characters
my $baseName = $leaf->{title} =~ s/\W//gr;
$baseName = lc $baseName;
$newapp = $baseName;
my $cnt = 1;
while ( exists $cn->{$newapp} ) {
$newapp = "${baseName}_" . $cnt++;
}
}
# Create new category
#
# Note that this works because nodes are ordered so "cat/cat2/app"
@ -594,11 +610,14 @@ sub _scanNodes {
if ( $leaf->{type} eq 'menuCat' ) {
hdebug(' menu cat');
$knownCat->{__id}++;
my $s = $knownCat->{$app} = sprintf '%04d-cat',
$knownCat->{__id};
$cn->{$s} = { catname => $leaf->{title}, type => 'category' };
$knownCat->{$app} = $newapp;
$cn->{$newapp} = {
catname => $leaf->{title},
type => 'category',
order => $knownCat->{__id}
};
unless ($cmp->{$app}
and $cmp->{$app}->{catname} eq $cn->{$s}->{catname} )
and $cmp->{$app}->{catname} eq $cn->{$newapp}->{catname} )
{
$self->confChanged(1);
push @{ $self->changes },
@ -606,15 +625,17 @@ sub _scanNodes {
key => join(
', ', 'applicationList', @path, $leaf->{title}
),
new => $cn->{$s}->{catname},
old => ( $cn->{$s} ? $cn->{$s}->{catname} : undef )
new => $cn->{$newapp}->{catname},
old => (
$cn->{$newapp} ? $cn->{$newapp}->{catname} : undef
)
};
}
if ( ref $subNodes ) {
$self->_scanNodes($subNodes) or return 0;
}
my @listCatRef = keys %{ $cmp->{$app} };
my @listCatNew = keys %{ $cn->{$s} };
my @listCatNew = keys %{ $cn->{$newapp} };
# Check for deleted
unless ( @listCatRef == @listCatNew ) {
@ -631,10 +652,12 @@ sub _scanNodes {
else {
hdebug(' new app');
$knownCat->{__id}++;
my $name = sprintf( '%04d-app', $knownCat->{__id} );
$cn->{$name} =
{ type => 'application', options => $leaf->{data} };
$cn->{$name}->{options}->{name} = $leaf->{title};
$cn->{$newapp} = {
type => 'application',
options => $leaf->{data},
order => $knownCat->{__id}
};
$cn->{$newapp}->{options}->{name} = $leaf->{title};
unless ( $cmp->{$app} ) {
$self->confChanged(1);
push @{ $self->changes },
@ -644,9 +667,17 @@ sub _scanNodes {
};
}
else {
foreach my $k ( keys %{ $cn->{$name}->{options} } ) {
# Check for change in ordering
if ( ( $cn->{$newapp}->{order} || 0 ) !=
( $cmp->{$newapp}->{order} || 0 ) )
{
$self->confChanged(1);
}
# Check for change in options
foreach my $k ( keys %{ $cn->{$newapp}->{options} } ) {
unless ( $cmp->{$app}->{options}->{$k} eq
$cn->{$name}->{options}->{$k} )
$cn->{$newapp}->{options}->{$k} )
{
$self->confChanged(1);
push @{ $self->changes },
@ -654,7 +685,7 @@ sub _scanNodes {
key => join( ', ',
'applicationList', @path,
$leaf->{title}, $k ),
new => $cn->{$name}->{options}->{$k},
new => $cn->{$newapp}->{options}->{$k},
old => $cmp->{$app}->{options}->{$k}
};
}
@ -1070,14 +1101,14 @@ sub _unitTest {
or $attr->{type} =~ /Container$/ )
{
my $keyMsg = $attr->{keyMsgFail} // $type->{keyMsgFail};
my $msg = $attr->{msgFail} // $type->{msgFail};
my $msg = $attr->{msgFail} // $type->{msgFail};
$res = 0
unless (
$self->_execTest( {
keyTest => $attr->{keyTest} // $type->{keyTest},
keyTest => $attr->{keyTest} // $type->{keyTest},
keyMsgFail => $attr->{keyMsgFail}
// $type->{keyMsgFail},
test => $attr->{test} // $type->{test},
test => $attr->{test} // $type->{test},
msgFail => $attr->{msgFail} // $type->{msgFail},
},
$conf->{$key},

View File

@ -1,7 +1,6 @@
{
"applicationList": {
"0001-cat": {
"catname": "Sample applications",
"0002-app": {
"options": {
"description": "A simple application displaying authenticated user",
@ -10,6 +9,7 @@
"name": "Application Test 1",
"uri": "http://test1.example.com/"
},
"order": 2,
"type": "application"
},
"0003-app": {
@ -20,12 +20,14 @@
"name": "Application Test 2",
"uri": "http://test2.example.com/"
},
"order": 3,
"type": "application"
},
"catname": "Sample applications",
"order": 1,
"type": "category"
},
"0004-cat": {
"catname": "Administration",
"0005-app": {
"options": {
"description": "Configure LemonLDAP::NG WebSSO",
@ -34,6 +36,7 @@
"name": "WebSSO Manager",
"uri": "http://manager.example.com/"
},
"order": 5,
"type": "application"
},
"0006-app": {
@ -44,6 +47,7 @@
"name": "Notifications explorer",
"uri": "http://manager.example.com/notifications"
},
"order": 6,
"type": "application"
},
"0007-app": {
@ -54,12 +58,14 @@
"name": "Sessions explorer",
"uri": "http://manager.example.com/sessions"
},
"order": 7,
"type": "application"
},
"catname": "Administration",
"order": 4,
"type": "category"
},
"0008-cat": {
"catname": "Documentation",
"0009-app": {
"options": {
"description": "Documentation supplied with LemonLDAP::NG",
@ -68,6 +74,7 @@
"name": "Local documentation",
"uri": "http://manager.example.com/doc/"
},
"order": 9,
"type": "application"
},
"0010-app": {
@ -78,8 +85,11 @@
"name": "Official Website",
"uri": "http://lemonldap-ng.org/"
},
"order": 10,
"type": "application"
},
"catname": "Documentation",
"order": 8,
"type": "category"
}
},
@ -104,8 +114,7 @@
"Auth-User": "$uid"
}
},
"exportedVars": {
},
"exportedVars": {},
"globalStorage": "Apache::Session::File",
"globalStorageOptions": {
"Directory": "t/sessions",
@ -132,11 +141,11 @@
"_whatToTrace": "$_auth eq 'SAML' ? \"$_user\\@$_idpConfKey\" : \"$_user\""
},
"notification": 1,
"oldNotifFormat": 0,
"notificationStorage": "File",
"notificationStorageOptions": {
"dirName": "t/notifications"
},
"oldNotifFormat": 0,
"passwordDB": "Demo",
"persistentStorage": "Apache::Session::File",
"persistentStorageOptions": {

View File

@ -193,7 +193,7 @@ sub _buildCategoryHash {
# Extract applications from hash
my $apphash;
foreach my $catkey ( sort keys %$cathash ) {
next if $catkey =~ /(type|options|catname)/;
next if $catkey =~ /(type|options|catname|order)/;
if ( $cathash->{$catkey}->{type} eq "application" ) {
$apphash->{$catkey} = $cathash->{$catkey};
}
@ -201,15 +201,29 @@ sub _buildCategoryHash {
# Display applications first
if ( scalar keys %$apphash > 0 ) {
foreach my $appkey ( sort keys %$apphash ) {
foreach my $appkey (
sort {
($apphash->{$a}->{order} || 0) <=> ($apphash->{$b}->{order} || 0)
or $a cmp $b
}
keys %$apphash
)
{
push @$applications,
$self->_buildApplicationHash( $appkey, $apphash->{$appkey} );
}
}
# Display subcategories
foreach my $catkey ( sort keys %$cathash ) {
next if $catkey =~ /(type|options|catname)/;
foreach my $catkey (
sort {
($cathash->{$a}->{order} || 0) <=> ($cathash->{$b}->{order} || 0)
or $a cmp $b
}
grep { not /^(?:catname|type|options|order)$/ } keys %$cathash
)
{
if ( $cathash->{$catkey}->{type} eq "category" ) {
push @$categories,
$self->_buildCategoryHash( $req, $catkey, $cathash->{$catkey},
@ -246,7 +260,7 @@ sub _buildApplicationHash {
# Detect sub applications
my $subapphash;
foreach my $key ( sort keys %$apphash ) {
next if $key =~ /(type|options|catname)/;
next if $key =~ /(type|options|catname|order)/;
if ( $apphash->{$key}->{type} eq "application" ) {
$subapphash->{$key} = $apphash->{$key};
}
@ -254,7 +268,14 @@ sub _buildApplicationHash {
# Display sub applications
if ( scalar keys %$subapphash > 0 ) {
foreach my $appkey ( sort keys %$subapphash ) {
foreach my $appkey (
sort {
($subapphash->{$a}->{order} || 0) <=> ( $subapphash->{$b}->{order} || 0 )
or $a cmp $b
}
keys %$subapphash
)
{
push @$applications,
$self->_buildApplicationHash( $appkey, $subapphash->{$appkey} );
}
@ -305,7 +326,7 @@ sub _filterHash {
my ( $self, $req, $apphash ) = @_;
foreach my $key ( keys %$apphash ) {
next if $key =~ /(type|options|catname)/;
next if $key =~ /(type|options|catname|order)/;
if ( $apphash->{$key}->{type}
and $apphash->{$key}->{type} eq "category" )
{
@ -319,7 +340,7 @@ sub _filterHash {
# Find sub applications and filter them
foreach my $appkey ( keys %{ $apphash->{$key} } ) {
next if $appkey =~ /(type|options|catname)/;
next if $appkey =~ /(type|options|catname|order)/;
# We have sub elements, so we filter them
$self->_filterHash( $req, $apphash->{$key} );
@ -393,7 +414,7 @@ sub _isCategoryEmpty {
# Test sub categories
foreach $key ( keys %$apphash ) {
next if $key =~ /(type|options|catname)/;
next if $key =~ /(type|options|catname|order)/;
if ( $apphash->{$key}->{type}
and $apphash->{$key}->{type} eq "category" )
{
@ -408,10 +429,12 @@ sub _isCategoryEmpty {
# Temporary store 'options'
my $tmp_options = $apphash->{options};
my $tmp_catname = $apphash->{catname};
my $tmp_order = $apphash->{order};
delete $apphash->{type};
delete $apphash->{options};
delete $apphash->{catname};
delete $apphash->{order};
if ( scalar( keys %$apphash ) ) {
@ -420,6 +443,7 @@ sub _isCategoryEmpty {
$apphash->{type} = "category";
$apphash->{options} = $tmp_options;
$apphash->{catname} = $tmp_catname;
$apphash->{order} = $tmp_order;
# Return false
return 0;