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