]>
Commit | Line | Data |
---|---|---|
1 | package PVE::API2::Role; | |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use PVE::Cluster qw (cfs_read_file cfs_write_file); | |
6 | use PVE::AccessControl; | |
7 | use PVE::JSONSchema qw(get_standard_option register_standard_option); | |
8 | ||
9 | use PVE::SafeSyslog; | |
10 | ||
11 | use PVE::RESTHandler; | |
12 | ||
13 | use base qw(PVE::RESTHandler); | |
14 | ||
15 | register_standard_option('role-id', { | |
16 | type => 'string', | |
17 | format => 'pve-roleid', | |
18 | }); | |
19 | register_standard_option('role-privs', { | |
20 | type => 'string' , | |
21 | format => 'pve-priv-list', | |
22 | optional => 1, | |
23 | }); | |
24 | ||
25 | __PACKAGE__->register_method ({ | |
26 | name => 'index', | |
27 | path => '', | |
28 | method => 'GET', | |
29 | description => "Role index.", | |
30 | permissions => { | |
31 | user => 'all', | |
32 | }, | |
33 | parameters => { | |
34 | additionalProperties => 0, | |
35 | properties => {}, | |
36 | }, | |
37 | returns => { | |
38 | type => 'array', | |
39 | items => { | |
40 | type => "object", | |
41 | properties => { | |
42 | roleid => get_standard_option('role-id'), | |
43 | privs => get_standard_option('role-privs'), | |
44 | special => { type => 'boolean', optional => 1, default => 0 }, | |
45 | }, | |
46 | }, | |
47 | links => [ { rel => 'child', href => "{roleid}" } ], | |
48 | }, | |
49 | code => sub { | |
50 | my ($param) = @_; | |
51 | ||
52 | my $res = []; | |
53 | ||
54 | my $usercfg = cfs_read_file("user.cfg"); | |
55 | ||
56 | foreach my $role (keys %{$usercfg->{roles}}) { | |
57 | my $privs = join(',', sort keys %{$usercfg->{roles}->{$role}}); | |
58 | push @$res, { | |
59 | roleid => $role, | |
60 | privs => $privs, | |
61 | special => PVE::AccessControl::role_is_special($role), | |
62 | }; | |
63 | } | |
64 | ||
65 | return $res; | |
66 | }}); | |
67 | ||
68 | __PACKAGE__->register_method ({ | |
69 | name => 'create_role', | |
70 | protected => 1, | |
71 | path => '', | |
72 | method => 'POST', | |
73 | permissions => { | |
74 | check => ['perm', '/access', ['Sys.Modify']], | |
75 | }, | |
76 | description => "Create new role.", | |
77 | parameters => { | |
78 | additionalProperties => 0, | |
79 | properties => { | |
80 | roleid => get_standard_option('role-id'), | |
81 | privs => get_standard_option('role-privs'), | |
82 | }, | |
83 | }, | |
84 | returns => { type => 'null' }, | |
85 | code => sub { | |
86 | my ($param) = @_; | |
87 | ||
88 | PVE::AccessControl::lock_user_config( | |
89 | sub { | |
90 | ||
91 | my $usercfg = cfs_read_file("user.cfg"); | |
92 | ||
93 | my $role = $param->{roleid}; | |
94 | ||
95 | die "role '$role' already exists\n" | |
96 | if $usercfg->{roles}->{$role}; | |
97 | ||
98 | $usercfg->{roles}->{$role} = {}; | |
99 | ||
100 | PVE::AccessControl::add_role_privs($role, $usercfg, $param->{privs}); | |
101 | ||
102 | cfs_write_file("user.cfg", $usercfg); | |
103 | }, "create role failed"); | |
104 | ||
105 | return undef; | |
106 | }}); | |
107 | ||
108 | __PACKAGE__->register_method ({ | |
109 | name => 'update_role', | |
110 | protected => 1, | |
111 | path => '{roleid}', | |
112 | method => 'PUT', | |
113 | permissions => { | |
114 | check => ['perm', '/access', ['Sys.Modify']], | |
115 | }, | |
116 | description => "Update an existing role.", | |
117 | parameters => { | |
118 | additionalProperties => 0, | |
119 | properties => { | |
120 | roleid => get_standard_option('role-id'), | |
121 | privs => get_standard_option('role-privs'), | |
122 | append => { type => 'boolean', optional => 1, requires => 'privs' }, | |
123 | }, | |
124 | }, | |
125 | returns => { type => 'null' }, | |
126 | code => sub { | |
127 | my ($param) = @_; | |
128 | ||
129 | my $role = $param->{roleid}; | |
130 | ||
131 | die "auto-generated role '$role' cannot be modified\n" | |
132 | if PVE::AccessControl::role_is_special($role); | |
133 | ||
134 | PVE::AccessControl::lock_user_config( | |
135 | sub { | |
136 | ||
137 | my $usercfg = cfs_read_file("user.cfg"); | |
138 | ||
139 | die "role '$role' does not exist\n" | |
140 | if !$usercfg->{roles}->{$role}; | |
141 | ||
142 | $usercfg->{roles}->{$role} = {} if !$param->{append}; | |
143 | ||
144 | PVE::AccessControl::add_role_privs($role, $usercfg, $param->{privs}); | |
145 | ||
146 | cfs_write_file("user.cfg", $usercfg); | |
147 | }, "update role failed"); | |
148 | ||
149 | return undef; | |
150 | }}); | |
151 | ||
152 | __PACKAGE__->register_method ({ | |
153 | name => 'read_role', | |
154 | path => '{roleid}', | |
155 | method => 'GET', | |
156 | permissions => { | |
157 | user => 'all', | |
158 | }, | |
159 | description => "Get role configuration.", | |
160 | parameters => { | |
161 | additionalProperties => 0, | |
162 | properties => { | |
163 | roleid => get_standard_option('role-id'), | |
164 | }, | |
165 | }, | |
166 | returns => { | |
167 | type => "object", | |
168 | additionalProperties => 0, | |
169 | properties => PVE::AccessControl::create_priv_properties(), | |
170 | }, | |
171 | code => sub { | |
172 | my ($param) = @_; | |
173 | ||
174 | my $usercfg = cfs_read_file("user.cfg"); | |
175 | ||
176 | my $role = $param->{roleid}; | |
177 | ||
178 | my $data = $usercfg->{roles}->{$role}; | |
179 | ||
180 | die "role '$role' does not exist\n" if !$data; | |
181 | ||
182 | return $data; | |
183 | } | |
184 | }); | |
185 | ||
186 | __PACKAGE__->register_method ({ | |
187 | name => 'delete_role', | |
188 | protected => 1, | |
189 | path => '{roleid}', | |
190 | method => 'DELETE', | |
191 | permissions => { | |
192 | check => ['perm', '/access', ['Sys.Modify']], | |
193 | }, | |
194 | description => "Delete role.", | |
195 | parameters => { | |
196 | additionalProperties => 0, | |
197 | properties => { | |
198 | roleid => get_standard_option('role-id'), | |
199 | }, | |
200 | }, | |
201 | returns => { type => 'null' }, | |
202 | code => sub { | |
203 | my ($param) = @_; | |
204 | ||
205 | my $role = $param->{roleid}; | |
206 | ||
207 | die "auto-generated role '$role' cannot be deleted\n" | |
208 | if PVE::AccessControl::role_is_special($role); | |
209 | ||
210 | PVE::AccessControl::lock_user_config( | |
211 | sub { | |
212 | my $usercfg = cfs_read_file("user.cfg"); | |
213 | ||
214 | die "role '$role' does not exist\n" | |
215 | if !$usercfg->{roles}->{$role}; | |
216 | ||
217 | delete ($usercfg->{roles}->{$role}); | |
218 | ||
219 | # fixme: delete role from acl? | |
220 | ||
221 | cfs_write_file("user.cfg", $usercfg); | |
222 | }, "delete role failed"); | |
223 | ||
224 | return undef; | |
225 | } | |
226 | }); | |
227 | ||
228 | 1; |