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