]> git.proxmox.com Git - pve-access-control.git/blob - PVE/API2/ACL.pm
iimported from svn 'pve-access-control/trunk'
[pve-access-control.git] / PVE / API2 / ACL.pm
1 package PVE::API2::ACL;
2
3 use strict;
4 use warnings;
5 use PVE::Cluster qw (cfs_read_file cfs_write_file);
6 use PVE::Tools qw(split_list);
7 use PVE::AccessControl;
8 use PVE::Exception qw(raise_param_exc);
9
10 use PVE::SafeSyslog;
11
12 use Data::Dumper; # fixme: remove
13
14 use PVE::RESTHandler;
15
16 use base qw(PVE::RESTHandler);
17
18 __PACKAGE__->register_method ({
19 name => 'read_acl',
20 path => '',
21 method => 'GET',
22 description => "Get Access Control List (ACLs).",
23 parameters => {
24 additionalProperties => 0,
25 properties => {},
26 },
27 returns => {
28 type => 'array',
29 items => {
30 type => "object",
31 additionalProperties => 0,
32 properties => {
33 path => { type => 'string' },
34 type => { type => 'string', enum => ['user', 'group'] },
35 ugid => { type => 'string' },
36 roleid => { type => 'string' },
37 propagate => { type => 'boolean' },
38 },
39 },
40 },
41 code => sub {
42 my ($param) = @_;
43
44 my $res = [];
45
46 my $usercfg = cfs_read_file("user.cfg");
47
48 if (!$usercfg || !$usercfg->{acl}) {
49 return {};
50 }
51
52 my $acl = $usercfg->{acl};
53 foreach my $path (keys %$acl) {
54 foreach my $type (qw(users groups)) {
55 my $d = $acl->{$path}->{$type};
56 next if !$d;
57 foreach my $id (keys %$d) {
58 foreach my $role (keys %{$d->{$id}}) {
59 my $propagate = $d->{$id}->{$role};
60 push @$res, {
61 path => $path,
62 type => $type eq 'groups' ? 'group' : 'user',
63 ugid => $id,
64 roleid => $role,
65 propagate => $propagate,
66 };
67 }
68 }
69 }
70 }
71
72 return $res;
73 }});
74
75 __PACKAGE__->register_method ({
76 name => 'update_acl',
77 protected => 1,
78 path => '',
79 method => 'PUT',
80 description => "Update Access Control List (add or remove permissions).",
81 parameters => {
82 additionalProperties => 0,
83 properties => {
84 path => {
85 description => "Access control path",
86 type => 'string',
87 },
88 users => {
89 description => "List of users.",
90 type => 'string', format => 'pve-userid-list',
91 optional => 1,
92 },
93 groups => {
94 description => "List of groups.",
95 type => 'string', format => 'pve-groupid-list',
96 optional => 1,
97 },
98 roles => {
99 description => "List of roles.",
100 type => 'string', format => 'pve-roleid-list',
101 },
102 propagate => {
103 description => "Allow to propagate (inherit) permissions.",
104 type => 'boolean',
105 optional => 1,
106 },
107 delete => {
108 description => "Remove permissions (instead of adding it).",
109 type => 'boolean',
110 optional => 1,
111 },
112 },
113 },
114 returns => { type => 'null' },
115 code => sub {
116 my ($param) = @_;
117
118 if (!($param->{users} || $param->{groups})) {
119 raise_param_exc({
120 users => "either 'users' or 'groups' is required.",
121 groups => "either 'users' or 'groups' is required." });
122 }
123
124 my $path = PVE::AccessControl::normalize_path($param->{path});
125 raise_param_exc({ path => "invalid ACL path '$param->{path}'" }) if !$path;
126
127 PVE::AccessControl::lock_user_config(
128 sub {
129
130 my $cfg = cfs_read_file("user.cfg");
131
132 my $propagate = $param->{propagate} ? 1 : 0;
133
134 foreach my $role (split_list($param->{roles})) {
135 die "role '$role' does not exist\n"
136 if !$cfg->{roles}->{$role};
137
138 foreach my $group (split_list($param->{groups})) {
139
140 die "group '$group' does not exist\n"
141 if !$cfg->{groups}->{$group};
142
143 if ($param->{delete}) {
144 delete($cfg->{acl}->{$path}->{groups}->{$group}->{$role});
145 } else {
146 $cfg->{acl}->{$path}->{groups}->{$group}->{$role} = $propagate;
147 }
148 }
149
150 foreach my $userid (split_list($param->{users})) {
151 my $username = PVE::AccessControl::verify_username($userid);
152
153 die "user '$username' does not exist\n"
154 if !$cfg->{users}->{$username};
155
156 if ($param->{delete}) {
157 delete($cfg->{acl}->{$path}->{users}->{$username}->{$role});
158 } else {
159 $cfg->{acl}->{$path}->{users}->{$username}->{$role} = $propagate;
160 }
161 }
162 }
163
164 cfs_write_file("user.cfg", $cfg);
165 }, "ACL update failed");
166
167 return undef;
168 }});
169
170 1;