[pve-devel] [PATCH v3 access-control 14/20] API: add 'permissions' API endpoint
Fabian Grünbichler
f.gruenbichler at proxmox.com
Tue Jan 21 13:54:12 CET 2020
and related helper, to dump permissions + propagate info for
- a specific, given path
- generic top-level + user.cfg-referenced paths, including pools
Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
Notes:
new in v2
PVE/API2/AccessControl.pm | 56 +++++++++++++++++++++++++++++++++++++++
PVE/RPCEnvironment.pm | 41 ++++++++++++++++++++++++++++
2 files changed, 97 insertions(+)
diff --git a/PVE/API2/AccessControl.pm b/PVE/API2/AccessControl.pm
index c6499be..5b63d2b 100644
--- a/PVE/API2/AccessControl.pm
+++ b/PVE/API2/AccessControl.pm
@@ -661,4 +661,60 @@ __PACKAGE__->register_method({
}
}});
+__PACKAGE__->register_method({
+ name => 'permissions',
+ path => 'permissions',
+ method => 'GET',
+ description => 'Retrieve effective permissions of given user/token.',
+ permissions => {
+ description => "Each user/token is allowed to dump their own permissions. A user can dump the permissions of another user if they have 'Sys.Audit' permission on /access.",
+ user => 'all',
+ },
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ userid => {
+ type => 'string',
+ description => "User ID or full API token ID",
+ pattern => $PVE::AccessControl::userid_or_token_regex,
+ optional => 1,
+ },
+ path => get_standard_option('acl-path', {
+ description => "Only dump this specific path, not the whole tree.",
+ optional => 1,
+ }),
+ },
+ },
+ returns => {
+ type => 'object',
+ description => 'Map of "path" => (Map of "privilege" => "propagate boolean").',
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+
+ my $userid = $param->{userid};
+ if (defined($userid)) {
+ $rpcenv->check($rpcenv->get_user(), '/access', ['Sys.Audit']);
+ } else {
+ $userid = $rpcenv->get_user();
+ }
+
+ my $res;
+
+ if (my $path = $param->{path}) {
+ my $perms = $rpcenv->permissions($userid, $path);
+ if ($perms) {
+ $res = { $path => $perms };
+ } else {
+ $res = {};
+ }
+ } else {
+ $res = $rpcenv->get_effective_permissions($userid);
+ }
+
+ return $res;
+ }});
+
1;
diff --git a/PVE/RPCEnvironment.pm b/PVE/RPCEnvironment.pm
index 8384376..e66107b 100644
--- a/PVE/RPCEnvironment.pm
+++ b/PVE/RPCEnvironment.pm
@@ -127,6 +127,47 @@ sub permissions {
return &$compile_acl_path($self, $user, $path);
}
+sub get_effective_permissions {
+ my ($self, $user) = @_;
+
+ # default / top level paths
+ my $paths = {
+ '/' => 1,
+ '/access' => 1,
+ '/access/groups' => 1,
+ '/nodes' => 1,
+ '/pools' => 1,
+ '/storage' => 1,
+ '/vms' => 1,
+ };
+
+ my $cfg = $self->{user_cfg};
+
+ # paths explicitly listed in ACLs
+ foreach my $acl_path (keys %{$cfg->{acl}}) {
+ $paths->{$acl_path} = 1;
+ }
+
+ # paths referenced by pool definitions
+ foreach my $pool (keys %{$cfg->{pools}}) {
+ my $d = $cfg->{pools}->{$pool};
+ foreach my $vmid (keys %{$d->{vms}}) {
+ $paths->{"/vms/$vmid"} = 1;
+ }
+ foreach my $storeid (keys %{$d->{storage}}) {
+ $paths->{"/storage/$storeid"} = 1;
+ }
+ }
+
+ my $perms = {};
+ foreach my $path (keys %$paths) {
+ my $path_perms = $self->permissions($user, $path);
+ # filter paths where user has NO permissions
+ $perms->{$path} = $path_perms if %$path_perms;
+ }
+ return $perms;
+}
+
sub check {
my ($self, $user, $path, $privs, $noerr) = @_;
--
2.20.1
More information about the pve-devel
mailing list