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