all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH access-control] tests: api: add tests for expected output of get permissions endpoint
@ 2024-11-06 14:48 Daniel Kral
  2024-11-10 19:09 ` [pve-devel] applied: " Thomas Lamprecht
  0 siblings, 1 reply; 2+ messages in thread
From: Daniel Kral @ 2024-11-06 14:48 UTC (permalink / raw)
  To: pve-devel

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 is related to the following patch series and should be only applied
after it:

https://lore.proxmox.com/pve-devel/20241105083039.150454-1-f.gruenbichler@proxmox.com/

Without the patch series above applied, test cases 2-4, 8, 13, 29 should
fail, as these were not considered before.

 src/test/Makefile                     |   1 +
 src/test/api-get-permissions-test.cfg |  17 ++
 src/test/api-get-permissions-test.pl  | 325 ++++++++++++++++++++++++++
 src/test/api-tests.pl                 |  12 +
 4 files changed, 355 insertions(+)
 create mode 100644 src/test/api-get-permissions-test.cfg
 create mode 100644 src/test/api-get-permissions-test.pl
 create mode 100755 src/test/api-tests.pl

diff --git a/src/test/Makefile b/src/test/Makefile
index 859a84b..53f2da7 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -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
diff --git a/src/test/api-get-permissions-test.cfg b/src/test/api-get-permissions-test.cfg
new file mode 100644
index 0000000..d9e415e
--- /dev/null
+++ b/src/test/api-get-permissions-test.cfg
@@ -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:
diff --git a/src/test/api-get-permissions-test.pl b/src/test/api-get-permissions-test.pl
new file mode 100644
index 0000000..f1af49f
--- /dev/null
+++ b/src/test/api-get-permissions-test.pl
@@ -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();
diff --git a/src/test/api-tests.pl b/src/test/api-tests.pl
new file mode 100755
index 0000000..a1a987a
--- /dev/null
+++ b/src/test/api-tests.pl
@@ -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};
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [pve-devel] applied: [PATCH access-control] tests: api: add tests for expected output of get permissions endpoint
  2024-11-06 14:48 [pve-devel] [PATCH access-control] tests: api: add tests for expected output of get permissions endpoint Daniel Kral
@ 2024-11-10 19:09 ` Thomas Lamprecht
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Lamprecht @ 2024-11-10 19:09 UTC (permalink / raw)
  To: Proxmox VE development discussion, Daniel Kral

Am 06.11.24 um 15:48 schrieb Daniel Kral:
> 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 is related to the following patch series and should be only applied
> after it:
> 
> https://lore.proxmox.com/pve-devel/20241105083039.150454-1-f.gruenbichler@proxmox.com/
> 
> Without the patch series above applied, test cases 2-4, 8, 13, 29 should
> fail, as these were not considered before.

A code review that results not only checking the changes but in a patch adding a
test harness? Impressive stuff that I gladly take, nice work!

> 
>  src/test/Makefile                     |   1 +
>  src/test/api-get-permissions-test.cfg |  17 ++
>  src/test/api-get-permissions-test.pl  | 325 ++++++++++++++++++++++++++
>  src/test/api-tests.pl                 |  12 +
>  4 files changed, 355 insertions(+)
>  create mode 100644 src/test/api-get-permissions-test.cfg
>  create mode 100644 src/test/api-get-permissions-test.pl
>  create mode 100755 src/test/api-tests.pl
> 
>

applied, thanks!


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-11-10 19:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-11-06 14:48 [pve-devel] [PATCH access-control] tests: api: add tests for expected output of get permissions endpoint Daniel Kral
2024-11-10 19:09 ` [pve-devel] applied: " Thomas Lamprecht

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal