]> git.proxmox.com Git - pve-access-control.git/blame - src/test/parser_writer.pl
bump version to 8.1.4
[pve-access-control.git] / src / test / parser_writer.pl
CommitLineData
7d1739ad
FG
1#!/usr/bin/perl -w
2
3use strict;
95fb22e6 4use warnings;
7d1739ad 5
95fb22e6 6use Storable qw(dclone);
7d1739ad 7use Test::More;
7d1739ad 8
95fb22e6 9use PVE::AccessControl;
7d1739ad
FG
10
11PVE::AccessControl::create_roles();
12my $default_user_cfg = {};
13PVE::AccessControl::userconfig_force_defaults($default_user_cfg);
14
15my $add_default_user_properties = sub {
16 my ($user) = @_;
17
18 $user->{enable} = 1 if !defined($user->{enable});
19 $user->{expire} = 0 if !defined($user->{expire});
20 $user->{email} = undef if !defined($user->{email});
21
22 return $user;
23};
24
25sub default_roles {
26 my $roles = dclone($default_user_cfg->{roles});
27 return $roles;
28}
29
30sub default_roles_with {
31 my ($extra_roles) = @_;
32
33 my $roles = default_roles();
34
35 foreach my $r (@$extra_roles) {
36 my $role = dclone($r);
37 my $roleid = delete $role->{id};
38 $roles->{$roleid} = $role;
39 }
40
41 return $roles;
42}
43
44sub default_users {
45 my $users = dclone($default_user_cfg->{users});
46 return { map { $_ => $add_default_user_properties->($users->{$_}); } keys %$users};
47}
48
49sub default_users_with {
50 my ($extra_users) = @_;
51
52 my $users = default_users();
53
54 foreach my $u (@$extra_users) {
55 my $user = dclone($u);
56 my $userid = delete $user->{id};
57 $users->{$userid} = $add_default_user_properties->($user);
58 }
59
60 return $users;
61}
62
63sub default_groups {
64 return {};
65}
66
67sub default_groups_with {
68 my ($extra_groups) = @_;
69
70 my $groups = default_groups();
71
72 foreach my $g (@$extra_groups) {
73 my $group = dclone($g);
74 my $groupid = delete $group->{id};
75 $groups->{$groupid} = $group;
76 }
77
78 return $groups;
79}
80
81sub default_pools {
82 return {};
83}
84
85sub default_pools_with {
86 my ($extra_pools) = @_;
87
88 my $pools = default_pools();
89
90 foreach my $p (@$extra_pools) {
91 my $pool = dclone($p);
92 my $poolid = delete $pool->{id};
93 $pools->{$poolid} = $pool;
94 }
95
96 return $pools;
97}
98
99sub default_pool_vms_with {
100 my ($extra_pools) = @_;
101
102 my $vms = {};
103 foreach my $pool (@$extra_pools) {
104 foreach my $vmid (keys %{$pool->{vms}}) {
105 $vms->{$vmid} = $pool->{id};
106 }
107 }
108 return $vms;
109}
110
111sub default_acls {
112 return {};
113}
114
115# note: does not support merging paths!
116sub default_acls_with {
117 my ($extra_acls) = @_;
118
119 my $acls = default_acls();
120
121 foreach my $a (@$extra_acls) {
122 my $acl = dclone($a);
123 my $path = delete $acl->{path};
170cf17b
FG
124 my $split_path = [ split("/", $path) ];
125 my $node = $acls;
126 for my $p (@$split_path) {
127 next if !$p;
128 $node->{children} = {} if !$node->{children};
129 $node->{children}->{$p} = {} if !$node->{children}->{$p};
130 $node = $node->{children}->{$p};
131 }
132 %$node = ( %$acl );
7d1739ad
FG
133 }
134
135 return $acls;
136}
137
138my $default_cfg = {
139 test_pam => {
140 'id' => 'test@pam',
141 'enable' => 1,
142 'expire' => 0,
143 'email' => undef,
144 },
145 test2_pam => {
146 'id' => 'test2@pam',
147 'enable' => 1,
148 'expire' => 0,
149 'email' => undef,
150 },
151 test_pam_with_group => {
152 'id' => 'test@pam',
153 'enable' => 1,
154 'expire' => 0,
155 'email' => undef,
156 'groups' => { 'testgroup' => 1 },
157 },
158 test2_pam_with_group => {
159 'id' => 'test2@pam',
160 'enable' => 1,
161 'expire' => 0,
162 'email' => undef,
163 'groups' => { 'testgroup' => 1 },
164 },
165 test3_pam => {
166 'id' => 'test3@pam',
167 'enable' => 1,
168 'expire' => 0,
169 'email' => undef,
170 'groups' => { 'another' => 1 },
171 },
891f7afa
FG
172 test_pam_with_token => {
173 'id' => 'test@pam',
174 'enable' => 1,
175 'expire' => 0,
176 'email' => undef,
177 'tokens' => {
178 'full' => {
179 'privsep' => 0,
180 'expire' => 0,
181 },
182 },
183 },
184 test_pam2_with_token => {
185 'id' => 'test2@pam',
186 'enable' => 1,
187 'expire' => 0,
188 'email' => undef,
189 'tokens' => {
190 'full' => {
191 'privsep' => 0,
192 'expire' => 0,
193 },
194 'privsep' => {
195 'privsep' => 1,
196 'expire' => 0,
197 },
198 'expired' => {
199 'privsep' => 0,
200 'expire' => 1,
201 },
202 },
203 },
7d1739ad
FG
204 test_group_empty => {
205 'id' => 'testgroup',
206 users => {},
207 },
208 test_group_single_member => {
209 'id' => 'testgroup',
210 'users' => {
211 'test@pam' => 1,
212 },
213 },
214 test_group_members => {
215 'id' => 'testgroup',
216 'users' => {
217 'test@pam' => 1,
218 'test2@pam' => 1,
219 },
220 },
221 test_group_second => {
222 'id' => 'another',
223 users => {
224 'test3@pam' => 1,
225 },
226 },
227 test_role_single_priv => {
228 'id' => 'testrolesingle',
229 'VM.Allocate' => 1,
230 },
231 test_role_privs => {
232 'id' => 'testrole',
233 'VM.Allocate' => 1,
234 'Datastore.Audit' => 1,
235 },
236 test_pool_empty => {
237 'id' => 'testpool',
238 vms => {},
239 storage => {},
4418b06b 240 pools => {},
7d1739ad
FG
241 },
242 test_pool_members => {
243 'id' => 'testpool',
244 vms => { 123 => 1, 1234 => 1},
245 storage => { 'local' => 1, 'local-zfs' => 1},
4418b06b 246 pools => {},
7d1739ad
FG
247 },
248 test_pool_duplicate_vms => {
249 'id' => 'test_duplicate_vms',
250 vms => {},
251 storage => {},
4418b06b 252 pools => {},
7d1739ad
FG
253 },
254 test_pool_duplicate_storages => {
255 'id' => 'test_duplicate_storages',
256 vms => {},
257 storage => { 'local' => 1, 'local-zfs' => 1},
4418b06b 258 pools => {},
7d1739ad
FG
259 },
260 acl_simple_user => {
261 'path' => '/',
262 users => {
263 'test@pam' => {
264 'PVEVMAdmin' => 1,
265 },
266 },
267 },
268 acl_complex_users => {
269 'path' => '/storage',
270 users => {
271 'test2@pam' => {
272 'PVEDatastoreUser' => 1,
273 },
274 'test@pam' => {
275 'PVEDatastoreAdmin' => 1,
276 },
277 },
278 },
279 acl_complex_missing_user => {
280 'path' => '/storage',
281 users => {
282 'test2@pam' => {
283 'PVEDatastoreUser' => 1,
284 },
5654260e
DC
285 'test@pam' => {
286 'PVEDatastoreAdmin' => 1,
287 },
7d1739ad
FG
288 },
289 },
891f7afa
FG
290 acl_simple_token => {
291 'path' => '/',
292 tokens => {
293 'test@pam!full' => {
294 'PVEVMAdmin' => 1,
295 },
296 },
297 },
298 acl_complex_tokens => {
299 'path' => '/storage',
300 tokens => {
301 'test2@pam!privsep' => {
302 'PVEDatastoreUser' => 1,
303 },
304 'test2@pam!expired' => {
305 'PVEDatastoreAdmin' => 1,
306 },
307 'test@pam!full' => {
308 'PVEDatastoreAdmin' => 1,
309 },
310 },
311 },
312 acl_complex_missing_token => {
313 'path' => '/storage',
314 tokens => {
315 'test2@pam!expired' => {
316 'PVEDatastoreAdmin' => 1,
317 },
318 'test2@pam!privsep' => {
319 'PVEDatastoreUser' => 1,
320 },
321 },
322 },
7d1739ad
FG
323 acl_simple_group => {
324 'path' => '/',
325 groups => {
326 'testgroup' => {
327 'PVEVMAdmin' => 1,
328 },
329 },
330 },
331 acl_complex_groups => {
332 'path' => '/storage',
333 groups => {
334 'testgroup' => {
335 'PVEDatastoreAdmin' => 1,
336 },
337 'another' => {
338 'PVEDatastoreUser' => 1,
339 },
340 },
341 },
342 acl_simple_group_noprop => {
343 'path' => '/',
344 groups => {
345 'testgroup' => {
346 'PVEVMAdmin' => 0,
347 },
348 },
349 },
350 acl_complex_groups_noprop => {
351 'path' => '/storage',
352 groups => {
353 'testgroup' => {
354 'PVEDatastoreAdmin' => 0,
355 },
356 'another' => {
357 'PVEDatastoreUser' => 0,
358 },
359 },
360 },
361 acl_complex_missing_group => {
362 'path' => '/storage',
363 groups => {
5654260e
DC
364 'testgroup' => {
365 'PVEDatastoreAdmin' => 1,
366 },
7d1739ad
FG
367 'another' => {
368 'PVEDatastoreUser' => 1,
369 },
370 },
371 },
372 acl_missing_role => {
373 'path' => '/storage',
374 users => {
375 'test@pam' => {
376 'MissingRole' => 1,
377 },
378 },
379 },
380};
381
382$default_cfg->{'acl_complex_mixed_root'} = {
383 'path' => '/',
384 users => $default_cfg->{'acl_simple_user'}->{users},
385 groups => $default_cfg->{'acl_simple_group'}->{groups},
386};
387
388$default_cfg->{'acl_complex_mixed_storage'} = {
389 'path' => '/storage',
390 users => $default_cfg->{'acl_complex_users'}->{users},
391 groups => $default_cfg->{'acl_complex_groups'}->{groups},
392};
393
394$default_cfg->{'acl_complex_mixed_root_noprop'} = {
395 'path' => '/',
396 users => $default_cfg->{'acl_simple_user'}->{users},
397 groups => $default_cfg->{'acl_simple_group_noprop'}->{groups},
398};
399
400$default_cfg->{'acl_complex_mixed_storage_noprop'} = {
401 'path' => '/storage',
402 users => $default_cfg->{'acl_complex_users'}->{users},
403 groups => $default_cfg->{'acl_complex_groups_noprop'}->{groups},
404};
405
406my $default_raw = {
407 users => {
408 'root@pam' => 'user:root@pam:1:0::::::',
409 'test_pam' => 'user:test@pam:1:0::::::',
410 'test2_pam' => 'user:test2@pam:1:0::::::',
411 'test3_pam' => 'user:test3@pam:1:0::::::',
412 },
413 groups => {
414 'test_group_empty' => 'group:testgroup:::',
415 'test_group_single_member' => 'group:testgroup:test@pam::',
416 'test_group_members' => 'group:testgroup:test2@pam,test@pam::',
417 'test_group_members_out_of_order' => 'group:testgroup:test@pam,test2@pam::',
418 'test_group_second' => 'group:another:test3@pam::',
419 },
891f7afa
FG
420 tokens => {
421 'test_token_simple' => 'token:test@pam!full:0:0::',
422 'test_token_multi_full' => 'token:test2@pam!full:0:0::',
423 'test_token_multi_privsep' => 'token:test2@pam!privsep:0:1::',
424 'test_token_multi_expired' => 'token:test2@pam!expired:1:0::',
425 },
7d1739ad
FG
426 roles => {
427 'test_role_single_priv' => 'role:testrolesingle:VM.Allocate:',
428 'test_role_privs' => 'role:testrole:Datastore.Audit,VM.Allocate:',
429 'test_role_privs_out_of_order' => 'role:testrole:VM.Allocate,Datastore.Audit:',
430 'test_role_privs_duplicate' => 'role:testrole:VM.Allocate,Datastore.Audit,VM.Allocate:',
431 'test_role_privs_invalid' => 'role:testrole:VM.Invalid,Datastore.Audit,VM.Allocate:',
432 },
433 pools => {
434 'test_pool_empty' => 'pool:testpool::::',
435 'test_pool_invalid' => 'pool:testpool::non-numeric:inval!d:',
436 'test_pool_members' => 'pool:testpool::123,1234:local,local-zfs:',
437 'test_pool_duplicate_vms' => 'pool:test_duplicate_vms::123,1234::',
438 'test_pool_duplicate_vms_expected' => 'pool:test_duplicate_vms::::',
439 'test_pool_duplicate_storages' => 'pool:test_duplicate_storages:::local,local-zfs:',
440 },
441 acl => {
442 'acl_simple_user' => 'acl:1:/:test@pam:PVEVMAdmin:',
443 'acl_complex_users_1' => 'acl:1:/storage:test@pam:PVEDatastoreAdmin:',
444 'acl_complex_users_2' => 'acl:1:/storage:test2@pam:PVEDatastoreUser:',
891f7afa
FG
445 'acl_simple_token' => 'acl:1:/:test@pam!full:PVEVMAdmin:',
446 'acl_complex_tokens_1' => 'acl:1:/storage:test2@pam!expired,test@pam!full:PVEDatastoreAdmin:',
447 'acl_complex_tokens_2' => 'acl:1:/storage:test2@pam!privsep:PVEDatastoreUser:',
448 'acl_complex_tokens_1_missing' => 'acl:1:/storage:test2@pam!expired:PVEDatastoreAdmin:',
7d1739ad
FG
449 'acl_simple_group' => 'acl:1:/:@testgroup:PVEVMAdmin:',
450 'acl_complex_groups_1' => 'acl:1:/storage:@testgroup:PVEDatastoreAdmin:',
451 'acl_complex_groups_2' => 'acl:1:/storage:@another:PVEDatastoreUser:',
452 'acl_simple_group_noprop' => 'acl:0:/:@testgroup:PVEVMAdmin:',
453 'acl_complex_groups_1_noprop' => 'acl:0:/storage:@testgroup:PVEDatastoreAdmin:',
454 'acl_complex_groups_2_noprop' => 'acl:0:/storage:@another:PVEDatastoreUser:',
455 'acl_complex_mixed_1' => 'acl:1:/:@testgroup,test@pam:PVEVMAdmin:',
456 'acl_complex_mixed_2' => 'acl:1:/storage:@testgroup,test@pam:PVEDatastoreAdmin:',
457 'acl_complex_mixed_3' => 'acl:1:/storage:@another,test2@pam:PVEDatastoreUser:',
458 'acl_missing_role' => 'acl:1:/storage:test@pam:MissingRole:',
459 },
460};
461
462my $tests = [
463 {
464 name => "empty_config",
465 config => {},
466 expected_config => {
170cf17b 467 acl_root => default_acls(),
7d1739ad
FG
468 users => { 'root@pam' => { enable => 1 } },
469 roles => default_roles(),
470 },
471 raw => "",
472 expected_raw => "\n\n\n\n",
473 },
474 {
475 name => "default_config",
476 config => {
170cf17b 477 acl_root => default_acls(),
7d1739ad
FG
478 users => default_users(),
479 roles => default_roles(),
480 },
481 raw => $default_raw->{users}->{'root@pam'}."\n\n\n\n\n",
482 },
483 {
484 name => "group_empty",
485 config => {
170cf17b 486 acl_root => default_acls(),
7d1739ad
FG
487 users => default_users(),
488 roles => default_roles(),
489 groups => default_groups_with([$default_cfg->{'test_group_empty'}]),
490 },
491 raw => "".
492 $default_raw->{users}->{'root@pam'}."\n\n".
493 $default_raw->{groups}->{'test_group_empty'}."\n\n".
494 "\n\n",
495 },
496 {
497 name => "group_inexisting_member",
498 config => {
170cf17b 499 acl_root => default_acls(),
7d1739ad
FG
500 users => default_users(),
501 roles => default_roles(),
502 groups => default_groups_with([$default_cfg->{'test_group_empty'}]),
503 },
504 raw => "".
505 $default_raw->{users}->{'root@pam'}."\n\n".
506 "group:testgroup:does_not_exist::".
507 "\n\n\n\n",
508 expected_raw => "".
509 $default_raw->{users}->{'root@pam'}."\n\n".
510 $default_raw->{groups}->{'test_group_empty'}."\n\n".
511 "\n\n",
512 },
513 {
514 name => "group_invalid_member",
515 expected_config => {
170cf17b 516 acl_root => default_acls(),
7d1739ad
FG
517 users => default_users(),
518 roles => default_roles(),
519 },
520 raw => "".
521 $default_raw->{users}->{'root@pam'}."\n\n".
522 'group:inval!d:root@pam:'.
523 "\n\n",
524 },
525 {
526 name => "group_with_one_member",
527 config => {
170cf17b 528 acl_root => default_acls(),
7d1739ad
FG
529 users => default_users_with([$default_cfg->{test_pam_with_group}]),
530 roles => default_roles(),
531 groups => default_groups_with([$default_cfg->{'test_group_single_member'}]),
532 },
533 raw => "".
534 $default_raw->{users}->{'root@pam'}."\n".
535 $default_raw->{users}->{'test_pam'}."\n\n".
536 $default_raw->{groups}->{'test_group_single_member'}."\n\n".
537 "\n\n",
538 },
539 {
540 name => "group_with_members",
541 config => {
170cf17b 542 acl_root => default_acls(),
7d1739ad
FG
543 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{test2_pam_with_group}]),
544 roles => default_roles(),
545 groups => default_groups_with([$default_cfg->{'test_group_members'}]),
546 },
547 raw => "".
548 $default_raw->{users}->{'root@pam'}."\n".
549 $default_raw->{users}->{'test2_pam'}."\n".
550 $default_raw->{users}->{'test_pam'}."\n\n".
551 $default_raw->{groups}->{'test_group_members'}."\n\n".
552 "\n\n",
553 },
891f7afa
FG
554 {
555 name => "token_simple",
556 config => {
170cf17b 557 acl_root => default_acls(),
891f7afa
FG
558 users => default_users_with([$default_cfg->{test_pam_with_token}]),
559 roles => default_roles(),
560 },
561 raw => "".
562 $default_raw->{users}->{'root@pam'}."\n".
563 $default_raw->{users}->{'test_pam'}."\n".
564 $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n",
565 },
566 {
567 name => "token_multi",
568 config => {
170cf17b 569 acl_root => default_acls(),
891f7afa
FG
570 users => default_users_with([$default_cfg->{test_pam_with_token}, $default_cfg->{test_pam2_with_token}]),
571 roles => default_roles(),
572 },
573 raw => "".
574 $default_raw->{users}->{'root@pam'}."\n".
575 $default_raw->{users}->{'test2_pam'}."\n".
576 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
577 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
578 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
579 $default_raw->{users}->{'test_pam'}."\n".
580 $default_raw->{tokens}->{'test_token_simple'}."\n".
581 "\n\n\n\n",
582 },
7d1739ad
FG
583 {
584 name => "custom_role_with_single_priv",
585 config => {
170cf17b 586 acl_root => default_acls(),
7d1739ad
FG
587 users => default_users(),
588 roles => default_roles_with([$default_cfg->{test_role_single_priv}]),
589 },
590 raw => "".
591 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
592 $default_raw->{roles}->{'test_role_single_priv'}."\n\n",
593 },
594 {
595 name => "custom_role_with_privs",
596 config => {
170cf17b 597 acl_root => default_acls(),
7d1739ad
FG
598 users => default_users(),
599 roles => default_roles_with([$default_cfg->{test_role_privs}]),
600 },
601 raw => "".
602 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
603 $default_raw->{roles}->{'test_role_privs'}."\n\n",
604 },
605 {
606 name => "custom_role_with_duplicate_privs",
607 config => {
170cf17b 608 acl_root => default_acls(),
7d1739ad
FG
609 users => default_users(),
610 roles => default_roles_with([$default_cfg->{test_role_privs}]),
611 },
612 raw => "".
613 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
614 $default_raw->{roles}->{'test_role_privs_duplicate'}."\n\n",
615 expected_raw => "".
616 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
617 $default_raw->{roles}->{'test_role_privs'}."\n\n",
618 },
619 {
620 name => "custom_role_with_invalid_priv",
621 config => {
170cf17b 622 acl_root => default_acls(),
7d1739ad
FG
623 users => default_users(),
624 roles => default_roles_with([$default_cfg->{test_role_privs}]),
625 },
626 raw => "".
627 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
628 $default_raw->{roles}->{'test_role_privs_invalid'}."\n\n",
629 expected_raw => "".
630 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
631 $default_raw->{roles}->{'test_role_privs'}."\n\n",
632 },
633 {
634 name => "pool_empty",
635 config => {
170cf17b 636 acl_root => default_acls(),
7d1739ad
FG
637 users => default_users(),
638 roles => default_roles(),
639 pools => default_pools_with([$default_cfg->{test_pool_empty}]),
640 },
641 raw => "".
642 $default_raw->{users}->{'root@pam'}."\n\n\n".
643 $default_raw->{pools}->{'test_pool_empty'}."\n\n\n",
644 },
645 {
646 name => "pool_invalid",
647 config => {
170cf17b 648 acl_root => default_acls(),
7d1739ad
FG
649 users => default_users(),
650 roles => default_roles(),
651 pools => default_pools_with([$default_cfg->{test_pool_empty}]),
652 },
653 raw => "".
654 $default_raw->{users}->{'root@pam'}."\n\n\n".
655 $default_raw->{pools}->{'test_pool_invalid'}."\n\n\n",
656 expected_raw => "".
657 $default_raw->{users}->{'root@pam'}."\n\n\n".
658 $default_raw->{pools}->{'test_pool_empty'}."\n\n\n",
659 },
660 {
661 name => "pool_members",
662 config => {
170cf17b 663 acl_root => default_acls(),
7d1739ad
FG
664 users => default_users(),
665 roles => default_roles(),
666 pools => default_pools_with([$default_cfg->{test_pool_members}]),
667 vms => default_pool_vms_with([$default_cfg->{test_pool_members}]),
668 },
669 raw => "".
670 $default_raw->{users}->{'root@pam'}."\n\n\n".
671 $default_raw->{pools}->{'test_pool_members'}."\n\n\n",
672 },
673 {
674 name => "pool_duplicate_members",
675 config => {
170cf17b 676 acl_root => default_acls(),
7d1739ad
FG
677 users => default_users(),
678 roles => default_roles(),
679 pools => default_pools_with([$default_cfg->{test_pool_members}, $default_cfg->{test_pool_duplicate_vms}, $default_cfg->{test_pool_duplicate_storages}]),
680 vms => default_pool_vms_with([$default_cfg->{test_pool_members}]),
681 },
682 raw => "".
683 $default_raw->{users}->{'root@pam'}."\n\n\n".
684 $default_raw->{pools}->{'test_pool_members'}."\n".
685 $default_raw->{pools}->{'test_pool_duplicate_vms'}."\n".
686 $default_raw->{pools}->{'test_pool_duplicate_storages'}."\n",
687 expected_raw => "".
688 $default_raw->{users}->{'root@pam'}."\n\n\n".
689 $default_raw->{pools}->{'test_pool_duplicate_storages'}."\n".
690 $default_raw->{pools}->{'test_pool_duplicate_vms_expected'}."\n".
691 $default_raw->{pools}->{'test_pool_members'}."\n\n\n",
692 },
693 {
694 name => "acl_simple_user",
695 config => {
696 users => default_users_with([$default_cfg->{test_pam}]),
697 roles => default_roles(),
170cf17b 698 acl_root => default_acls_with([$default_cfg->{acl_simple_user}]),
7d1739ad
FG
699 },
700 raw => "".
701 $default_raw->{users}->{'root@pam'}."\n".
702 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
703 $default_raw->{acl}->{'acl_simple_user'}."\n",
704 },
705 {
706 name => "acl_complex_users",
707 config => {
708 users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{'test2_pam'}]),
709 roles => default_roles(),
170cf17b 710 acl_root => default_acls_with([$default_cfg->{acl_simple_user}, $default_cfg->{acl_complex_users}]),
7d1739ad
FG
711 },
712 raw => "".
713 $default_raw->{users}->{'root@pam'}."\n".
714 $default_raw->{users}->{'test2_pam'}."\n".
715 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
716 $default_raw->{acl}->{'acl_simple_user'}."\n".
717 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
718 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
719 },
720 {
721 name => "acl_complex_missing_user",
722 config => {
723 users => default_users_with([$default_cfg->{test2_pam}]),
724 roles => default_roles(),
170cf17b 725 acl_root => default_acls_with([$default_cfg->{acl_simple_user}, $default_cfg->{acl_complex_missing_user}]),
7d1739ad
FG
726 },
727 raw => "".
728 $default_raw->{users}->{'root@pam'}."\n".
729 $default_raw->{users}->{'test2_pam'}."\n\n\n\n\n".
730 $default_raw->{acl}->{'acl_simple_user'}."\n".
731 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
732 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
7d1739ad
FG
733 },
734 {
735 name => "acl_simple_group",
736 config => {
737 users => default_users_with([$default_cfg->{test_pam_with_group}]),
738 groups => default_groups_with([$default_cfg->{'test_group_single_member'}]),
739 roles => default_roles(),
170cf17b 740 acl_root => default_acls_with([$default_cfg->{acl_simple_group}]),
7d1739ad
FG
741 },
742 raw => "".
743 $default_raw->{users}->{'root@pam'}."\n".
744 $default_raw->{users}->{'test_pam'}."\n\n".
745 $default_raw->{groups}->{'test_group_single_member'}."\n\n\n\n".
746 $default_raw->{acl}->{'acl_simple_group'}."\n",
747 },
748 {
749 name => "acl_complex_groups",
750 config => {
751 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]),
752 groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]),
753 roles => default_roles(),
170cf17b 754 acl_root => default_acls_with([$default_cfg->{acl_simple_group}, $default_cfg->{acl_complex_groups}]),
7d1739ad
FG
755 },
756 raw => "".
757 $default_raw->{users}->{'root@pam'}."\n".
758 $default_raw->{users}->{'test2_pam'}."\n".
759 $default_raw->{users}->{'test3_pam'}."\n".
760 $default_raw->{users}->{'test_pam'}."\n\n".
761 $default_raw->{groups}->{'test_group_second'}."\n".
762 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
763 $default_raw->{acl}->{'acl_simple_group'}."\n".
764 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
765 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
766 },
767 {
768 name => "acl_complex_missing_group",
769 config => {
770 users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{'test2_pam'}, $default_cfg->{'test3_pam'}]),
771 groups => default_groups_with([$default_cfg->{'test_group_second'}]),
772 roles => default_roles(),
170cf17b 773 acl_root => default_acls_with([$default_cfg->{acl_simple_group}, $default_cfg->{acl_complex_missing_group}]),
7d1739ad
FG
774 },
775 raw => "".
776 $default_raw->{users}->{'root@pam'}."\n".
777 $default_raw->{users}->{'test2_pam'}."\n".
778 $default_raw->{users}->{'test3_pam'}."\n".
779 $default_raw->{users}->{'test_pam'}."\n\n".
780 $default_raw->{groups}->{'test_group_second'}."\n".
781 $default_raw->{acl}->{'acl_simple_group'}."\n".
782 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
783 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
784 expected_raw => "".
785 $default_raw->{users}->{'root@pam'}."\n".
786 $default_raw->{users}->{'test2_pam'}."\n".
787 $default_raw->{users}->{'test3_pam'}."\n".
788 $default_raw->{users}->{'test_pam'}."\n\n".
789 $default_raw->{groups}->{'test_group_second'}."\n\n\n\n".
5654260e
DC
790 $default_raw->{acl}->{'acl_simple_group'}."\n".
791 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
7d1739ad
FG
792 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
793 },
891f7afa
FG
794 {
795 name => "acl_simple_token",
796 config => {
797 users => default_users_with([$default_cfg->{test_pam_with_token}]),
798 roles => default_roles(),
170cf17b 799 acl_root => default_acls_with([$default_cfg->{acl_simple_token}]),
891f7afa
FG
800 },
801 raw => "".
802 $default_raw->{users}->{'root@pam'}."\n".
803 $default_raw->{users}->{'test_pam'}."\n".
804 $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n".
805 $default_raw->{acl}->{'acl_simple_token'}."\n",
806 },
807 {
808 name => "acl_complex_tokens",
809 config => {
810 users => default_users_with([$default_cfg->{test_pam_with_token}, $default_cfg->{'test_pam2_with_token'}]),
811 roles => default_roles(),
170cf17b 812 acl_root => default_acls_with([$default_cfg->{acl_simple_token}, $default_cfg->{acl_complex_tokens}]),
891f7afa
FG
813 },
814 raw => "".
815 $default_raw->{users}->{'root@pam'}."\n".
816 $default_raw->{users}->{'test2_pam'}."\n".
817 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
818 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
819 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
820 $default_raw->{users}->{'test_pam'}."\n".
821 $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n".
822 $default_raw->{acl}->{'acl_simple_token'}."\n".
823 $default_raw->{acl}->{'acl_complex_tokens_1'}."\n".
824 $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
825 },
826 {
827 name => "acl_complex_missing_token",
828 config => {
829 users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{test_pam2_with_token}]),
830 roles => default_roles(),
170cf17b 831 acl_root => default_acls_with([$default_cfg->{acl_complex_missing_token}]),
891f7afa
FG
832 },
833 raw => "".
834 $default_raw->{users}->{'root@pam'}."\n".
835 $default_raw->{users}->{'test2_pam'}."\n".
836 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
837 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
838 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
839 $default_raw->{users}->{'test_pam'}."\n".
840 $default_raw->{acl}->{'acl_simple_token'}."\n".
841 $default_raw->{acl}->{'acl_complex_tokens_1'}."\n".
842 $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
843 expected_raw => "".
844 $default_raw->{users}->{'root@pam'}."\n".
845 $default_raw->{users}->{'test2_pam'}."\n".
846 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
847 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
848 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
849 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
850 $default_raw->{acl}->{'acl_complex_tokens_1_missing'}."\n".
851 $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
852 },
7d1739ad
FG
853 {
854 name => "acl_missing_role",
855 config => {
856 users => default_users_with([$default_cfg->{test_pam}]),
857 roles => default_roles(),
170cf17b 858 acl_root => default_acls_with([$default_cfg->{acl_simple_user}]),
7d1739ad
FG
859 },
860 raw => "".
861 $default_raw->{users}->{'root@pam'}."\n".
862 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
863 $default_raw->{acl}->{'acl_simple_user'}."\n".
864 $default_raw->{acl}->{'acl_missing_role'}."\n",
21f523a5
FG
865 expected_raw => "".
866 $default_raw->{users}->{'root@pam'}."\n".
867 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
868 $default_raw->{acl}->{'acl_simple_user'}."\n",
7d1739ad
FG
869 },
870 {
871 name => "acl_complex_mixed",
872 config => {
873 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]),
874 groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]),
875 roles => default_roles(),
170cf17b 876 acl_root => default_acls_with([
7d1739ad
FG
877 $default_cfg->{acl_complex_mixed_root},
878 $default_cfg->{acl_complex_mixed_storage},
879 ]),
880 },
881 raw => "".
882 $default_raw->{users}->{'root@pam'}."\n".
883 $default_raw->{users}->{'test2_pam'}."\n".
884 $default_raw->{users}->{'test3_pam'}."\n".
885 $default_raw->{users}->{'test_pam'}."\n\n".
886 $default_raw->{groups}->{'test_group_second'}."\n".
887 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
888 $default_raw->{acl}->{'acl_simple_group'}."\n".
889 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
890 $default_raw->{acl}->{'acl_complex_groups_2'}."\n".
891 $default_raw->{acl}->{'acl_simple_user'}."\n".
892 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
893 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
894 expected_raw => "".
895 $default_raw->{users}->{'root@pam'}."\n".
896 $default_raw->{users}->{'test2_pam'}."\n".
897 $default_raw->{users}->{'test3_pam'}."\n".
898 $default_raw->{users}->{'test_pam'}."\n\n".
899 $default_raw->{groups}->{'test_group_second'}."\n".
900 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
901 $default_raw->{acl}->{'acl_complex_mixed_1'}."\n".
902 $default_raw->{acl}->{'acl_complex_mixed_2'}."\n".
903 $default_raw->{acl}->{'acl_complex_mixed_3'}."\n",
904 },
905 {
906 name => "acl_complex_mixed_prop_noprop_no_merge_sort_by_path",
907 config => {
908 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]),
909 groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]),
910 roles => default_roles(),
170cf17b 911 acl_root => default_acls_with([
7d1739ad
FG
912 $default_cfg->{acl_complex_mixed_root_noprop},
913 $default_cfg->{acl_complex_mixed_storage_noprop},
914 ]),
915 },
916 raw => "".
917 $default_raw->{users}->{'root@pam'}."\n".
918 $default_raw->{users}->{'test2_pam'}."\n".
919 $default_raw->{users}->{'test3_pam'}."\n".
920 $default_raw->{users}->{'test_pam'}."\n\n".
921 $default_raw->{groups}->{'test_group_second'}."\n".
922 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
923 $default_raw->{acl}->{'acl_simple_group_noprop'}."\n".
924 $default_raw->{acl}->{'acl_simple_user'}."\n".
925 $default_raw->{acl}->{'acl_complex_groups_1_noprop'}."\n".
926 $default_raw->{acl}->{'acl_complex_groups_2_noprop'}."\n".
927 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
928 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
929 },
930 {
931 name => "sort_roles_and_privs",
932 raw => "".
933 $default_raw->{users}->{'root@pam'}."\n".
934 $default_raw->{roles}->{'test_role_single_priv'}."\n\n".
935 $default_raw->{roles}->{'test_role_privs_out_of_order'}."\n\n",
936 expected_raw => "".
937 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
938 $default_raw->{roles}->{'test_role_privs'}."\n".
939 $default_raw->{roles}->{'test_role_single_priv'}."\n\n",
940 },
941 {
942 name => "sort_users_and_group_members",
943 raw => "".
944 $default_raw->{users}->{'test2_pam'}."\n".
945 $default_raw->{users}->{'root@pam'}."\n".
946 $default_raw->{users}->{'test_pam'}."\n\n".
947 $default_raw->{groups}->{'test_group_members_out_of_order'}."\n\n".
948 "\n\n",
949 expected_raw => "".
950 $default_raw->{users}->{'root@pam'}."\n".
951 $default_raw->{users}->{'test2_pam'}."\n".
952 $default_raw->{users}->{'test_pam'}."\n\n".
953 $default_raw->{groups}->{'test_group_members'}."\n\n".
954 "\n\n",
955 },
956 {
957 name => "sort_user_groups_and_acls",
958 raw => "".
959 $default_raw->{users}->{'test2_pam'}."\n".
960 $default_raw->{users}->{'root@pam'}."\n".
961 $default_raw->{users}->{'test_pam'}."\n\n".
962 $default_raw->{users}->{'test3_pam'}."\n".
963 $default_raw->{groups}->{'test_group_members_out_of_order'}."\n\n\n\n".
964 $default_raw->{groups}->{'test_group_second'}."\n".
965 $default_raw->{acl}->{'acl_simple_user'}."\n".
966 $default_raw->{acl}->{'acl_simple_group'}."\n".
967 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
968 $default_raw->{acl}->{'acl_complex_users_2'}."\n".
969 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
970 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
971 expected_raw => "".
972 $default_raw->{users}->{'root@pam'}."\n".
973 $default_raw->{users}->{'test2_pam'}."\n".
974 $default_raw->{users}->{'test3_pam'}."\n".
975 $default_raw->{users}->{'test_pam'}."\n\n".
976 $default_raw->{groups}->{'test_group_second'}."\n".
977 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
978 $default_raw->{acl}->{'acl_complex_mixed_1'}."\n".
979 $default_raw->{acl}->{'acl_complex_mixed_2'}."\n".
980 $default_raw->{acl}->{'acl_complex_mixed_3'}."\n",
981 },
982 {
983 name => 'default_values',
984 config => {
985 users => {
986 'root@pam' => {
987 enable => 0,
988 expire => 0,
989 email => undef,
990 },
991 'test@pam' => {
992 enable => 0,
993 expire => 0,
994 email => undef,
891f7afa
FG
995 tokens => {
996 'test' => {
997 expire => 0,
998 privsep => 0,
999 },
1000 },
7d1739ad
FG
1001 },
1002 },
1003 roles => default_roles_with([{ id => 'testrole' }]),
1004 groups => default_groups_with([$default_cfg->{test_group_empty}]),
1005 pools => default_pools_with([$default_cfg->{test_pool_empty}]),
170cf17b 1006 acl_root => {},
7d1739ad
FG
1007 },
1008 raw => "".
1009 'user:root@pam'."\n".
891f7afa
FG
1010 'user:test@pam'."\n".
1011 'token:test@pam!test'."\n\n".
7d1739ad
FG
1012 'group:testgroup'."\n\n".
1013 'pool:testpool'."\n\n".
1014 'role:testrole'."\n\n".
1015 'acl::/:',
1016 expected_raw => "".
1017 'user:root@pam:0:0::::::'."\n".
891f7afa
FG
1018 'user:test@pam:0:0::::::'."\n".
1019 'token:test@pam!test:0:0::'."\n\n".
7d1739ad
FG
1020 'group:testgroup:::'."\n\n".
1021 'pool:testpool::::'."\n\n".
1022 'role:testrole::'."\n\n",
1023 },
1024];
1025
1026
1027my $number_of_tests_run = 0;
1028foreach my $t (@$tests) {
1029 my $expected_config = $t->{expected_config} // $t->{config};
1030 my $expected_raw = $t->{expected_raw} // $t->{raw};
1031 if (defined($t->{raw})) {
1032 my $parsed = PVE::AccessControl::parse_user_config($t->{name}, $t->{raw});
1033 if (defined($expected_config)) {
1034 is_deeply($parsed, $expected_config, "$t->{name}_parse");
1035 $number_of_tests_run++;
1036 }
1037 if (defined($t->{expected_raw}) && !defined($t->{config})) {
1038 is(PVE::AccessControl::write_user_config($t->{name}, $parsed), $t->{expected_raw}, "$t->{name}_rewrite");
1039 $number_of_tests_run++;
1040 }
1041
1042 }
1043 if (defined($t->{config})) {
1044 my $written = PVE::AccessControl::write_user_config($t->{name}, $t->{config});
1045 if (defined($expected_raw)) {
1046 is($written, $expected_raw, "$t->{name}_write");
1047 $number_of_tests_run++;
1048 }
1049 if (defined($t->{expected_config}) && !defined($t->{raw})) {
1050 is_deeply(PVE::AccessControl::parse_user_config($t->{name}, $t->{written}), $t->{expected_config}, "$t->{name}_reparse");
1051 $number_of_tests_run++;
1052 }
1053 }
1054};
1055
1056done_testing( $number_of_tests_run);