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