[pve-devel] [PATCH manager 01/17] copy api permission calculation to /version api call

Dominik Csapak d.csapak at proxmox.com
Wed Jul 19 15:45:13 CEST 2017


the code is copied from the /access/ticket api call
from the pve-access-control package

this will be used instead of the /access/ticket call,
because we will be using the /version api call to get info from the
backend to the frontend (e.g. storage type capabilities)

i do not want to remove the code from the /access/ticket call yet,
as this would change the api (and someone could rely on that)

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 PVE/API2.pm | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/PVE/API2.pm b/PVE/API2.pm
index 38baf133..f2663956 100644
--- a/PVE/API2.pm
+++ b/PVE/API2.pm
@@ -6,6 +6,8 @@ use warnings;
 use PVE::pvecfg;
 use PVE::RESTHandler;
 use PVE::JSONSchema;
+use PVE::Storage;
+use PVE::Cluster;
 
 use base qw(PVE::RESTHandler);
 
@@ -79,6 +81,81 @@ __PACKAGE__->register_method ({
 	return $res;
     }});
 
+my $compute_api_permission = sub {
+    my ($rpcenv) = @_;
+
+    my $authuser = $rpcenv->get_user();
+    my $usercfg = $rpcenv->{user_cfg};
+
+    my $nodelist = PVE::Cluster::get_nodelist();
+    my $vmlist = PVE::Cluster::get_vmlist() || {};
+    my $idlist = $vmlist->{ids} || {};
+
+    my $cfg = PVE::Storage::config();
+    my @sids =  PVE::Storage::storage_ids ($cfg);
+
+    my $res = {
+	vms => {},
+	storage => {},
+	access => {},
+	nodes => {},
+	dc => {},
+    };
+
+    my $extract_vm_caps = sub {
+	my ($path) = @_;
+
+	my $perm = $rpcenv->permissions($authuser, $path);
+	foreach my $priv (keys %$perm) {
+	    next if !($priv eq 'Permissions.Modify' || $priv =~ m/^VM\./);
+	    $res->{vms}->{$priv} = 1;
+	}
+    };
+
+    foreach my $pool (keys %{$usercfg->{pools}}) {
+	&$extract_vm_caps("/pool/$pool");
+    }
+
+    foreach my $vmid (keys %$idlist, '__phantom__') {
+	&$extract_vm_caps("/vms/$vmid");
+    }
+
+    foreach my $storeid (@sids, '__phantom__') {
+	my $perm = $rpcenv->permissions($authuser, "/storage/$storeid"); foreach my $priv (keys %$perm) {
+	    next if !($priv eq 'Permissions.Modify' || $priv =~ m/^Datastore\./);
+	    $res->{storage}->{$priv} = 1;
+	}
+    }
+
+    foreach my $path (('/access/groups')) {
+	my $perm = $rpcenv->permissions($authuser, $path);
+	foreach my $priv (keys %$perm) {
+	    next if $priv !~ m/^(User|Group)\./;
+	    $res->{access}->{$priv} = 1;
+	}
+    }
+
+    foreach my $group (keys %{$usercfg->{users}->{$authuser}->{groups}}, '__phantom__') {
+	my $perm = $rpcenv->permissions($authuser, "/access/groups/$group");
+	if ($perm->{'User.Modify'}) {
+	    $res->{access}->{'User.Modify'} = 1;
+	}
+    }
+
+    foreach my $node (@$nodelist) {
+	my $perm = $rpcenv->permissions($authuser, "/nodes/$node");
+	foreach my $priv (keys %$perm) {
+	    next if $priv !~ m/^Sys\./;
+	    $res->{nodes}->{$priv} = 1;
+	}
+    }
+
+    my $perm = $rpcenv->permissions($authuser, "/");
+    $res->{dc}->{'Sys.Audit'} = 1 if $perm->{'Sys.Audit'};
+
+    return $res;
+};
+
 __PACKAGE__->register_method ({
     name => 'version', 
     path => 'version',
@@ -101,12 +178,17 @@ __PACKAGE__->register_method ({
 	my ($resp, $param) = @_;
     
 	my $res = PVE::Cluster::cfs_read_file('datacenter.cfg');
+	my $rpcenv = PVE::RPCEnvironment::get();
 
 	my $vi = PVE::pvecfg::version_info();
 	foreach my $k (qw(version release repoid)) {
 	    $res->{$k} = $vi->{$k};
 	}
 	
+	# get api permissions
+
+	$res->{cap} = $compute_api_permission->($rpcenv);
+
 	return $res;
     }});
 
-- 
2.11.0





More information about the pve-devel mailing list