[pve-devel] [PATCH v3 access-control 15/20] test: add token-related tests

Fabian Grünbichler f.gruenbichler at proxmox.com
Tue Jan 21 13:54:13 CET 2020


Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---

Notes:
    v2->v3: retitled commit
    new in v2

 test/Makefile         |   1 +
 test/parser_writer.pl | 173 +++++++++++++++++++++++++++++++++++++++++-
 test/perm-test8.pl    |  68 +++++++++++++++++
 test/test8.cfg        |  28 +++++++
 4 files changed, 268 insertions(+), 2 deletions(-)
 create mode 100644 test/perm-test8.pl
 create mode 100644 test/test8.cfg

diff --git a/test/Makefile b/test/Makefile
index dc75e4f..adaacb9 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -11,3 +11,4 @@ check:
 	perl -I.. perm-test5.pl
 	perl -I.. perm-test6.pl
 	perl -I.. perm-test7.pl
+	perl -I.. perm-test8.pl
diff --git a/test/parser_writer.pl b/test/parser_writer.pl
index 28c5a8c..6bf6d72 100755
--- a/test/parser_writer.pl
+++ b/test/parser_writer.pl
@@ -160,6 +160,38 @@ my $default_cfg = {
 	'email' => undef,
 	'groups' => { 'another' => 1 },
     },
+    test_pam_with_token => {
+	'id' => 'test at pam',
+	'enable' => 1,
+	'expire' => 0,
+	'email' => undef,
+	'tokens' => {
+	    'full' => {
+		'privsep' => 0,
+		'expire' => 0,
+	    },
+	},
+    },
+    test_pam2_with_token => {
+	'id' => 'test2 at pam',
+	'enable' => 1,
+	'expire' => 0,
+	'email' => undef,
+	'tokens' => {
+	    'full' => {
+		'privsep' => 0,
+		'expire' => 0,
+	    },
+	    'privsep' => {
+		'privsep' => 1,
+		'expire' => 0,
+	    },
+	    'expired' => {
+		'privsep' => 0,
+		'expire' => 1,
+	    },
+	},
+    },
     test_group_empty => {
 	'id' => 'testgroup',
 	users => {},
@@ -239,6 +271,39 @@ my $default_cfg = {
 	    },
 	},
     },
