5
0
mirror of git://git.proxmox.com/git/pve-access-control.git synced 2025-01-03 01:17:55 +03:00

tests: api: add tests for expected output of get permissions endpoint

Adds test cases for the GET permissions API endpoint to ensure that:

- users with the Sys.Audit perm can access any user's permissions
- users with the Sys.Audit perm can access any token's permissions
- users without the Sys.Audit perm can access their own permissions
- users without the Sys.Audit perm can access their token's permissions
- tokens with the Sys.Audit perm can access any user's permissions
- tokens without the Sys.Audit perm can access their own permissions

These tests also separate whether a token has the privilege-separated
property or not.

Signed-off-by: Daniel Kral <d.kral@proxmox.com>
This commit is contained in:
Daniel Kral 2024-11-06 15:48:13 +01:00 committed by Thomas Lamprecht
parent 138ecc60fa
commit b8b2d85fe9
4 changed files with 355 additions and 0 deletions

View File

@ -13,3 +13,4 @@ check:
perl -I.. perm-test7.pl
perl -I.. perm-test8.pl
perl -I.. realm_sync_test.pl
perl -I.. api-tests.pl

View File

@ -0,0 +1,17 @@
user:auditor@pam:1:
token:auditor@pam!noprivsep::0:
token:auditor@pam!privsep::1:
user:stranger@pve:1:
token:stranger@pve!noprivsep::0:
token:stranger@pve!privsep::1:
role:sys_auditor:Sys.Audit:
role:vm_lurker:VM.Audit,VM.Console:
role:vm_manager:VM.PowerMgmt:
acl:1:/access:auditor@pam:sys_auditor:
acl:1:/vms:auditor@pam:vm_lurker:
acl:1:/vms:auditor@pam!privsep:vm_lurker:
acl:1:/vms:stranger@pve:vm_lurker:
acl:1:/vms:stranger@pve:vm_manager:
acl:1:/vms:stranger@pve!privsep:vm_lurker:

View File

