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