+    acl_simple_token => {
+	'path' => '/',
+	tokens => {
+	    'test at pam!full' => {
+		'PVEVMAdmin' => 1,
+	    },
+	},
+    },
+    acl_complex_tokens => {
+	'path' => '/storage',
+	tokens => {
+	    'test2 at pam!privsep' => {
+		'PVEDatastoreUser' => 1,
+	    },
+	    'test2 at pam!expired' => {
+		'PVEDatastoreAdmin' => 1,
+	    },
+	    'test at pam!full' => {
+		'PVEDatastoreAdmin' => 1,
+	    },
+	},
+    },
+    acl_complex_missing_token => {
+	'path' => '/storage',
+	tokens => {
+	    'test2 at pam!expired' => {
+		'PVEDatastoreAdmin' => 1,
+	    },
+	    'test2 at pam!privsep' => {
+		'PVEDatastoreUser' => 1,
+	    },
+	},
+    },
     acl_simple_group => {
 	'path' => '/',
 	groups => {
@@ -333,6 +398,12 @@ my $default_raw = {
 	'test_group_members_out_of_order' => 'group:testgroup:test at pam,test2 at pam::',
 	'test_group_second' => 'group:another:test3 at pam::',
     },
+    tokens => {
+	'test_token_simple' => 'token:test at pam!full:0:0::',
+	'test_token_multi_full' => 'token:test2 at pam!full:0:0::',
+	'test_token_multi_privsep' => 'token:test2 at pam!privsep:0:1::',
+	'test_token_multi_expired' => 'token:test2 at pam!expired:1:0::',
+    },
     roles => {
 	'test_role_single_priv' => 'role:testrolesingle:VM.Allocate:',
 	'test_role_privs' => 'role:testrole:Datastore.Audit,VM.Allocate:',
@@ -352,6 +423,10 @@ my $default_raw = {
 	'acl_simple_user' => 'acl:1:/:test at pam:PVEVMAdmin:',
 	'acl_complex_users_1' => 'acl:1:/storage:test at pam:PVEDatastoreAdmin:',
 	'acl_complex_users_2' => 'acl:1:/storage:test2 at pam:PVEDatastoreUser:',
+	'acl_simple_token' => 'acl:1:/:test at pam!full:PVEVMAdmin:',
+	'acl_complex_tokens_1' => 'acl:1:/storage:test2 at pam!expired,test at pam!full:PVEDatastoreAdmin:',
+	'acl_complex_tokens_2' => 'acl:1:/storage:test2 at pam!privsep:PVEDatastoreUser:',
+	'acl_complex_tokens_1_missing' => 'acl:1:/storage:test2 at pam!expired:PVEDatastoreAdmin:',
 	'acl_simple_group' => 'acl:1:/:@testgroup:PVEVMAdmin:',
 	'acl_complex_groups_1' => 'acl:1:/storage:@testgroup:PVEDatastoreAdmin:',
 	'acl_complex_groups_2' => 'acl:1:/storage:@another:PVEDatastoreUser:',
@@ -450,6 +525,33 @@ my $tests = [
 	       $default_raw->{groups}->{'test_group_members'}."\n\n".
 	       "\n\n",
     },
+    {
+	name => "token_simple",
+	config => {
+	    users => default_users_with([$default_cfg->{test_pam_with_token}]),
+	    roles => default_roles(),
+	},
+	raw => "".
+	       $default_raw->{users}->{'root at pam'}."\n".
+	       $default_raw->{users}->{'test_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n",
+    },
+    {
+	name => "token_multi",
+	config => {
+	    users => default_users_with([$default_cfg->{test_pam_with_token}, $default_cfg->{test_pam2_with_token}]),
+	    roles => default_roles(),
+	},
+	raw => "".
+	       $default_raw->{users}->{'root at pam'}."\n".
+	       $default_raw->{users}->{'test2_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_full'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
+	       $default_raw->{users}->{'test_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_simple'}."\n".
+	       "\n\n\n\n",
+    },
     {
 	name => "custom_role_with_single_priv",
 	config => {
@@ -655,6 +757,65 @@ my $tests = [
 	       $default_raw->{groups}->{'test_group_second'}."\n\n\n\n".
 	       $default_raw->{acl}->{'acl_complex_groups_2'}."\n",
     },
+    {
+	name => "acl_simple_token",
+	config => {
+	    users => default_users_with([$default_cfg->{test_pam_with_token}]),
+	    roles => default_roles(),
+	    acl => default_acls_with([$default_cfg->{acl_simple_token}]),
+	},
+	raw => "".
+	       $default_raw->{users}->{'root at pam'}."\n".
+	       $default_raw->{users}->{'test_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n".
+	       $default_raw->{acl}->{'acl_simple_token'}."\n",
+    },
+    {
+	name => "acl_complex_tokens",
+	config => {
+	    users => default_users_with([$default_cfg->{test_pam_with_token}, $default_cfg->{'test_pam2_with_token'}]),
+	    roles => default_roles(),
+	    acl => default_acls_with([$default_cfg->{acl_simple_token}, $default_cfg->{acl_complex_tokens}]),
+	},
+	raw => "".
+	       $default_raw->{users}->{'root at pam'}."\n".
+	       $default_raw->{users}->{'test2_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_full'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
+	       $default_raw->{users}->{'test_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_simple'}."\n\n\n\n\n".
+	       $default_raw->{acl}->{'acl_simple_token'}."\n".
+	       $default_raw->{acl}->{'acl_complex_tokens_1'}."\n".
+	       $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
+    },
+    {
+	name => "acl_complex_missing_token",
+	config => {
+	    users => default_users_with([$default_cfg->{test_pam}, $default_cfg->{test_pam2_with_token}]),
+	    roles => default_roles(),
+	    acl => default_acls_with([$default_cfg->{acl_complex_missing_token}]),
+	},
+	raw => "".
+	       $default_raw->{users}->{'root at pam'}."\n".
+	       $default_raw->{users}->{'test2_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_full'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
+	       $default_raw->{users}->{'test_pam'}."\n".
+	       $default_raw->{acl}->{'acl_simple_token'}."\n".
+	       $default_raw->{acl}->{'acl_complex_tokens_1'}."\n".
+	       $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
+	expected_raw => "".
+	       $default_raw->{users}->{'root at pam'}."\n".
+	       $default_raw->{users}->{'test2_pam'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_expired'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_full'}."\n".
+	       $default_raw->{tokens}->{'test_token_multi_privsep'}."\n".
+	       $default_raw->{users}->{'test_pam'}."\n\n\n\n\n".
+	       $default_raw->{acl}->{'acl_complex_tokens_1_missing'}."\n".
+	       $default_raw->{acl}->{'acl_complex_tokens_2'}."\n",
+    },
     {
 	name => "acl_missing_role",
 	config => {
@@ -793,6 +954,12 @@ my $tests = [
 		    enable => 0,
 		    expire => 0,
 		    email => undef,
+		    tokens => {
+			'test' => {
+			    expire => 0,
+			    privsep => 0,
+			},
+		    },
 		},
 	    },
 	    roles => default_roles_with([{ id => 'testrole' }]),
@@ -801,14 +968,16 @@ my $tests = [
 	},
 	raw => "".
 	       'user:root at pam'."\n".
-	       'user:test at pam'."\n\n".
+	       'user:test at pam'."\n".
+	       'token:test at pam!test'."\n\n".
 	       'group:testgroup'."\n\n".
 	       'pool:testpool'."\n\n".
 	       'role:testrole'."\n\n".
 	       'acl::/:',
 	expected_raw => "".
 	       'user:root at pam:0:0::::::'."\n".
-	       'user:test at pam:0:0::::::'."\n\n".
+	       'user:test at pam:0:0::::::'."\n".
+	       'token:test at pam!test:0:0::'."\n\n".
 	       'group:testgroup:::'."\n\n".
 	       'pool:testpool::::'."\n\n".
 	       'role:testrole::'."\n\n",
diff --git a/test/perm-test8.pl b/test/perm-test8.pl
new file mode 100644
index 0000000..67e0cb1
--- /dev/null
+++ b/test/perm-test8.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -w
+
+use strict;
+use PVE::Tools;
+use PVE::AccessControl;
+use PVE::RPCEnvironment;
+
+my $rpcenv = PVE::RPCEnvironment->init('cli');
+
+my $cfgfn = "test8.cfg";
+$rpcenv->init_request(userconfig => $cfgfn);
+
+sub check_roles {
+    my ($user, $path, $expected_result) = @_;
+
+    my $roles = PVE::AccessControl::roles($rpcenv->{user_cfg}, $user, $path);
+    my $res = join(',', sort keys %$roles);
+
+    die "unexpected result\nneed '${expected_result}'\ngot '$res'\n"
+	if $res ne $expected_result;
+
+    print "ROLES:$path:$user:$res\n";
+}
+
+sub check_permission {
+    my ($user, $path, $expected_result) = @_;
+
+    my $perm = $rpcenv->permissions($user, $path);
+    my $res = join(',', sort keys %$perm);
+
+    die "unexpected result\nneed '${expected_result}'\ngot '$res'\n"
+	if $res ne $expected_result;
+
+    $perm = $rpcenv->permissions($user, $path);
+    $res = join(',', sort keys %$perm);
+    die "unexpected result (compiled)\nneed '${expected_result}'\ngot '$res'\n"
+	if $res ne $expected_result;
+
+    print "PERM:$path:$user:$res\n";
+}
+
+check_roles('max at pve', '/', '');
+check_roles('max at pve', '/vms', 'vm_admin');
+
+#user permissions overrides group permissions
+check_roles('max at pve', '/vms/100', 'customer');
+check_roles('max at pve', '/vms/101', 'vm_admin');
+
+check_permission('max at pve', '/', '');
+check_permission('max at pve', '/vms', 'Permissions.Modify,VM.Allocate,VM.Audit,VM.Console');
+check_permission('max at pve', '/vms/100', 'VM.Audit,VM.PowerMgmt');
+
+check_permission('alex at pve', '/vms', '');
+check_permission('alex at pve', '/vms/100', 'VM.Audit,VM.PowerMgmt');
+
+check_roles('max at pve', '/vms/200', 'storage_manager');
+check_roles('joe at pve', '/vms/200', 'vm_admin');
+check_roles('sue at pve', '/vms/200', 'NoAccess');
+
+check_roles('carol at pam', '/vms/200', 'NoAccess');
+check_roles('carol at pam!token', '/vms/200', 'NoAccess');
+check_roles('max at pve!token', '/vms/200', 'storage_manager');
+check_roles('max at pve!token2', '/vms/200', 'customer');
+
+print "all tests passed\n";
+
+exit (0);
+
diff --git a/test/test8.cfg b/test/test8.cfg
new file mode 100644
index 0000000..6b0eac6
--- /dev/null
+++ b/test/test8.cfg
@@ -0,0 +1,28 @@
+user:joe at pve:1:
+user:max at pve:1:
+token:max at pve!token::0:
+token:max at pve!token2::1:
+user:alex at pve:1:
+user:sue at pve:1:
+user:carol at pam:1:
+token:carol at pam!token:
+
+group:testgroup1:joe at pve,max at pve,sue at pve:
+group:testgroup2:alex at pve,carol at pam,sue at pve:
+group:testgroup3:max at pve:
+
+role:storage_manager:Datastore.AllocateSpace,Datastore.Audit:
+role:customer:VM.Audit,VM.PowerMgmt:
+role:vm_admin:VM.Audit,VM.Allocate,Permissions.Modify,VM.Console:
+
+acl:1:/vms:@testgroup1:vm_admin:
+acl:1:/vms/100/:alex at pve,max at pve:customer:
+acl:1:/storage/nfs1:@testgroup2:storage_manager:
+acl:1:/users:max at pve:Administrator:
+
+acl:1:/vms/200:@testgroup3:storage_manager:
+acl:1:/vms/200:@testgroup2:NoAccess:
+
+acl:1:/vms/200:carol at pam!token:vm_admin
+acl:1:/vms/200:max at pve!token:storage_manager
+acl:1:/vms/200:max at pve!token2:customer
-- 
2.20.1





More information about the pve-devel mailing list