373e8e2da4bebdd50ea8dbdb971262592eda7c30
[pve-access-control.git] / PVE / API2 / Group.pm
1 package PVE::API2::Group;
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 my $extract_group_data = sub {
17     my ($data, $full) = @_;
18
19     my $res = {};
20
21     $res->{comment} = $data->{comment} if defined($data->{comment});
22
23     return $res if !$full;
24
25     $res->{users} = $data->{users} ? [ keys %{$data->{users}} ] : [];
26
27     return $res;
28 };
29
30 # fixme: index should return more/all attributes?
31 __PACKAGE__->register_method ({
32     name => 'index', 
33     path => '', 
34     method => 'GET',
35     description => "Group index.",
36     permissions => { 
37         description => "The returned list is restricted to groups where you have 'User.Allocate' or 'Sys.Audit' permissions on '/access', or 'User.Allocate' on /access/groups/<group>.",
38         user => 'all',
39     },
40     parameters => {
41         additionalProperties => 0,
42         properties => {},
43     },
44     returns => {
45         type => 'array',
46         items => {
47             type => "object",
48             properties => {
49                 groupid => { type => 'string' },
50             },
51         },
52         links => [ { rel => 'child', href => "{groupid}" } ],
53     },
54     code => sub {
55         my ($param) = @_;
56     
57         my $res = [];
58
59         my $rpcenv = PVE::RPCEnvironment::get();
60         my $usercfg = cfs_read_file("user.cfg");
61         my $authuser = $rpcenv->get_user();
62
63         my $privs = [ 'User.Allocate', 'Sys.Audit' ];
64         my $allow = $rpcenv->check_any($authuser, "/access", $privs, 1);
65         my $allowed_groups = $rpcenv->filter_groups($authuser, $privs, 1);
66  
67         foreach my $group (keys %{$usercfg->{groups}}) {
68             next if !($allow || $allowed_groups->{$group});
69             my $entry = &$extract_group_data($usercfg->{groups}->{$group});
70             $entry->{groupid} = $group;
71             push @$res, $entry;
72         }
73
74         return $res;
75     }});
76
77 __PACKAGE__->register_method ({
78     name => 'create_group', 
79     protected => 1,
80     path => '', 
81     method => 'POST',
82     permissions => { 
83         check => ['perm', '/access', ['Sys.Modify']],
84     },
85     description => "Create new group.",
86     parameters => {
87         additionalProperties => 0,
88         properties => {
89             groupid => { type => 'string', format => 'pve-groupid' },
90             comment => { type => 'string', optional => 1 },
91         },
92     },
93     returns => { type => 'null' },
94     code => sub {
95         my ($param) = @_;
96
97         PVE::AccessControl::lock_user_config(
98             sub {
99                         
100                 my $usercfg = cfs_read_file("user.cfg");
101
102                 my $group = $param->{groupid};
103         
104                 die "group '$group' already exists\n" 
105                     if $usercfg->{groups}->{$group};
106
107                 $usercfg->{groups}->{$group} = { users => {} };
108
109                 $usercfg->{groups}->{$group}->{comment} = $param->{comment} if $param->{comment};
110
111                 
112                 cfs_write_file("user.cfg", $usercfg);
113             }, "create group failed");
114
115         return undef;
116     }});
117
118 __PACKAGE__->register_method ({
119     name => 'update_group', 
120     protected => 1,
121     path => '{groupid}', 
122     method => 'PUT',
123     permissions => { 
124         check => ['perm', '/access', ['Sys.Modify']],
125     },
126     description => "Update group data.",
127     parameters => {
128         additionalProperties => 0,
129         properties => {
130             # fixme: set/delete members
131             groupid => { type => 'string', format => 'pve-groupid' },
132             comment => { type => 'string', optional => 1 },
133         },
134     },
135     returns => { type => 'null' },
136     code => sub {
137         my ($param) = @_;
138
139         PVE::AccessControl::lock_user_config(
140             sub {
141                         
142                 my $usercfg = cfs_read_file("user.cfg");
143
144                 my $group = $param->{groupid};
145         
146                 my $data = $usercfg->{groups}->{$group};
147
148                 die "group '$group' does not exist\n" 
149                     if !$data;
150
151                 $data->{comment} = $param->{comment} if defined($param->{comment});
152                 
153                 cfs_write_file("user.cfg", $usercfg);
154             }, "update group failed");
155
156         return undef;
157     }});
158
159 # fixme: return format!
160 __PACKAGE__->register_method ({
161     name => 'read_group', 
162     path => '{groupid}', 
163     method => 'GET',
164     permissions => { 
165         check => ['perm', '/access', ['Sys.Audit']],
166     },
167     description => "Get group configuration.",
168     parameters => {
169         additionalProperties => 0,
170         properties => {
171             groupid => { type => 'string', format => 'pve-groupid' },
172         },
173     },
174     returns => {},
175     code => sub {
176         my ($param) = @_;
177
178         my $group = $param->{groupid};
179
180         my $usercfg = cfs_read_file("user.cfg");
181  
182         my $data = $usercfg->{groups}->{$group};
183
184         die "group '$group' does not exist\n" if !$data;
185
186         return &$extract_group_data($data, 1);
187     }});
188
189
190 __PACKAGE__->register_method ({
191     name => 'delete_group', 
192     protected => 1,
193     path => '{groupid}', 
194     method => 'DELETE',
195     permissions => { 
196         check => ['perm', '/access', ['Sys.Modify']],
197     },
198     description => "Delete group.",
199     parameters => {
200         additionalProperties => 0,
201         properties => {
202             groupid => { type => 'string' , format => 'pve-groupid' },
203         }
204     },
205     returns => { type => 'null' },
206     code => sub {
207         my ($param) = @_;
208
209         PVE::AccessControl::lock_user_config(
210             sub {
211
212                 my $usercfg = cfs_read_file("user.cfg");
213
214                 my $group = $param->{groupid};
215
216                 die "group '$group' does not exist\n" 
217                     if !$usercfg->{groups}->{$group};
218         
219                 delete ($usercfg->{groups}->{$group});
220
221                 PVE::AccessControl::delete_group_acl($group, $usercfg);
222
223                 cfs_write_file("user.cfg", $usercfg);
224             }, "delete group failed");
225         
226         return undef;
227     }});
228
229 1;