style fix
[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 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, {
46                 roleid => $role,
47                 privs => $privs,
48                 special => PVE::AccessControl::role_is_special($role),
49             };
50         }
51
52         return $res;
53 }});
54
55 __PACKAGE__->register_method ({
56     name => 'create_role',
57     protected => 1,
58     path => '',
59     method => 'POST',
60     permissions => {
61         check => ['perm', '/access', ['Sys.Modify']],
62     },
63     description => "Create new role.",
64     parameters => {
65         additionalProperties => 0,
66         properties => {
67             roleid => { type => 'string', format => 'pve-roleid' },
68             privs => { type => 'string' , format => 'pve-priv-list', optional => 1 },
69         },
70     },
71     returns => { type => 'null' },
72     code => sub {
73         my ($param) = @_;
74
75         PVE::AccessControl::lock_user_config(
76             sub {
77
78                 my $usercfg = cfs_read_file("user.cfg");
79
80                 my $role = $param->{roleid};
81
82                 die "role '$role' already exists\n"
83                     if $usercfg->{roles}->{$role};
84
85                 $usercfg->{roles}->{$role} = {};
86
87                 PVE::AccessControl::add_role_privs($role, $usercfg, $param->{privs});
88
89                 cfs_write_file("user.cfg", $usercfg);
90             }, "create role failed");
91
92         return undef;
93 }});
94
95 __PACKAGE__->register_method ({
96     name => 'update_role',
97     protected => 1,
98     path => '{roleid}',
99     method => 'PUT',
100     permissions => {
101         check => ['perm', '/access', ['Sys.Modify']],
102     },
103     description => "Create new role.",
104     parameters => {
105         additionalProperties => 0,
106         properties => {
107             roleid => { type => 'string', format => 'pve-roleid' },
108             privs => { type => 'string' , format => 'pve-priv-list' },
109             append => {
110                 type => 'boolean',
111                 optional => 1,
112                 requires => 'privs',
113             },
114         },
115     },
116     returns => { type => 'null' },
117     code => sub {
118         my ($param) = @_;
119
120         PVE::AccessControl::lock_user_config(
121             sub {
122
123                 my $role = $param->{roleid};
124
125                 my $usercfg = cfs_read_file("user.cfg");
126
127                 die "role '$role' does not exist\n"
128                     if !$usercfg->{roles}->{$role};
129
130                 $usercfg->{roles}->{$role} = {} if !$param->{append};
131
132                 PVE::AccessControl::add_role_privs($role, $usercfg, $param->{privs});
133
134                 cfs_write_file("user.cfg", $usercfg);
135             }, "update role failed");
136
137         return undef;
138 }});
139
140 # fixme: return format!
141 __PACKAGE__->register_method ({
142     name => 'read_role',
143     path => '{roleid}',
144     method => 'GET',
145     permissions => {
146         user => 'all',
147     },
148     description => "Get role configuration.",
149     parameters => {
150         additionalProperties => 0,
151         properties => {
152             roleid => { type => 'string' , format => 'pve-roleid' },
153         },
154     },
155     returns => {},
156     code => sub {
157         my ($param) = @_;
158
159         my $usercfg = cfs_read_file("user.cfg");
160
161         my $role = $param->{roleid};
162
163         my $data = $usercfg->{roles}->{$role};
164
165         die "role '$role' does not exist\n" if !$data;
166
167         return $data;
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         my $role = $param->{roleid};
190
191         die "auto-generated role '$role' cannot be deleted\n"
192             if PVE::AccessControl::role_is_special($role);
193
194         PVE::AccessControl::lock_user_config(
195             sub {
196                 my $usercfg = cfs_read_file("user.cfg");
197
198                 die "role '$role' does not exist\n"
199                     if !$usercfg->{roles}->{$role};
200
201                 delete ($usercfg->{roles}->{$role});
202
203                 # fixme: delete role from acl?
204
205                 cfs_write_file("user.cfg", $usercfg);
206             }, "delete role failed");
207
208         return undef;
209 }});
210
211 1;