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