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