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