@ -0,0 +1,325 @@
#!/usr/bin/env perl
use strict;
use warnings;
use lib qw(..);
use PVE::Tools;
use Test::More;
use Test::MockModule;
use PVE::AccessControl;
use PVE::RPCEnvironment;
use PVE::API2::AccessControl;
my $cluster_module = Test::MockModule->new('PVE::Cluster');
# make cfs_update a stub as it's not relevant to the test cases and will
# make these tests fail if the user doesn't have access to the cluster ipcc
$cluster_module->noop('cfs_update');
my $rpcenv = PVE::RPCEnvironment->init('cli');
$rpcenv->init_request(userconfig => 'api-get-permissions-test.cfg');
my ($handler, $handler_info) = PVE::API2::AccessControl->find_handler('GET', 'permissions');
# stranger = user without Sys.Audit permission
my $stranger_perms = $rpcenv->get_effective_permissions('stranger@pve');
my $stranger_privsep_perms = $rpcenv->get_effective_permissions('stranger@pve!privsep');
my $stranger_user_tests = [
{
description => 'get stranger\'s perms without passing the user\'s userid',
rpcuser => 'stranger@pve',
params => {},
result => $stranger_perms,
},
{
description => 'get stranger\'s perms with passing the user\'s userid',
rpcuser => 'stranger@pve',
params => {
userid => 'stranger@pve',
},
result => $stranger_perms,
},
{
description => 'get stranger-owned non-priv-sep\'d token\'s perms from stranger user',
rpcuser => 'stranger@pve',
params => {
userid => 'stranger@pve!noprivsep',
},
result => $stranger_perms,
},
{
description => 'get stranger-owned priv-sep\'d token\'s perms from stranger user',
rpcuser => 'stranger@pve',
params => {
userid => 'stranger@pve!privsep',
},
result => $stranger_privsep_perms,
},
{
description => 'get auditor\'s perms from stranger user',
should_fail => 1,
rpcuser => 'stranger@pve',
params => {
userid => 'auditor@pam',
},
},
{
description => 'get auditor-owned token\'s perms from stranger user',
should_fail => 1,
rpcuser => 'stranger@pve',
params => {
userid => 'auditor@pam!noprivsep',
},
},
];
my $stranger_nonprivsep_tests = [
{
description => 'get stranger-owned non-priv-sep\'d token\'s perms without passing the token',
rpcuser => 'stranger@pve!noprivsep',
params => {},
result => $stranger_perms,
},
{
description => 'get stranger-owned non-priv-sep\'d token\'s perms with passing the token',
rpcuser => 'stranger@pve!noprivsep',
params => {
userid => 'stranger@pve!noprivsep',
},
result => $stranger_perms,
},
{
description => 'get stranger\'s perms from stranger-owned non-priv-sep\'d token',
should_fail => 1,
rpcuser => 'stranger@pve!noprivsep',
params => {
userid => 'stranger@pve',
},
},
{
description => 'get stranger-owned priv-sep\'d token\'s perms '
. 'from stranger-owned non-priv-sep\'d token',
should_fail => 1,
rpcuser => 'stranger@pve!noprivsep',
params => {
userid => 'stranger@pve!privsep',
},
},
{
description => 'get auditor-owned token\'s perms from stranger-owned non-priv-sep\'d token',
should_fail => 1,
rpcuser => 'stranger@pve!noprivsep',
params => {
userid => 'auditor@pam!noprivsep',
}
},
];
my $stranger_privsep_tests = [
{
description => 'get stranger-owned priv-sep\'d token\'s perms without passing the token',
rpcuser => 'stranger@pve!privsep',
params => {},
result => $stranger_privsep_perms,
},
{
description => 'get stranger-owned priv-sep\'d token\'s perms with passing the token',
rpcuser => 'stranger@pve!privsep',
params => {
userid => 'stranger@pve!privsep',
},
result => $stranger_privsep_perms,
},
{
description => 'get stranger\'s perms from stranger-owned priv-sep\'d token',
should_fail => 1,
rpcuser => 'stranger@pve!privsep',
params => {
userid => 'stranger@pve',
},
},
{
description => 'get stranger-owned non-priv-sep\'d token\'s perms '
. 'from stranger-owned priv-sep\'d token',
should_fail => 1,
rpcuser => 'stranger@pve!privsep',
params => {
userid => 'stranger@pve!noprivsep',
},
},
{
description => 'get auditor-owned token\'s perms from stranger-owned priv-sep\'d token',
should_fail => 1,
rpcuser => 'stranger@pve!privsep',
params => {
userid => 'auditor@pam!noprivsep',
}
},
];
# auditor = user with Sys.Audit permission
my $auditor_perms = $rpcenv->get_effective_permissions('auditor@pam');
my $auditor_privsep_perms = $rpcenv->get_effective_permissions('auditor@pam!privsep');
my $auditor_user_tests = [
{
description => 'get auditor\'s perms without passing the user\'s userid',
rpcuser => 'auditor@pam',
params => {},
result => $auditor_perms,
},
{
description => 'get auditor\'s perms with passing the user\'s userid',
rpcuser => 'auditor@pam',
params => {
userid => 'auditor@pam',
},
result => $auditor_perms,
},
{
description => 'get auditor-owned non-priv-sep\'d token\'s perms from auditor user',
rpcuser => 'auditor@pam',
params => {
userid => 'auditor@pam!noprivsep',
},
result => $auditor_perms,
},
{
description => 'get auditor-owned priv-sep\'d token\'s perms from auditor user',
rpcuser => 'auditor@pam',
params => {
userid => 'auditor@pam!privsep',
},
result => $auditor_privsep_perms,
},
{
description => 'get stranger\'s perms from auditor user',
rpcuser => 'auditor@pam',
params => {
userid => 'stranger@pve',
},
result => $stranger_perms,
},
{
description => 'get stranger-owned token\'s perms from auditor user',
rpcuser => 'auditor@pam',
params => {
userid => 'stranger@pve!noprivsep',
},
result => $stranger_perms,
},
];
my $auditor_nonprivsep_tests = [
{
description => 'get auditor-owned non-priv-sep\'d token\'s perms without passing the token',
rpcuser => 'auditor@pam!noprivsep',
params => {},
result => $auditor_perms,
},
{
description => 'get auditor-owned non-priv-sep\'d token\'s perms with passing the token',
rpcuser => 'auditor@pam!noprivsep',
params => {
userid => 'auditor@pam!noprivsep',
},
result => $auditor_perms,
},
{
description => 'get auditor\'s perms from auditor-owned non-priv-sep\'d token',
rpcuser => 'auditor@pam!noprivsep',
params => {
userid => 'auditor@pam',
},
result => $auditor_perms,
},
{
description => 'get auditor-owned priv-sep\'d token\'s perms '
. 'from auditor-owned non-priv-sep\'d token',
rpcuser => 'auditor@pam!noprivsep',
params => {
userid => 'auditor@pam!privsep',
},
result => $auditor_privsep_perms,
},
{
description => 'get stranger-owned token\'s perms from auditor-owned non-priv-sep\'d token',
rpcuser => 'auditor@pam!noprivsep',
params => {
userid => 'stranger@pve!noprivsep',
},
result => $stranger_perms,
},
];
my $auditor_privsep_tests = [
{
description => 'get auditor-owned priv-sep\'d token\'s perms without passing the token',
rpcuser => 'auditor@pam!privsep',
params => {},
result => $auditor_privsep_perms,
},
{
description => 'get auditor-owned priv-sep\'d token\'s perms with passing the token',
rpcuser => 'auditor@pam!privsep',
params => {
userid => 'auditor@pam!privsep',
},
result => $auditor_privsep_perms,
},
{
description => 'get auditor\'s perms from auditor-owned priv-sep\'d token',
should_fail => 1,
rpcuser => 'auditor@pam!privsep',
params => {
userid => 'auditor@pam',
},
},
{
description => 'get auditor-owned non-priv-sep\'d token\'s perms '
. 'from auditor-owned priv-sep\'d token',
should_fail => 1,
rpcuser => 'auditor@pam!privsep',
params => {
userid => 'auditor@pam!noprivsep',
},
},
{
description => 'get stranger-owned token\'s perms from auditor-owned priv-sep\'d token',
should_fail => 1,
rpcuser => 'auditor@pam!privsep',
params => {
userid => 'stranger@pve!noprivsep',
},
},
];
my $tests = [
@$stranger_user_tests,
@$stranger_nonprivsep_tests,
@$stranger_privsep_tests,
@$auditor_user_tests,
@$auditor_nonprivsep_tests,
@$auditor_privsep_tests,
];
plan(tests => scalar($tests->@*));
for my $case ($tests->@*) {
$rpcenv->set_user($case->{rpcuser});
my $result = eval { $handler->handle($handler_info, $case->{params}) };
if ($@) {
my $should_fail = exists($case->{should_fail}) ? $case->{should_fail} : 0;
is(defined($@), $should_fail, "should fail: $case->{description}") || diag explain $@;
} else {
is_deeply($result, $case->{result}, $case->{description});
}
}
done_testing();

12
src/test/api-tests.pl Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env perl
use strict;
use warnings;
use TAP::Harness;
my $harness = TAP::Harness->new({ verbosity => -1 });
my $result = $harness->runtests('api-get-permissions-test.pl');
exit -1 if $result->{failed};