]>
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 | ||
43aa2489 TL |
88 | PVE::AccessControl::lock_user_config(sub { |
89 | my $usercfg = cfs_read_file("user.cfg"); | |
0a6e09fd | 90 | |
43aa2489 | 91 | my $role = $param->{roleid}; |
2c3a6c0a | 92 | |
43aa2489 | 93 | die "role '$role' already exists\n" if $usercfg->{roles}->{$role}; |
2c3a6c0a | 94 | |
43aa2489 | 95 | $usercfg->{roles}->{$role} = {}; |
2c3a6c0a | 96 | |
43aa2489 | 97 | PVE::AccessControl::add_role_privs($role, $usercfg, $param->{privs}); |
2c3a6c0a | 98 | |
43aa2489 TL |
99 | cfs_write_file("user.cfg", $usercfg); |
100 | }, "create role failed"); | |
2c3a6c0a DM |
101 | |
102 | return undef; | |
0a6e09fd | 103 | }}); |
2c3a6c0a DM |
104 | |
105 | __PACKAGE__->register_method ({ | |
0a6e09fd | 106 | name => 'update_role', |
2c3a6c0a | 107 | protected => 1, |
0a6e09fd | 108 | path => '{roleid}', |
2c3a6c0a | 109 | method => 'PUT', |
0a6e09fd | 110 | permissions => { |
96919234 DM |
111 | check => ['perm', '/access', ['Sys.Modify']], |
112 | }, | |
3a5ae7a0 | 113 | description => "Update an existing role.", |
2c3a6c0a | 114 | parameters => { |
0a6e09fd | 115 | additionalProperties => 0, |
2c3a6c0a | 116 | properties => { |
3a5ae7a0 SI |
117 | roleid => get_standard_option('role-id'), |
118 | privs => get_standard_option('role-privs'), | |
119 | append => { type => 'boolean', optional => 1, requires => 'privs' }, | |
2c3a6c0a DM |
120 | }, |
121 | }, | |
122 | returns => { type => 'null' }, | |
123 | code => sub { | |
124 | my ($param) = @_; | |
125 | ||
deb63acf DC |
126 | my $role = $param->{roleid}; |
127 | ||
128 | die "auto-generated role '$role' cannot be modified\n" | |
129 | if PVE::AccessControl::role_is_special($role); | |
130 | ||
43aa2489 TL |
131 | PVE::AccessControl::lock_user_config(sub { |
132 | my $usercfg = cfs_read_file("user.cfg"); | |
0a6e09fd | 133 | |
43aa2489 | 134 | die "role '$role' does not exist\n" if !$usercfg->{roles}->{$role}; |
2c3a6c0a | 135 | |
43aa2489 | 136 | $usercfg->{roles}->{$role} = {} if !$param->{append}; |
2c3a6c0a | 137 | |
43aa2489 | 138 | PVE::AccessControl::add_role_privs($role, $usercfg, $param->{privs}); |
2c3a6c0a | 139 | |
43aa2489 TL |
140 | cfs_write_file("user.cfg", $usercfg); |
141 | }, "update role failed"); | |
2c3a6c0a DM |
142 | |
143 | return undef; | |
0a6e09fd | 144 | }}); |
2c3a6c0a | 145 | |
2c3a6c0a | 146 | __PACKAGE__->register_method ({ |
0a6e09fd PA |
147 | name => 'read_role', |
148 | path => '{roleid}', | |
2c3a6c0a | 149 | method => 'GET', |
0a6e09fd | 150 | permissions => { |
82b63965 | 151 | user => 'all', |
96919234 | 152 | }, |
2c3a6c0a DM |
153 | description => "Get role configuration.", |
154 | parameters => { | |
0a6e09fd | 155 | additionalProperties => 0, |
2c3a6c0a | 156 | properties => { |
3a5ae7a0 SI |
157 | roleid => get_standard_option('role-id'), |
158 | }, | |
159 | }, | |
160 | returns => { | |
161 | type => "object", | |
162 | additionalProperties => 0, | |
0fea3f16 | 163 | properties => PVE::AccessControl::create_priv_properties(), |
2c3a6c0a | 164 | }, |
2c3a6c0a DM |
165 | code => sub { |
166 | my ($param) = @_; | |
167 | ||
168 | my $usercfg = cfs_read_file("user.cfg"); | |
169 | ||
170 | my $role = $param->{roleid}; | |
171 | ||
172 | my $data = $usercfg->{roles}->{$role}; | |
173 | ||
174 | die "role '$role' does not exist\n" if !$data; | |
175 | ||
176 | return $data; | |
3a5ae7a0 SI |
177 | } |
178 | }); | |
2c3a6c0a DM |
179 | |
180 | __PACKAGE__->register_method ({ | |
0a6e09fd | 181 | name => 'delete_role', |
2c3a6c0a | 182 | protected => 1, |
0a6e09fd | 183 | path => '{roleid}', |
2c3a6c0a | 184 | method => 'DELETE', |
0a6e09fd | 185 | permissions => { |
96919234 DM |
186 | check => ['perm', '/access', ['Sys.Modify']], |
187 | }, | |
2c3a6c0a DM |
188 | description => "Delete role.", |
189 | parameters => { | |
0a6e09fd | 190 | additionalProperties => 0, |
2c3a6c0a | 191 | properties => { |
3a5ae7a0 SI |
192 | roleid => get_standard_option('role-id'), |
193 | }, | |
2c3a6c0a DM |
194 | }, |
195 | returns => { type => 'null' }, | |
196 | code => sub { | |
197 | my ($param) = @_; | |
198 | ||
e41cc73c | 199 | my $role = $param->{roleid}; |
2c3a6c0a | 200 | |
e41cc73c WB |
201 | die "auto-generated role '$role' cannot be deleted\n" |
202 | if PVE::AccessControl::role_is_special($role); | |
2c3a6c0a | 203 | |
43aa2489 TL |
204 | PVE::AccessControl::lock_user_config(sub { |
205 | my $usercfg = cfs_read_file("user.cfg"); | |
2c3a6c0a | 206 | |
43aa2489 | 207 | die "role '$role' does not exist\n" if !$usercfg->{roles}->{$role}; |
0a6e09fd | 208 | |
43aa2489 | 209 | delete ($usercfg->{roles}->{$role}); |
2c3a6c0a | 210 | |
43aa2489 | 211 | # fixme: delete role from acl? |
2c3a6c0a | 212 | |
43aa2489 TL |
213 | cfs_write_file("user.cfg", $usercfg); |
214 | }, "delete role failed"); | |
0a6e09fd | 215 | |
2c3a6c0a | 216 | return undef; |
3a5ae7a0 SI |
217 | } |
218 | }); | |
2c3a6c0a DM |
219 | |
220 | 1; |