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