mirror of
https://git.proxmox.com/git/pve-access-control
synced 2025-07-20 20:42:32 +00:00
API: add 'permissions' API endpoint
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@proxmox.com>
This commit is contained in:
parent
7e8bcaa754
commit
c3fa8a3634
@ -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;
|
||||
|
@ -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) = @_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user