]> git.proxmox.com Git - pve-access-control.git/blame - src/test/parser_writer.pl
fix various perlcritic lints
[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 => {},
240 },
241 test_pool_members => {
242 'id' => 'testpool',
243 vms => { 123 => 1, 1234 => 1},
244 storage => { 'local' => 1, 'local-zfs' => 1},
245 },
246 test_pool_duplicate_vms => {
247 'id' => 'test_duplicate_vms',
248 vms => {},
249 storage => {},
250 },
251 test_pool_duplicate_storages => {
252 'id' => 'test_duplicate_storages',
253 vms => {},
254 storage => { 'local' => 1, 'local-zfs' => 1},
255 },
256 acl_simple_user => {
257 'path' => '/',
258 users => {
259 'test@pam' => {
260 'PVEVMAdmin' => 1,
261 },
262 },
263 },
264 acl_complex_users => {
265 'path' => '/storage',
266 users => {
267 'test2@pam' => {
268 'PVEDatastoreUser' => 1,
269 },
270 'test@pam' => {
271 'PVEDatastoreAdmin' => 1,
272 },
273 },
274 },
275 acl_complex_missing_user => {
276 'path' => '/storage',
277 users => {
278 'test2@pam' => {
279 'PVEDatastoreUser' => 1,
280 },
5654260e
DC
281 'test@pam' => {
282 'PVEDatastoreAdmin' => 1,
283 },
7d1739ad
FG
284 },
285 },
891f7afa
FG
286 acl_simple_token => {
287 'path' => '/',
288 tokens => {
289 'test@pam!full' => {
290 'PVEVMAdmin' => 1,
291 },
292 },
293 },
294 acl_complex_tokens => {
295 'path' => '/storage',
296 tokens => {
297 'test2@pam!privsep' => {
298 'PVEDatastoreUser' => 1,
299 },
300 'test2@pam!expired' => {
301 'PVEDatastoreAdmin' => 1,
302 },
303 'test@pam!full' => {
304 'PVEDatastoreAdmin' => 1,
305 },
306 },
307 },
308 acl_complex_missing_token => {
309 'path' => '/storage',
310 tokens => {
311 'test2@pam!expired' => {
312 'PVEDatastoreAdmin' => 1,
313 },
314 'test2@pam!privsep' => {
315 'PVEDatastoreUser' => 1,
316 },
317 },
318 },
7d1739ad
FG
319 acl_simple_group => {
320 'path' => '/',
321 groups => {
322 'testgroup' => {
323 'PVEVMAdmin' => 1,
324 },
325 },
326 },
327 acl_complex_groups => {
328 'path' => '/storage',
329 groups => {
330 'testgroup' => {
331 'PVEDatastoreAdmin' => 1,
332 },
333 'another' => {
334 'PVEDatastoreUser' => 1,
335 },
336 },
337 },
338 acl_simple_group_noprop => {
339 'path' => '/',
340 groups => {
341 'testgroup' => {
342 'PVEVMAdmin' => 0,
343 },
344 },
345 },
346 acl_complex_groups_noprop => {
347 'path' => '/storage',
348 groups => {
349 'testgroup' => {
350 'PVEDatastoreAdmin' => 0,
351 },
352 'another' => {
353 'PVEDatastoreUser' => 0,
354 },
355 },
356 },
357 acl_complex_missing_group => {
358 'path' => '/storage',
359 groups => {
5654260e
DC
360 'testgroup' => {
361 'PVEDatastoreAdmin' => 1,
362 },
7d1739ad
FG
363 'another' => {
364 'PVEDatastoreUser' => 1,
365 },
366 },
367 },
368 acl_missing_role => {
369 'path' => '/storage',
370 users => {
371 'test@pam' => {
372 'MissingRole' => 1,
373 },
374 },
375 },
376};
377
378$default_cfg->{'acl_complex_mixed_root'} = {
379 'path' => '/',
380 users => $default_cfg->{'acl_simple_user'}->{users},
381 groups => $default_cfg->{'acl_simple_group'}->{groups},
382};
383
384$default_cfg->{'acl_complex_mixed_storage'} = {
385 'path' => '/storage',
386 users => $default_cfg->{'acl_complex_users'}->{users},
387 groups => $default_cfg->{'acl_complex_groups'}->{groups},
388};
389
390$default_cfg->{'acl_complex_mixed_root_noprop'} = {
391 'path' => '/',
392 users => $default_cfg->{'acl_simple_user'}->{users},
393 groups => $default_cfg->{'acl_simple_group_noprop'}->{groups},
394};
395
396$default_cfg->{'acl_complex_mixed_storage_noprop'} = {
397 'path' => '/storage',
398 users => $default_cfg->{'acl_complex_users'}->{users},
399 groups => $default_cfg->{'acl_complex_groups_noprop'}->{groups},
400};
401
402my $default_raw = {
403 users => {
404 'root@pam' => 'user:root@pam:1:0::::::',
405 'test_pam' => 'user:test@pam:1:0::::::',
406 'test2_pam' => 'user:test2@pam:1:0::::::',
407 'test3_pam' => 'user:test3@pam:1:0::::::',
408 },
409 groups => {
410 'test_group_empty' => 'group:testgroup:::',
411 'test_group_single_member' => 'group:testgroup:test@pam::',
412 'test_group_members' => 'group:testgroup:test2@pam,test@pam::',
413 'test_group_members_out_of_order' => 'group:testgroup:test@pam,test2@pam::',
414 'test_group_second' => 'group:another:test3@pam::',
415 },
891f7afa
FG
416 tokens => {
417 'test_token_simple' => 'token:test@pam!full:0:0::',
418 'test_token_multi_full' => 'token:test2@pam!full:0:0::',
419 'test_token_multi_privsep' => 'token:test2@pam!privsep:0:1::',
420 'test_token_multi_expired' => 'token:test2@pam!expired:1:0::',
421 },
7d1739ad
FG
422 roles => {
423 'test_role_single_priv' => 'role:testrolesingle:VM.Allocate:',
424 'test_role_privs' => 'role:testrole:Datastore.Audit,VM.Allocate:',
425 'test_role_privs_out_of_order' => 'role:testrole:VM.Allocate,Datastore.Audit:',
426 'test_role_privs_duplicate' => 'role:testrole:VM.Allocate,Datastore.Audit,VM.Allocate:',
427 'test_role_privs_invalid' => 'role:testrole:VM.Invalid,Datastore.Audit,VM.Allocate:',
428 },
429 pools => {
430 'test_pool_empty' => 'pool:testpool::::',
431 'test_pool_invalid' => 'pool:testpool::non-numeric:inval!d:',
432 'test_pool_members' => 'pool:testpool::123,1234:local,local-zfs:',
433 'test_pool_duplicate_vms' => 'pool:test_duplicate_vms::123,1234::',
434 'test_pool_duplicate_vms_expected' => 'pool:test_duplicate_vms::::',
435 'test_pool_duplicate_storages' => 'pool:test_duplicate_storages:::local,local-zfs:',
436 },
437 acl => {
438 'acl_simple_user' => 'acl:1:/:test@pam:PVEVMAdmin:',
439 'acl_complex_users_1' => 'acl:1:/storage:test@pam:PVEDatastoreAdmin:',
440 'acl_complex_users_2' => 'acl:1:/storage:test2@pam:PVEDatastoreUser:',
891f7afa
FG
441 'acl_simple_token' => 'acl:1:/:test@pam!full:PVEVMAdmin:',
442 'acl_complex_tokens_1' => 'acl:1:/storage:test2@pam!expired,test@pam!full:PVEDatastoreAdmin:',
443 'acl_complex_tokens_2' => 'acl:1:/storage:test2@pam!privsep:PVEDatastoreUser:',
444 'acl_complex_tokens_1_missing' => 'acl:1:/storage:test2@pam!expired:PVEDatastoreAdmin:',
7d1739ad
FG
445 'acl_simple_group' => 'acl:1:/:@testgroup:PVEVMAdmin:',
446 'acl_complex_groups_1' => 'acl:1:/storage:@testgroup:PVEDatastoreAdmin:',
447 'acl_complex_groups_2' => 'acl:1:/storage:@another:PVEDatastoreUser:',
448 'acl_simple_group_noprop' => 'acl:0:/:@testgroup:PVEVMAdmin:',
449 'acl_complex_groups_1_noprop' => 'acl:0:/storage:@testgroup:PVEDatastoreAdmin:',
450 'acl_complex_groups_2_noprop' => 'acl:0:/storage:@another:PVEDatastoreUser:',
451 'acl_complex_mixed_1' => 'acl:1:/:@testgroup,test@pam:PVEVMAdmin:',
452 'acl_complex_mixed_2' => 'acl:1:/storage:@testgroup,test@pam:PVEDatastoreAdmin:',
453 'acl_complex_mixed_3' => 'acl:1:/storage:@another,test2@pam:PVEDatastoreUser:',
454 'acl_missing_role' => 'acl:1:/storage:test@pam:MissingRole:',
455 },
456};
457
458my $tests = [
459 {
460 name => "empty_config",
461 config => {},
462 expected_config => {
170cf17b 463 acl_root => default_acls(),
7d1739ad
FG
464 users => { 'root@pam' => { enable => 1 } },
465 roles => default_roles(),
466 },
467 raw => "",
468 expected_raw => "\n\n\n\n",
469 },
470 {
471 name => "default_config",
472 config => {
170cf17b 473 acl_root => default_acls(),
7d1739ad
FG
474 users => default_users(),
475 roles => default_roles(),
476 },
477 raw => $default_raw->{users}->{'root@pam'}."\n\n\n\n\n",
478 },
479 {
480 name => "group_empty",
481 config => {
170cf17b 482 acl_root => default_acls(),
7d1739ad
FG
483 users => default_users(),
484 roles => default_roles(),
485 groups => default_groups_with([$default_cfg->{'test_group_empty'}]),
486 },
487 raw => "".
488 $default_raw->{users}->{'root@pam'}."\n\n".
489 $default_raw->{groups}->{'test_group_empty'}."\n\n".
490 "\n\n",
491 },
492 {
493 name => "group_inexisting_member",
494 config => {
170cf17b 495 acl_root => default_acls(),
7d1739ad
FG
496 users => default_users(),
497 roles => default_roles(),
498 groups => default_groups_with([$default_cfg->{'test_group_empty'}]),
499 },
500 raw => "".
501 $default_raw->{users}->{'root@pam'}."\n\n".
502 "group:testgroup:does_not_exist::".
503 "\n\n\n\n",
504 expected_raw => "".
505 $default_raw->{users}->{'root@pam'}."\n\n".
506 $default_raw->{groups}->{'test_group_empty'}."\n\n".
507 "\n\n",
508 },
509 {
510 name => "group_invalid_member",
511 expected_config => {
170cf17b 512 acl_root => default_acls(),
7d1739ad
FG
513 users => default_users(),
514 roles => default_roles(),
515 },
516 raw => "".
517 $default_raw->{users}->{'root@pam'}."\n\n".
518 'group:inval!d:root@pam:'.
519 "\n\n",
520 },
521 {
522 name => "group_with_one_member",
523 config => {
170cf17b 524 acl_root => default_acls(),
7d1739ad
FG
525 users => default_users_with([$default_cfg->{test_pam_with_group}]),
526 roles => default_roles(),
527 groups => default_groups_with([$default_cfg->{'test_group_single_member'}]),
528 },
529 raw => "".
530 $default_raw->{users}->{'root@pam'}."\n".
531 $default_raw->{users}->{'test_pam'}."\n\n".
532 $default_raw->{groups}->{'test_group_single_member'}."\n\n".
533 "\n\n",
534 },
535 {
536 name => "group_with_members",
537 config => {
170cf17b 538 acl_root => default_acls(),
7d1739ad
FG
539 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{test2_pam_with_group}]),
540 roles => default_roles(),
541 groups => default_groups_with([$default_cfg->{'test_group_members'}]),
542 },
543 raw => "".
544 $default_raw->{users}->{'root@pam'}."\n".
545 $default_raw->{users}->{'test2_pam'}."\n".
546 $default_raw->{users}->{'test_pam'}."\n\n".
547 $default_raw->{groups}->{'test_group_members'}."\n\n".
548 "\n\n",
549 },
891f7afa
FG
550 {
551 name => "token_simple",
552 config => {
170cf17b 553 acl_root => default_acls(),
891f7afa
FG
554 users => default_users_with([$default_cfg->{test_pam_with_token}]),
555 roles => default_roles(),
556 },
557 raw => "".
558 $default_raw->{users}->{'root@pam'}."\n".
559 $default_raw->{users}->{'test_pam'}."\n".
560 $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n",
561 },
562 {
563 name => "token_multi",
564 config => {
170cf17b 565 acl_root => default_acls(),
891f7afa
FG
566 users => default_users_with([$default_cfg->{test_pam_with_token}, $default_cfg->{test_pam2_with_token}]),
567 roles => default_roles(),
568 },
569 raw => "".
570 $default_raw->{users}->{'root@pam'}."\n".
571 $default_raw->{users}->{'test2_pam'}."\n".
572 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
573 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
574 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
575 $default_raw->{users}->{'test_pam'}."\n".
576 $default_raw->{tokens}->{'test_token_simple'}."\n".
577 "\n\n\n\n",
578 },
7d1739ad
FG
579 {
580 name => "custom_role_with_single_priv",
581 config => {
170cf17b 582 acl_root => default_acls(),
7d1739ad
FG
583 users => default_users(),
584 roles => default_roles_with([$default_cfg->{test_role_single_priv}]),
585 },
586 raw => "".
587 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
588 $default_raw->{roles}->{'test_role_single_priv'}."\n\n",
589 },
590 {
591 name => "custom_role_with_privs",
592 config => {
170cf17b 593 acl_root => default_acls(),
7d1739ad
FG
594 users => default_users(),
595 roles => default_roles_with([$default_cfg->{test_role_privs}]),
596 },
597 raw => "".
598 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
599 $default_raw->{roles}->{'test_role_privs'}."\n\n",
600 },
601 {
602 name => "custom_role_with_duplicate_privs",
603 config => {
170cf17b 604 acl_root => default_acls(),
7d1739ad
FG
605 users => default_users(),
606 roles => default_roles_with([$default_cfg->{test_role_privs}]),
607 },
608 raw => "".
609 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
610 $default_raw->{roles}->{'test_role_privs_duplicate'}."\n\n",
611 expected_raw => "".
612 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
613 $default_raw->{roles}->{'test_role_privs'}."\n\n",
614 },
615 {
616 name => "custom_role_with_invalid_priv",
617 config => {
170cf17b 618 acl_root => default_acls(),
7d1739ad
FG
619 users => default_users(),
620 roles => default_roles_with([$default_cfg->{test_role_privs}]),
621 },
622 raw => "".
623 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
624 $default_raw->{roles}->{'test_role_privs_invalid'}."\n\n",
625 expected_raw => "".
626 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
627 $default_raw->{roles}->{'test_role_privs'}."\n\n",
628 },
629 {
630 name => "pool_empty",
631 config => {
170cf17b 632 acl_root => default_acls(),
7d1739ad
FG
633 users => default_users(),
634 roles => default_roles(),
635 pools => default_pools_with([$default_cfg->{test_pool_empty}]),
636 },
637 raw => "".
638 $default_raw->{users}->{'root@pam'}."\n\n\n".
639 $default_raw->{pools}->{'test_pool_empty'}."\n\n\n",
640 },
641 {
642 name => "pool_invalid",
643 config => {
170cf17b 644 acl_root => default_acls(),
7d1739ad
FG
645 users => default_users(),
646 roles => default_roles(),
647 pools => default_pools_with([$default_cfg->{test_pool_empty}]),
648 },
649 raw => "".
650 $default_raw->{users}->{'root@pam'}."\n\n\n".
651 $default_raw->{pools}->{'test_pool_invalid'}."\n\n\n",
652 expected_raw => "".
653 $default_raw->{users}->{'root@pam'}."\n\n\n".
654 $default_raw->{pools}->{'test_pool_empty'}."\n\n\n",
655 },
656 {
657 name => "pool_members",
658 config => {
170cf17b 659 acl_root => default_acls(),
7d1739ad
FG
660 users => default_users(),
661 roles => default_roles(),
662 pools => default_pools_with([$default_cfg->{test_pool_members}]),
663 vms => default_pool_vms_with([$default_cfg->{test_pool_members}]),
664 },
665 raw => "".
666 $default_raw->{users}->{'root@pam'}."\n\n\n".
667 $default_raw->{pools}->{'test_pool_members'}."\n\n\n",
668 },
669 {
670 name => "pool_duplicate_members",
671 config => {
170cf17b 672 acl_root => default_acls(),
7d1739ad
FG
673 users => default_users(),
674 roles => default_roles(),
675 pools => default_pools_with([$default_cfg->{test_pool_members}, $default_cfg->{test_pool_duplicate_vms}, $default_cfg->{test_pool_duplicate_storages}]),
676 vms => default_pool_vms_with([$default_cfg->{test_pool_members}]),
677 },
678 raw => "".
679 $default_raw->{users}->{'root@pam'}."\n\n\n".
680 $default_raw->{pools}->{'test_pool_members'}."\n".
681 $default_raw->{pools}->{'test_pool_duplicate_vms'}."\n".
682 $default_raw->{pools}->{'test_pool_duplicate_storages'}."\n",
683 expected_raw => "".
684 $default_raw->{users}->{'root@pam'}."\n\n\n".
685 $default_raw->{pools}->{'test_pool_duplicate_storages'}."\n".
686 $default_raw->{pools}->{'test_pool_duplicate_vms_expected'}."\n".
687 $default_raw->{pools}->{'test_pool_members'}."\n\n\n",
688 },
689 {
690 name => "acl_simple_user",
691 config => {
692 users => default_users_with([$default_cfg->{test_pam}]),
693 roles => default_roles(),
170cf17b 694 acl_root => default_acls_with([$default_cfg->{acl_simple_user}]),
7d1739ad
FG
695 },
696 raw => "".
697 $default_raw->{users}->{'root@pam'}."\n".
698 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
699 $default_raw->{acl}->{'acl_simple_user'}."\n",
700 },
701 {
702 name => "acl_complex_users",
703 config => {
704 users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{'test2_pam'}]),
705 roles => default_roles(),
170cf17b 706 acl_root => default_acls_with([$default_cfg->{acl_simple_user}, $default_cfg->{acl_complex_users}]),
7d1739ad
FG
707 },
708 raw => "".
709 $default_raw->{users}->{'root@pam'}."\n".
710 $default_raw->{users}->{'test2_pam'}."\n".
711 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
712 $default_raw->{acl}->{'acl_simple_user'}."\n".
713 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
714 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
715 },
716 {
717 name => "acl_complex_missing_user",
718 config => {
719 users => default_users_with([$default_cfg->{test2_pam}]),
720 roles => default_roles(),
170cf17b 721 acl_root => default_acls_with([$default_cfg->{acl_simple_user}, $default_cfg->{acl_complex_missing_user}]),
7d1739ad
FG
722 },
723 raw => "".
724 $default_raw->{users}->{'root@pam'}."\n".
725 $default_raw->{users}->{'test2_pam'}."\n\n\n\n\n".
726 $default_raw->{acl}->{'acl_simple_user'}."\n".
727 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
728 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
7d1739ad
FG
729 },
730 {
731 name => "acl_simple_group",
732 config => {
733 users => default_users_with([$default_cfg->{test_pam_with_group}]),
734 groups => default_groups_with([$default_cfg->{'test_group_single_member'}]),
735 roles => default_roles(),
170cf17b 736 acl_root => default_acls_with([$default_cfg->{acl_simple_group}]),
7d1739ad
FG
737 },
738 raw => "".
739 $default_raw->{users}->{'root@pam'}."\n".
740 $default_raw->{users}->{'test_pam'}."\n\n".
741 $default_raw->{groups}->{'test_group_single_member'}."\n\n\n\n".
742 $default_raw->{acl}->{'acl_simple_group'}."\n",
743 },
744 {
745 name => "acl_complex_groups",
746 config => {
747 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]),
748 groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]),
749 roles => default_roles(),
170cf17b 750 acl_root => default_acls_with([$default_cfg->{acl_simple_group}, $default_cfg->{acl_complex_groups}]),
7d1739ad
FG
751 },
752 raw => "".
753 $default_raw->{users}->{'root@pam'}."\n".
754 $default_raw->{users}->{'test2_pam'}."\n".
755 $default_raw->{users}->{'test3_pam'}."\n".
756 $default_raw->{users}->{'test_pam'}."\n\n".
757 $default_raw->{groups}->{'test_group_second'}."\n".
758 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
759 $default_raw->{acl}->{'acl_simple_group'}."\n".
760 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
761 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
762 },
763 {
764 name => "acl_complex_missing_group",
765 config => {
766 users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{'test2_pam'}, $default_cfg->{'test3_pam'}]),
767 groups => default_groups_with([$default_cfg->{'test_group_second'}]),
768 roles => default_roles(),
170cf17b 769 acl_root => default_acls_with([$default_cfg->{acl_simple_group}, $default_cfg->{acl_complex_missing_group}]),
7d1739ad
FG
770 },
771 raw => "".
772 $default_raw->{users}->{'root@pam'}."\n".
773 $default_raw->{users}->{'test2_pam'}."\n".
774 $default_raw->{users}->{'test3_pam'}."\n".
775 $default_raw->{users}->{'test_pam'}."\n\n".
776 $default_raw->{groups}->{'test_group_second'}."\n".
777 $default_raw->{acl}->{'acl_simple_group'}."\n".
778 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
779 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
780 expected_raw => "".
781 $default_raw->{users}->{'root@pam'}."\n".
782 $default_raw->{users}->{'test2_pam'}."\n".
783 $default_raw->{users}->{'test3_pam'}."\n".
784 $default_raw->{users}->{'test_pam'}."\n\n".
785 $default_raw->{groups}->{'test_group_second'}."\n\n\n\n".
5654260e
DC
786 $default_raw->{acl}->{'acl_simple_group'}."\n".
787 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
7d1739ad
FG
788 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
789 },
891f7afa
FG
790 {
791 name => "acl_simple_token",
792 config => {
793 users => default_users_with([$default_cfg->{test_pam_with_token}]),
794 roles => default_roles(),
170cf17b 795 acl_root => default_acls_with([$default_cfg->{acl_simple_token}]),
891f7afa
FG
796 },
797 raw => "".
798 $default_raw->{users}->{'root@pam'}."\n".
799 $default_raw->{users}->{'test_pam'}."\n".
800 $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n".
801 $default_raw->{acl}->{'acl_simple_token'}."\n",
802 },
803 {
804 name => "acl_complex_tokens",
805 config => {
806 users => default_users_with([$default_cfg->{test_pam_with_token}, $default_cfg->{'test_pam2_with_token'}]),
807 roles => default_roles(),
170cf17b 808 acl_root => default_acls_with([$default_cfg->{acl_simple_token}, $default_cfg->{acl_complex_tokens}]),
891f7afa
FG
809 },
810 raw => "".
811 $default_raw->{users}->{'root@pam'}."\n".
812 $default_raw->{users}->{'test2_pam'}."\n".
813 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
814 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
815 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
816 $default_raw->{users}->{'test_pam'}."\n".
817 $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n".
818 $default_raw->{acl}->{'acl_simple_token'}."\n".
819 $default_raw->{acl}->{'acl_complex_tokens_1'}."\n".
820 $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
821 },
822 {
823 name => "acl_complex_missing_token",
824 config => {
825 users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{test_pam2_with_token}]),
826 roles => default_roles(),
170cf17b 827 acl_root => default_acls_with([$default_cfg->{acl_complex_missing_token}]),
891f7afa
FG
828 },
829 raw => "".
830 $default_raw->{users}->{'root@pam'}."\n".
831 $default_raw->{users}->{'test2_pam'}."\n".
832 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
833 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
834 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
835 $default_raw->{users}->{'test_pam'}."\n".
836 $default_raw->{acl}->{'acl_simple_token'}."\n".
837 $default_raw->{acl}->{'acl_complex_tokens_1'}."\n".
838 $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
839 expected_raw => "".
840 $default_raw->{users}->{'root@pam'}."\n".
841 $default_raw->{users}->{'test2_pam'}."\n".
842 $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
843 $default_raw->{tokens}->{'test_token_multi_full'}."\n".
844 $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
845 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
846 $default_raw->{acl}->{'acl_complex_tokens_1_missing'}."\n".
847 $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
848 },
7d1739ad
FG
849 {
850 name => "acl_missing_role",
851 config => {
852 users => default_users_with([$default_cfg->{test_pam}]),
853 roles => default_roles(),
170cf17b 854 acl_root => default_acls_with([$default_cfg->{acl_simple_user}]),
7d1739ad
FG
855 },
856 raw => "".
857 $default_raw->{users}->{'root@pam'}."\n".
858 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
859 $default_raw->{acl}->{'acl_simple_user'}."\n".
860 $default_raw->{acl}->{'acl_missing_role'}."\n",
21f523a5
FG
861 expected_raw => "".
862 $default_raw->{users}->{'root@pam'}."\n".
863 $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
864 $default_raw->{acl}->{'acl_simple_user'}."\n",
7d1739ad
FG
865 },
866 {
867 name => "acl_complex_mixed",
868 config => {
869 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]),
870 groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]),
871 roles => default_roles(),
170cf17b 872 acl_root => default_acls_with([
7d1739ad
FG
873 $default_cfg->{acl_complex_mixed_root},
874 $default_cfg->{acl_complex_mixed_storage},
875 ]),
876 },
877 raw => "".
878 $default_raw->{users}->{'root@pam'}."\n".
879 $default_raw->{users}->{'test2_pam'}."\n".
880 $default_raw->{users}->{'test3_pam'}."\n".
881 $default_raw->{users}->{'test_pam'}."\n\n".
882 $default_raw->{groups}->{'test_group_second'}."\n".
883 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
884 $default_raw->{acl}->{'acl_simple_group'}."\n".
885 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
886 $default_raw->{acl}->{'acl_complex_groups_2'}."\n".
887 $default_raw->{acl}->{'acl_simple_user'}."\n".
888 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
889 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
890 expected_raw => "".
891 $default_raw->{users}->{'root@pam'}."\n".
892 $default_raw->{users}->{'test2_pam'}."\n".
893 $default_raw->{users}->{'test3_pam'}."\n".
894 $default_raw->{users}->{'test_pam'}."\n\n".
895 $default_raw->{groups}->{'test_group_second'}."\n".
896 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
897 $default_raw->{acl}->{'acl_complex_mixed_1'}."\n".
898 $default_raw->{acl}->{'acl_complex_mixed_2'}."\n".
899 $default_raw->{acl}->{'acl_complex_mixed_3'}."\n",
900 },
901 {
902 name => "acl_complex_mixed_prop_noprop_no_merge_sort_by_path",
903 config => {
904 users => default_users_with([$default_cfg->{test_pam_with_group}, $default_cfg->{'test2_pam_with_group'}, $default_cfg->{'test3_pam'}]),
905 groups => default_groups_with([$default_cfg->{'test_group_members'}, $default_cfg->{'test_group_second'}]),
906 roles => default_roles(),
170cf17b 907 acl_root => default_acls_with([
7d1739ad
FG
908 $default_cfg->{acl_complex_mixed_root_noprop},
909 $default_cfg->{acl_complex_mixed_storage_noprop},
910 ]),
911 },
912 raw => "".
913 $default_raw->{users}->{'root@pam'}."\n".
914 $default_raw->{users}->{'test2_pam'}."\n".
915 $default_raw->{users}->{'test3_pam'}."\n".
916 $default_raw->{users}->{'test_pam'}."\n\n".
917 $default_raw->{groups}->{'test_group_second'}."\n".
918 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
919 $default_raw->{acl}->{'acl_simple_group_noprop'}."\n".
920 $default_raw->{acl}->{'acl_simple_user'}."\n".
921 $default_raw->{acl}->{'acl_complex_groups_1_noprop'}."\n".
922 $default_raw->{acl}->{'acl_complex_groups_2_noprop'}."\n".
923 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
924 $default_raw->{acl}->{'acl_complex_users_2'}."\n",
925 },
926 {
927 name => "sort_roles_and_privs",
928 raw => "".
929 $default_raw->{users}->{'root@pam'}."\n".
930 $default_raw->{roles}->{'test_role_single_priv'}."\n\n".
931 $default_raw->{roles}->{'test_role_privs_out_of_order'}."\n\n",
932 expected_raw => "".
933 $default_raw->{users}->{'root@pam'}."\n\n\n\n".
934 $default_raw->{roles}->{'test_role_privs'}."\n".
935 $default_raw->{roles}->{'test_role_single_priv'}."\n\n",
936 },
937 {
938 name => "sort_users_and_group_members",
939 raw => "".
940 $default_raw->{users}->{'test2_pam'}."\n".
941 $default_raw->{users}->{'root@pam'}."\n".
942 $default_raw->{users}->{'test_pam'}."\n\n".
943 $default_raw->{groups}->{'test_group_members_out_of_order'}."\n\n".
944 "\n\n",
945 expected_raw => "".
946 $default_raw->{users}->{'root@pam'}."\n".
947 $default_raw->{users}->{'test2_pam'}."\n".
948 $default_raw->{users}->{'test_pam'}."\n\n".
949 $default_raw->{groups}->{'test_group_members'}."\n\n".
950 "\n\n",
951 },
952 {
953 name => "sort_user_groups_and_acls",
954 raw => "".
955 $default_raw->{users}->{'test2_pam'}."\n".
956 $default_raw->{users}->{'root@pam'}."\n".
957 $default_raw->{users}->{'test_pam'}."\n\n".
958 $default_raw->{users}->{'test3_pam'}."\n".
959 $default_raw->{groups}->{'test_group_members_out_of_order'}."\n\n\n\n".
960 $default_raw->{groups}->{'test_group_second'}."\n".
961 $default_raw->{acl}->{'acl_simple_user'}."\n".
962 $default_raw->{acl}->{'acl_simple_group'}."\n".
963 $default_raw->{acl}->{'acl_complex_users_1'}."\n".
964 $default_raw->{acl}->{'acl_complex_users_2'}."\n".
965 $default_raw->{acl}->{'acl_complex_groups_1'}."\n".
966 $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
967 expected_raw => "".
968 $default_raw->{users}->{'root@pam'}."\n".
969 $default_raw->{users}->{'test2_pam'}."\n".
970 $default_raw->{users}->{'test3_pam'}."\n".
971 $default_raw->{users}->{'test_pam'}."\n\n".
972 $default_raw->{groups}->{'test_group_second'}."\n".
973 $default_raw->{groups}->{'test_group_members'}."\n\n\n\n".
974 $default_raw->{acl}->{'acl_complex_mixed_1'}."\n".
975 $default_raw->{acl}->{'acl_complex_mixed_2'}."\n".
976 $default_raw->{acl}->{'acl_complex_mixed_3'}."\n",
977 },
978 {
979 name => 'default_values',
980 config => {
981 users => {
982 'root@pam' => {
983 enable => 0,
984 expire => 0,
985 email => undef,
986 },
987 'test@pam' => {
988 enable => 0,
989 expire => 0,
990 email => undef,
891f7afa
FG
991 tokens => {
992 'test' => {
993 expire => 0,
994 privsep => 0,
995 },
996 },
7d1739ad
FG
997 },
998 },
999 roles => default_roles_with([{ id => 'testrole' }]),
1000 groups => default_groups_with([$default_cfg->{test_group_empty}]),
1001 pools => default_pools_with([$default_cfg->{test_pool_empty}]),
170cf17b 1002 acl_root => {},
7d1739ad
FG
1003 },
1004 raw => "".
1005 'user:root@pam'."\n".
891f7afa
FG
1006 'user:test@pam'."\n".
1007 'token:test@pam!test'."\n\n".
7d1739ad
FG
1008 'group:testgroup'."\n\n".
1009 'pool:testpool'."\n\n".
1010 'role:testrole'."\n\n".
1011 'acl::/:',
1012 expected_raw => "".
1013 'user:root@pam:0:0::::::'."\n".
891f7afa
FG
1014 'user:test@pam:0:0::::::'."\n".
1015 'token:test@pam!test:0:0::'."\n\n".
7d1739ad
FG
1016 'group:testgroup:::'."\n\n".
1017 'pool:testpool::::'."\n\n".
1018 'role:testrole::'."\n\n",
1019 },
1020];
1021
1022
1023my $number_of_tests_run = 0;
1024foreach my $t (@$tests) {
1025 my $expected_config = $t->{expected_config} // $t->{config};
1026 my $expected_raw = $t->{expected_raw} // $t->{raw};
1027 if (defined($t->{raw})) {
1028 my $parsed = PVE::AccessControl::parse_user_config($t->{name}, $t->{raw});
1029 if (defined($expected_config)) {
1030 is_deeply($parsed, $expected_config, "$t->{name}_parse");
1031 $number_of_tests_run++;
1032 }
1033 if (defined($t->{expected_raw}) && !defined($t->{config})) {
1034 is(PVE::AccessControl::write_user_config($t->{name}, $parsed), $t->{expected_raw}, "$t->{name}_rewrite");
1035 $number_of_tests_run++;
1036 }
1037
1038 }
1039 if (defined($t->{config})) {
1040 my $written = PVE::AccessControl::write_user_config($t->{name}, $t->{config});
1041 if (defined($expected_raw)) {
1042 is($written, $expected_raw, "$t->{name}_write");
1043 $number_of_tests_run++;
1044 }
1045 if (defined($t->{expected_config}) && !defined($t->{raw})) {
1046 is_deeply(PVE::AccessControl::parse_user_config($t->{name}, $t->{written}), $t->{expected_config}, "$t->{name}_reparse");
1047 $number_of_tests_run++;
1048 }
1049 }
1050};
1051
1052done_testing( $number_of_tests_run);