From 7d1739ad60bbd6d34c20dc35b4656554e71c8758 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fabian=20Gr=C3=BCnbichler?= Date: Tue, 21 Jan 2020 13:54:01 +0100 Subject: [PATCH] test: add parser/writer tests MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Grünbichler --- test/Makefile | 2 +- test/parser_writer.pl | 848 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 849 insertions(+), 1 deletion(-) create mode 100755 test/parser_writer.pl diff --git a/test/Makefile b/test/Makefile index 5c9c94e..dc75e4f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,6 +3,7 @@ all: .PHONY: check check: + perl -I.. parser_writer.pl perl -I.. perm-test1.pl perl -I.. perm-test2.pl perl -I.. perm-test3.pl @@ -10,4 +11,3 @@ check: perl -I.. perm-test5.pl perl -I.. perm-test6.pl perl -I.. perm-test7.pl - diff --git a/test/parser_writer.pl b/test/parser_writer.pl new file mode 100755 index 0000000..28c5a8c --- /dev/null +++ b/test/parser_writer.pl @@ -0,0 +1,848 @@ +#!/usr/bin/perl -w + +use strict; + +use Test::More; +use PVE::AccessControl; + +use Storable qw(dclone); + +PVE::AccessControl::create_roles(); +my $default_user_cfg = {}; +PVE::AccessControl::userconfig_force_defaults($default_user_cfg); + +my $add_default_user_properties = sub { + my ($user) = @_; + + $user->{enable} = 1 if !defined($user->{enable}); + $user->{expire} = 0 if !defined($user->{expire}); + $user->{email} = undef if !defined($user->{email}); + + return $user; +}; + +sub default_roles { + my $roles = dclone($default_user_cfg->{roles}); + return $roles; +} + +sub default_roles_with { + my ($extra_roles) = @_; + + my $roles = default_roles(); + + foreach my $r (@$extra_roles) { + my $role = dclone($r); + my $roleid = delete $role->{id}; + $roles->{$roleid} = $role; + } + + return $roles; +} + +sub default_users { + my $users = dclone($default_user_cfg->{users}); + return { map { $_ => $add_default_user_properties->($users->{$_}); } keys %$users}; +} + +sub default_users_with { + my ($extra_users) = @_; + + my $users = default_users(); + + foreach my $u (@$extra_users) { + my $user = dclone($u); + my $userid = delete $user->{id}; + $users->{$userid} = $add_default_user_properties->($user); + } + + return $users; +} + +sub default_groups { + return {}; +} + +sub default_groups_with { + my ($extra_groups) = @_; + + my $groups = default_groups(); + + foreach my $g (@$extra_groups) { + my $group = dclone($g); + my $groupid = delete $group->{id}; + $groups->{$groupid} = $group; + } + + return $groups; +} + +sub default_pools { + return {}; +} + +sub default_pools_with { + my ($extra_pools) = @_; + + my $pools = default_pools(); + + foreach my $p (@$extra_pools) { + my $pool = dclone($p); + my $poolid = delete $pool->{id}; + $pools->{$poolid} = $pool; + } + + return $pools; +} + +sub default_pool_vms_with { + my ($extra_pools) = @_; + + my $vms = {}; + foreach my $pool (@$extra_pools) { + foreach my $vmid (keys %{$pool->{vms}}) { + $vms->{$vmid} = $pool->{id}; + } + } + return $vms; +} + +sub default_acls { + return {}; +} + +# note: does not support merging paths! +sub default_acls_with { + my ($extra_acls) = @_; + + my $acls = default_acls(); + + foreach my $a (@$extra_acls) { + my $acl = dclone($a); + my $path = delete $acl->{path}; + $acls->{$path} = $acl; + } + + return $acls; +} + +my $default_cfg = { + test_pam => { + 'id' => 'test@pam', + 'enable' => 1, + 'expire' => 0, + 'email' => undef, + }, + test2_pam => { + 'id' => 'test2@pam', + 'enable' => 1, + 'expire' => 0, + 'email' => undef, + }, + test_pam_with_group => { + 'id' => 'test@pam', + 'enable' => 1, + 'expire' => 0, + 'email' => undef, + 'groups' => { 'testgroup' => 1 }, + }, + test2_pam_with_group => { + 'id' => 'test2@pam', + 'enable' => 1, + 'expire' => 0, + 'email' => undef, + 'groups' => { 'testgroup' => 1 }, + }, + test3_pam => { + 'id' => 'test3@pam', + 'enable' => 1, + 'expire' => 0, + 'email' => undef, + 'groups' => { 'another' => 1 }, + }, + test_group_empty => { + 'id' => 'testgroup', + users => {}, + }, + test_group_single_member => { + 'id' => 'testgroup', + 'users' => { + 'test@pam' => 1, + }, + }, + test_group_members => { + 'id' => 'testgroup', + 'users' => { + 'test@pam' => 1, + 'test2@pam' => 1, + }, + }, + test_group_second => { + 'id' => 'another', + users => { + 'test3@pam' => 1, + }, + }, + test_role_single_priv => { + 'id' => 'testrolesingle', + 'VM.Allocate' => 1, + }, + test_role_privs => { + 'id' => 'testrole', + 'VM.Allocate' => 1, + 'Datastore.Audit' => 1, + }, + test_pool_empty => { + 'id' => 'testpool', + vms => {}, + storage => {}, + }, + test_pool_members => { + 'id' => 'testpool', + vms => { 123 => 1, 1234 => 1}, + storage => { 'local' => 1, 'local-zfs' => 1}, + }, + test_pool_duplicate_vms => { + 'id' => 'test_duplicate_vms', + vms => {}, + storage => {}, + }, + test_pool_duplicate_storages => { + 'id' => 'test_duplicate_storages', + vms => {}, + storage => { 'local' => 1, 'local-zfs' => 1}, + }, + acl_simple_user => { + 'path' => '/', + users => { + 'test@pam' => { + 'PVEVMAdmin' => 1, + }, + }, + }, + acl_complex_users => { + 'path' => '/storage', + users => { + 'test2@pam' => { + 'PVEDatastoreUser' => 1, + }, + 'test@pam' => { + 'PVEDatastoreAdmin' => 1, + }, + }, + }, + acl_complex_missing_user => { + 'path' => '/storage', + users => { + 'test2@pam' => { + 'PVEDatastoreUser' => 1, + }, + }, + }, + acl_simple_group => { + 'path' => '/', + groups => { + 'testgroup' => { + 'PVEVMAdmin' => 1, + }, + }, + }, + acl_complex_groups => { + 'path' => '/storage', + groups => { + 'testgroup' => { + 'PVEDatastoreAdmin' => 1, + }, + 'another' => { + 'PVEDatastoreUser' => 1, + }, + }, + }, + acl_simple_group_noprop => { + 'path' => '/', + groups => { + 'testgroup' => { + 'PVEVMAdmin' => 0, + }, + }, + }, + acl_complex_groups_noprop => { + 'path' => '/storage', + groups => { + 'testgroup' => { + 'PVEDatastoreAdmin' => 0, + }, + 'another' => { + 'PVEDatastoreUser' => 0, + }, + }, + }, + acl_complex_missing_group => { + 'path' => '/storage', + groups => { + 'another' => { + 'PVEDatastoreUser' => 1, + }, + }, + }, + acl_missing_role => { + 'path' => '/storage', + users => { + 'test@pam' => { + 'MissingRole' => 1, + }, + }, + }, +}; + +$default_cfg->{'acl_complex_mixed_root'} = { + 'path' => '/', + users => $default_cfg->{'acl_simple_user'}->{users}, + groups => $default_cfg->{'acl_simple_group'}->{groups}, +}; + +$default_cfg->{'acl_complex_mixed_storage'} = { + 'path' => '/storage', + users => $default_cfg->{'acl_complex_users'}->{users}, + groups => $default_cfg->{'acl_complex_groups'}->{groups}, +}; + +$default_cfg->{'acl_complex_mixed_root_noprop'} = { + 'path' => '/', + users => $default_cfg->{'acl_simple_user'}->{users}, + groups => $default_cfg->{'acl_simple_group_noprop'}->{groups}, +}; + +$default_cfg->{'acl_complex_mixed_storage_noprop'} = { + 'path' => '/storage', + users => $default_cfg->{'acl_complex_users'}->{users}, + groups => $default_cfg->{'acl_complex_groups_noprop'}->{groups}, +}; + +my $default_raw = { + users => { + 'root@pam' => 'user:root@pam:1:0::::::', + 'test_pam' => 'user:test@pam:1:0::::::', + 'test2_pam' => 'user:test2@pam:1:0::::::', + 'test3_pam' => 'user:test3@pam:1:0::::::', + }, + groups => { + 'test_group_empty' => 'group:testgroup:::', + 'test_group_single_member' => 'group:testgroup:test@pam::', + 'test_group_members' => 'group:testgroup:test2@pam,test@pam::', + 'test_group_members_out_of_order' => 'group:testgroup:test@pam,test2@pam::', + 'test_group_second' => 'group:another:test3@pam::', + }, + roles => { + 'test_role_single_priv' => 'role:testrolesingle:VM.Allocate:', + 'test_role_privs' => 'role:testrole:Datastore.Audit,VM.Allocate:', + 'test_role_privs_out_of_order' => 'role:testrole:VM.Allocate,Datastore.Audit:', + 'test_role_privs_duplicate' => 'role:testrole:VM.Allocate,Datastore.Audit,VM.Allocate:', + 'test_role_privs_invalid' => 'role:testrole:VM.Invalid,Datastore.Audit,VM.Allocate:', + }, + pools => { + 'test_pool_empty' => 'pool:testpool::::', + 'test_pool_invalid' => 'pool:testpool::non-numeric:inval!d:', + 'test_pool_members' => 'pool:testpool::123,1234:local,local-zfs:', + 'test_pool_duplicate_vms' => 'pool:test_duplicate_vms::123,1234::', + 'test_pool_duplicate_vms_expected' => 'pool:test_duplicate_vms::::', + 'test_pool_duplicate_storages' => 'pool:test_duplicate_storages:::local,local-zfs:', + }, + acl => { + 'acl_simple_user' => 'acl:1:/:test@pam:PVEVMAdmin:', + 'acl_complex_users_1' => 'acl:1:/storage:test@pam:PVEDatastoreAdmin:', + 'acl_complex_users_2' => 'acl:1:/storage:test2@pam:PVEDatastoreUser:', + 'acl_simple_group' => 'acl:1:/:@testgroup:PVEVMAdmin:', + 'acl_complex_groups_1' => 'acl:1:/storage:@testgroup:PVEDatastoreAdmin:', + 'acl_complex_groups_2' => 'acl:1:/storage:@another:PVEDatastoreUser:', + 'acl_simple_group_noprop' => 'acl:0:/:@testgroup:PVEVMAdmin:', + 'acl_complex_groups_1_noprop' => 'acl:0:/storage:@testgroup:PVEDatastoreAdmin:', + 'acl_complex_groups_2_noprop' => 'acl:0:/storage:@another:PVEDatastoreUser:', + 'acl_complex_mixed_1' => 'acl:1:/:@testgroup,test@pam:PVEVMAdmin:', + 'acl_complex_mixed_2' => 'acl:1:/storage:@testgroup,test@pam:PVEDatastoreAdmin:', + 'acl_complex_mixed_3' => 'acl:1:/storage:@another,test2@pam:PVEDatastoreUser:', + 'acl_missing_role' => 'acl:1:/storage:test@pam:MissingRole:', + }, +}; + +my $tests = [ + { + name => "empty_config", + config => {}, + expected_config => { + users => { 'root@pam' => { enable => 1 } }, + roles => default_roles(), + }, + raw => "", + expected_raw => "\n\n\n\n", + }, + { + name => "default_config", + config => { + users => default_users(), + roles => default_roles(), + }, + raw => $default_raw->{users}->{'root@pam'}."\n\n\n\n\n", + }, + { + name => "group_empty", + config => { + users => default_users(), + roles => default_roles(), + groups => default_groups_with([$default_cfg->{'test_group_empty'}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n". + $default_raw->{groups}->{'test_group_empty'}."\n\n". + "\n\n", + }, + { + name => "group_inexisting_member", + config => { + users => default_users(), + roles => default_roles(), + groups => default_groups_with([$default_cfg->{'test_group_empty'}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n". + "group:testgroup:does_not_exist::". + "\n\n\n\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n\n". + $default_raw->{groups}->{'test_group_empty'}."\n\n". + "\n\n", + }, + { + name => "group_invalid_member", + expected_config => { + users => default_users(), + roles => default_roles(), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n". + 'group:inval!d:root@pam:'. + "\n\n", + }, + { + name => "group_with_one_member", + config => { + users => default_users_with([$default_cfg->{test_pam_with_group}]), + roles => default_roles(), + groups => default_groups_with([$default_cfg->{'test_group_single_member'}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_single_member'}."\n\n". + "\n\n", + }, + { + name => "group_with_members", + config => { + users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{test2_pam_with_group}]), + roles => default_roles(), + groups => default_groups_with([$default_cfg->{'test_group_members'}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_members'}."\n\n". + "\n\n", + }, + { + name => "custom_role_with_single_priv", + config => { + users => default_users(), + roles => default_roles_with([$default_cfg->{test_role_single_priv}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n\n". + $default_raw->{roles}->{'test_role_single_priv'}."\n\n", + }, + { + name => "custom_role_with_privs", + config => { + users => default_users(), + roles => default_roles_with([$default_cfg->{test_role_privs}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n\n". + $default_raw->{roles}->{'test_role_privs'}."\n\n", + }, + { + name => "custom_role_with_duplicate_privs", + config => { + users => default_users(), + roles => default_roles_with([$default_cfg->{test_role_privs}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n\n". + $default_raw->{roles}->{'test_role_privs_duplicate'}."\n\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n\n". + $default_raw->{roles}->{'test_role_privs'}."\n\n", + }, + { + name => "custom_role_with_invalid_priv", + config => { + users => default_users(), + roles => default_roles_with([$default_cfg->{test_role_privs}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n\n". + $default_raw->{roles}->{'test_role_privs_invalid'}."\n\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n\n". + $default_raw->{roles}->{'test_role_privs'}."\n\n", + }, + { + name => "pool_empty", + config => { + users => default_users(), + roles => default_roles(), + pools => default_pools_with([$default_cfg->{test_pool_empty}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n". + $default_raw->{pools}->{'test_pool_empty'}."\n\n\n", + }, + { + name => "pool_invalid", + config => { + users => default_users(), + roles => default_roles(), + pools => default_pools_with([$default_cfg->{test_pool_empty}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n". + $default_raw->{pools}->{'test_pool_invalid'}."\n\n\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n". + $default_raw->{pools}->{'test_pool_empty'}."\n\n\n", + }, + { + name => "pool_members", + config => { + users => default_users(), + roles => default_roles(), + pools => default_pools_with([$default_cfg->{test_pool_members}]), + vms => default_pool_vms_with([$default_cfg->{test_pool_members}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n". + $default_raw->{pools}->{'test_pool_members'}."\n\n\n", + }, + { + name => "pool_duplicate_members", + config => { + users => default_users(), + roles => default_roles(), + pools => default_pools_with([$default_cfg->{test_pool_members}, $default_cfg->{test_pool_duplicate_vms}, $default_cfg->{test_pool_duplicate_storages}]), + vms => default_pool_vms_with([$default_cfg->{test_pool_members}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n". + $default_raw->{pools}->{'test_pool_members'}."\n". + $default_raw->{pools}->{'test_pool_duplicate_vms'}."\n". + $default_raw->{pools}->{'test_pool_duplicate_storages'}."\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n". + $default_raw->{pools}->{'test_pool_duplicate_storages'}."\n". + $default_raw->{pools}->{'test_pool_duplicate_vms_expected'}."\n". + $default_raw->{pools}->{'test_pool_members'}."\n\n\n", + }, + { + name => "acl_simple_user", + config => { + users => default_users_with([$default_cfg->{test_pam}]), + roles => default_roles(), + acl => default_acls_with([$default_cfg->{acl_simple_user}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n\n\n\n". + $default_raw->{acl}->{'acl_simple_user'}."\n", + }, + { + name => "acl_complex_users", + config => { + users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{'test2_pam'}]), + roles => default_roles(), + acl => default_acls_with([$default_cfg->{acl_simple_user}, $default_cfg->{acl_complex_users}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n\n\n\n". + $default_raw->{acl}->{'acl_simple_user'}."\n". + $default_raw->{acl}->{'acl_complex_users_1'}."\n". + $default_raw->{acl}->{'acl_complex_users_2'}."\n", + }, + { + name => "acl_complex_missing_user", + config => { + users => default_users_with([$default_cfg->{test2_pam}]), + roles => default_roles(), + acl => default_acls_with([$default_cfg->{acl_complex_missing_user}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n\n\n\n\n". + $default_raw->{acl}->{'acl_simple_user'}."\n". + $default_raw->{acl}->{'acl_complex_users_1'}."\n". + $default_raw->{acl}->{'acl_complex_users_2'}."\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n\n\n\n\n". + $default_raw->{acl}->{'acl_complex_users_2'}."\n", + }, + { + name => "acl_simple_group", + config => { + users => default_users_with([$default_cfg->{test_pam_with_group}]), + groups => default_groups_with([$default_cfg->{'test_group_single_member'}]), + roles => default_roles(), + acl => default_acls_with([$default_cfg->{acl_simple_group}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_single_member'}."\n\n\n\n". + $default_raw->{acl}->{'acl_simple_group'}."\n", + }, + { + name => "acl_complex_groups", + config => { + users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]), + groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]), + roles => default_roles(), + acl => default_acls_with([$default_cfg->{acl_simple_group}, $default_cfg->{acl_complex_groups}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_second'}."\n". + $default_raw->{groups}->{'test_group_members'}."\n\n\n\n". + $default_raw->{acl}->{'acl_simple_group'}."\n". + $default_raw->{acl}->{'acl_complex_groups_1'}."\n". + $default_raw->{acl}->{'acl_complex_groups_2'}."\n", + }, + { + name => "acl_complex_missing_group", + config => { + users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{'test2_pam'}, $default_cfg->{'test3_pam'}]), + groups => default_groups_with([$default_cfg->{'test_group_second'}]), + roles => default_roles(), + acl => default_acls_with([$default_cfg->{acl_complex_missing_group}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_second'}."\n". + $default_raw->{acl}->{'acl_simple_group'}."\n". + $default_raw->{acl}->{'acl_complex_groups_1'}."\n". + $default_raw->{acl}->{'acl_complex_groups_2'}."\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_second'}."\n\n\n\n". + $default_raw->{acl}->{'acl_complex_groups_2'}."\n", + }, + { + name => "acl_missing_role", + config => { + users => default_users_with([$default_cfg->{test_pam}]), + roles => default_roles(), + acl => default_acls_with([$default_cfg->{acl_missing_role}, $default_cfg->{acl_simple_user}]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n\n\n\n". + $default_raw->{acl}->{'acl_simple_user'}."\n". + $default_raw->{acl}->{'acl_missing_role'}."\n", + }, + { + name => "acl_complex_mixed", + config => { + users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]), + groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]), + roles => default_roles(), + acl => default_acls_with([ + $default_cfg->{acl_complex_mixed_root}, + $default_cfg->{acl_complex_mixed_storage}, + ]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_second'}."\n". + $default_raw->{groups}->{'test_group_members'}."\n\n\n\n". + $default_raw->{acl}->{'acl_simple_group'}."\n". + $default_raw->{acl}->{'acl_complex_groups_1'}."\n". + $default_raw->{acl}->{'acl_complex_groups_2'}."\n". + $default_raw->{acl}->{'acl_simple_user'}."\n". + $default_raw->{acl}->{'acl_complex_users_1'}."\n". + $default_raw->{acl}->{'acl_complex_users_2'}."\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_second'}."\n". + $default_raw->{groups}->{'test_group_members'}."\n\n\n\n". + $default_raw->{acl}->{'acl_complex_mixed_1'}."\n". + $default_raw->{acl}->{'acl_complex_mixed_2'}."\n". + $default_raw->{acl}->{'acl_complex_mixed_3'}."\n", + }, + { + name => "acl_complex_mixed_prop_noprop_no_merge_sort_by_path", + config => { + users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]), + groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]), + roles => default_roles(), + acl => default_acls_with([ + $default_cfg->{acl_complex_mixed_root_noprop}, + $default_cfg->{acl_complex_mixed_storage_noprop}, + ]), + }, + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_second'}."\n". + $default_raw->{groups}->{'test_group_members'}."\n\n\n\n". + $default_raw->{acl}->{'acl_simple_group_noprop'}."\n". + $default_raw->{acl}->{'acl_simple_user'}."\n". + $default_raw->{acl}->{'acl_complex_groups_1_noprop'}."\n". + $default_raw->{acl}->{'acl_complex_groups_2_noprop'}."\n". + $default_raw->{acl}->{'acl_complex_users_1'}."\n". + $default_raw->{acl}->{'acl_complex_users_2'}."\n", + }, + { + name => "sort_roles_and_privs", + raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{roles}->{'test_role_single_priv'}."\n\n". + $default_raw->{roles}->{'test_role_privs_out_of_order'}."\n\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n\n\n\n". + $default_raw->{roles}->{'test_role_privs'}."\n". + $default_raw->{roles}->{'test_role_single_priv'}."\n\n", + }, + { + name => "sort_users_and_group_members", + raw => "". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_members_out_of_order'}."\n\n". + "\n\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_members'}."\n\n". + "\n\n", + }, + { + name => "sort_user_groups_and_acls", + raw => "". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{groups}->{'test_group_members_out_of_order'}."\n\n\n\n". + $default_raw->{groups}->{'test_group_second'}."\n". + $default_raw->{acl}->{'acl_simple_user'}."\n". + $default_raw->{acl}->{'acl_simple_group'}."\n". + $default_raw->{acl}->{'acl_complex_users_1'}."\n". + $default_raw->{acl}->{'acl_complex_users_2'}."\n". + $default_raw->{acl}->{'acl_complex_groups_1'}."\n". + $default_raw->{acl}->{'acl_complex_groups_2'}."\n", + expected_raw => "". + $default_raw->{users}->{'root@pam'}."\n". + $default_raw->{users}->{'test2_pam'}."\n". + $default_raw->{users}->{'test3_pam'}."\n". + $default_raw->{users}->{'test_pam'}."\n\n". + $default_raw->{groups}->{'test_group_second'}."\n". + $default_raw->{groups}->{'test_group_members'}."\n\n\n\n". + $default_raw->{acl}->{'acl_complex_mixed_1'}."\n". + $default_raw->{acl}->{'acl_complex_mixed_2'}."\n". + $default_raw->{acl}->{'acl_complex_mixed_3'}."\n", + }, + { + name => 'default_values', + config => { + users => { + 'root@pam' => { + enable => 0, + expire => 0, + email => undef, + }, + 'test@pam' => { + enable => 0, + expire => 0, + email => undef, + }, + }, + roles => default_roles_with([{ id => 'testrole' }]), + groups => default_groups_with([$default_cfg->{test_group_empty}]), + pools => default_pools_with([$default_cfg->{test_pool_empty}]), + }, + raw => "". + 'user:root@pam'."\n". + 'user:test@pam'."\n\n". + 'group:testgroup'."\n\n". + 'pool:testpool'."\n\n". + 'role:testrole'."\n\n". + 'acl::/:', + expected_raw => "". + 'user:root@pam:0:0::::::'."\n". + 'user:test@pam:0:0::::::'."\n\n". + 'group:testgroup:::'."\n\n". + 'pool:testpool::::'."\n\n". + 'role:testrole::'."\n\n", + }, +]; + + +my $number_of_tests_run = 0; +foreach my $t (@$tests) { + my $expected_config = $t->{expected_config} // $t->{config}; + my $expected_raw = $t->{expected_raw} // $t->{raw}; + if (defined($t->{raw})) { + my $parsed = PVE::AccessControl::parse_user_config($t->{name}, $t->{raw}); + if (defined($expected_config)) { + is_deeply($parsed, $expected_config, "$t->{name}_parse"); + $number_of_tests_run++; + } + if (defined($t->{expected_raw}) && !defined($t->{config})) { + is(PVE::AccessControl::write_user_config($t->{name}, $parsed), $t->{expected_raw}, "$t->{name}_rewrite"); + $number_of_tests_run++; + } + + } + if (defined($t->{config})) { + my $written = PVE::AccessControl::write_user_config($t->{name}, $t->{config}); + if (defined($expected_raw)) { + is($written, $expected_raw, "$t->{name}_write"); + $number_of_tests_run++; + } + if (defined($t->{expected_config}) && !defined($t->{raw})) { + is_deeply(PVE::AccessControl::parse_user_config($t->{name}, $t->{written}), $t->{expected_config}, "$t->{name}_reparse"); + $number_of_tests_run++; + } + } +}; + +done_testing( $number_of_tests_run); -- 2.39.2