import rt 3.8.10
[freeside.git] / rt / lib / t / regression / 18stale_delegations_cleanup.t
1 #!/usr/bin/perl -w
2
3 # Regression test suite for http://rt3.fsck.com/Ticket/Display.html?id=6184
4 # and related corner cases related to cleanup of delegated ACEs when
5 # the delegator loses the right to delegate.  This causes complexities
6 # due to the fact that multiple ACEs can grant different delegation
7 # rights to a principal, and because DelegateRights and SuperUser can
8 # themselves be delegated.
9
10 # The case where the "parent" delegated ACE is removed is handled in
11 # the embedded regression tests in lib/RT/ACE_Overlay.pm .
12
13 use Test::More qw(no_plan);
14
15 use RT;
16
17 ok( RT::LoadConfig, "Locating config files" );
18 ok( RT::Init,       "Basic initialization and DB connectivity" );
19
20 my ($u1, $u2, $g1, $g2, $g3, $pg1, $pg2, $ace, @groups, @users, @principals);
21 @groups = (\$g1, \$g2, \$g3, \$pg1, \$pg2);
22 @users = (\$u1, \$u2);
23 @principals = (@groups, @users);
24
25 my($ret, $msg);
26
27 $u1 = RT::User->new($RT::SystemUser);
28 ( $ret, $msg ) = $u1->LoadOrCreateByEmail('delegtest1@example.com');
29 ok( $ret, "Load / Create test user 1: $msg" );
30 $u1->SetPrivileged(1);
31 $u2 = RT::User->new($RT::SystemUser);
32 ( $ret, $msg ) = $u2->LoadOrCreateByEmail('delegtest2@example.com');
33 ok( $ret, "Load / Create test user 2: $msg" );
34 $u2->SetPrivileged(1);
35 $g1 = RT::Group->new($RT::SystemUser);
36 ( $ret, $msg) = $g1->LoadUserDefinedGroup('dg1');
37 unless ($ret) {
38     ( $ret, $msg ) = $g1->CreateUserDefinedGroup( Name => 'dg1' );
39 }
40 ok( $ret, "Load / Create test group 1: $msg" );
41 $g2 = RT::Group->new($RT::SystemUser);
42 ( $ret, $msg) = $g2->LoadUserDefinedGroup('dg2');
43 unless ($ret) {
44     ( $ret, $msg ) = $g2->CreateUserDefinedGroup( Name => 'dg2' );
45 }
46 ok( $ret, "Load / Create test group 2: $msg" );
47 $g3 = RT::Group->new($RT::SystemUser);
48 ( $ret, $msg) = $g3->LoadUserDefinedGroup('dg3');
49 unless ($ret) {
50     ( $ret, $msg ) = $g3->CreateUserDefinedGroup( Name => 'dg3' );
51 }
52 ok( $ret, "Load / Create test group 3: $msg" );
53 $pg1 = RT::Group->new($RT::SystemUser);
54 ( $ret, $msg ) = $pg1->LoadPersonalGroup( Name => 'dpg1',
55                                           User => $u1->PrincipalId );
56 unless ($ret) {
57     ( $ret, $msg ) = $pg1->CreatePersonalGroup( Name => 'dpg1',
58                                                 PrincipalId => $u1->PrincipalId );
59 }
60 ok( $ret, "Load / Create test personal group 1: $msg" );
61 $pg2 = RT::Group->new($RT::SystemUser);
62 ( $ret, $msg ) = $pg2->LoadPersonalGroup( Name => 'dpg2',
63                                           User => $u2->PrincipalId );
64 unless ($ret) {
65     ( $ret, $msg ) = $pg2->CreatePersonalGroup( Name => 'dpg2',
66                                                 PrincipalId => $u2->PrincipalId );
67 }
68 ok( $ret, "Load / Create test personal group 2: $msg" );
69
70
71
72 # Basic case: u has global DelegateRights through g1 and ShowConfigTab
73 # through g2; then u is removed from g1.
74
75 clear_acls_and_groups();
76
77 ( $ret, $msg ) = $g1->PrincipalObj->GrantRight( Right => 'DelegateRights' );
78 ok( $ret, "Grant DelegateRights to g1: $msg" );
79 ( $ret, $msg ) = $g2->PrincipalObj->GrantRight( Right => 'ShowConfigTab' );
80 ok( $ret, "Grant ShowConfigTab to g2: $msg" );
81 ( $ret, $msg ) = $g1->AddMember( $u1->PrincipalId );
82 ok( $ret, "Add test user 1 to g1: $msg" );
83 ok(
84     $u1->PrincipalObj->HasRight(
85         Right  => 'DelegateRights',
86         Object => $RT::System
87     ),
88     "test user 1 has DelegateRights after joining g1"
89 );
90 ( $ret, $msg ) = $g2->AddMember( $u1->PrincipalId );
91 ok( $ret, "Add test user 1 to g2: $msg" );
92 ok(
93     $u1->PrincipalObj->HasRight(
94         Right  => 'ShowConfigTab',
95         Object => $RT::System
96     ),
97     "test user 1 has ShowConfigTab after joining g2"
98 );
99
100 $ace = RT::ACE->new($u1);
101 ( $ret, $msg ) = $ace->LoadByValues(
102     RightName     => 'ShowConfigTab',
103     Object        => $RT::System,
104     PrincipalType => 'Group',
105     PrincipalId   => $g2->PrincipalId
106 );
107 ok( $ret, "Look up ACE to be delegated: $msg" );
108 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
109 ok( $ret, "Delegate ShowConfigTab to pg1: $msg" );
110 ok(
111     $pg1->PrincipalObj->HasRight(
112         Right  => 'ShowConfigTab',
113         Object => $RT::System
114     ),
115     "Test personal group 1 has ShowConfigTab right after delegation"
116 );
117
118 ( $ret, $msg ) = $g1->DeleteMember( $u1->PrincipalId );
119 ok( $ret, "Delete test user 1 from g1: $msg" );
120 ok(
121     not(
122         $pg1->PrincipalObj->HasRight(
123             Right  => 'ShowConfigTab',
124             Object => $RT::System
125         )
126     ),
127     "Test personal group 1 lacks ShowConfigTab right after user removed from g1"
128 );
129
130 # Basic case: u has global DelegateRights through g1 and ShowConfigTab
131 # through g2; then DelegateRights revoked from g1.
132
133 ( $ret, $msg ) = $g1->AddMember( $u1->PrincipalId );
134 ok( $ret, "Add test user 1 to g1: $msg" );
135 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
136 ok( $ret, "Delegate ShowConfigTab to pg1: $msg" );
137 ( $ret, $msg ) = $g1->PrincipalObj->RevokeRight( Right => 'DelegateRights' );
138 ok( $ret, "Revoke DelegateRights from g1: $msg" );
139 ok(
140     not(
141         $pg1->PrincipalObj->HasRight(
142             Right  => 'ShowConfigTab',
143             Object => $RT::System
144         )
145     ),
146     "Test personal group 1 lacks ShowConfigTab right after DelegateRights revoked from g1"
147 );
148
149
150
151 # Corner case - restricted delegation: u has DelegateRights on pg1
152 # through g1 and AdminGroup on pg1 through g2; then DelegateRights
153 # revoked from g1.
154
155 clear_acls_and_groups();
156
157 ( $ret, $msg ) = $g1->PrincipalObj->GrantRight( Right => 'DelegateRights',
158                                                 Object => $pg1);
159 ok( $ret, "Grant DelegateRights on pg1 to g1: $msg" );
160 ( $ret, $msg ) = $g2->PrincipalObj->GrantRight( Right => 'AdminGroup',
161                                                 Object => $pg1);
162 ok( $ret, "Grant AdminGroup on pg1 to g2: $msg" );
163 ( $ret, $msg ) = $g1->AddMember( $u1->PrincipalId );
164 ok( $ret, "Add test user 1 to g1: $msg" );
165 ( $ret, $msg ) = $g2->AddMember( $u1->PrincipalId );
166 ok( $ret, "Add test user 1 to g2: $msg" );
167 ok( $u1->PrincipalObj->HasRight(
168         Right  => 'DelegateRights',
169         Object => $pg1 ),
170     "test user 1 has DelegateRights on pg1 after joining g1" );
171 ok( not( $u1->PrincipalObj->HasRight(
172             Right  => 'DelegateRights',
173             Object => $RT::System )),
174     "Test personal group 1 lacks global DelegateRights after joining g1" );
175 $ace = RT::ACE->new($u1);
176 ( $ret, $msg ) = $ace->LoadByValues(
177     RightName     => 'AdminGroup',
178     Object        => $pg1,
179     PrincipalType => 'Group',
180     PrincipalId   => $g2->PrincipalId
181 );
182 ok( $ret, "Look up ACE to be delegated: $msg" );
183 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
184 ok( $ret, "Delegate AdminGroup on pg1 to pg1: $msg" );
185 ok( $pg1->PrincipalObj->HasRight(
186         Right  => 'AdminGroup',
187         Object => $pg1 ),
188     "Test personal group 1 has AdminGroup right on pg1 after delegation" );
189 ( $ret, $msg ) = $g1->PrincipalObj->RevokeRight ( Right => 'DelegateRights',
190                                                   Object => $pg1 );
191 ok( $ret, "Revoke DelegateRights on pg1 from g1: $msg" );
192 ok( not( $pg1->PrincipalObj->HasRight(
193             Right  => 'AdminGroup',
194             Object => $pg1 )),
195     "Test personal group 1 lacks AdminGroup right on pg1 after DelegateRights revoked from g1" );
196 ( $ret, $msg ) = $g1->PrincipalObj->GrantRight( Right => 'DelegateRights',
197                                                 Object => $pg1);
198
199 # Corner case - restricted delegation: u has DelegateRights on pg1
200 # through g1 and AdminGroup on pg1 through g2; then u removed from g1.
201
202 ok( $ret, "Grant DelegateRights on pg1 to g1: $msg" );
203 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
204 ok( $ret, "Delegate AdminGroup on pg1 to pg1: $msg" );
205 ok( $pg1->PrincipalObj->HasRight(
206         Right  => 'AdminGroup',
207         Object => $pg1 ),
208     "Test personal group 1 has AdminGroup right on pg1 after delegation" );
209 ( $ret, $msg ) = $g1->DeleteMember( $u1->PrincipalId );
210 ok( $ret, "Delete test user 1 from g1: $msg" );
211 ok( not( $pg1->PrincipalObj->HasRight(
212             Right  => 'AdminGroup',
213             Object => $pg1 )),
214     "Test personal group 1 lacks AdminGroup right on pg1 after user removed from g1" );
215
216 clear_acls_and_groups();
217
218
219
220 # Corner case - multiple delegation rights: u has global
221 # DelegateRights directly and DelegateRights on pg1 through g1, and
222 # AdminGroup on pg1 through g2; then u removed from g1 (delegation
223 # should remain); then DelegateRights revoked from u (delegation
224 # should not remain).
225
226 ( $ret, $msg ) = $g1->PrincipalObj->GrantRight( Right => 'DelegateRights',
227                                                 Object => $pg1);
228 ok( $ret, "Grant DelegateRights on pg1 to g1: $msg" );
229 ( $ret, $msg ) = $g2->PrincipalObj->GrantRight( Right => 'AdminGroup',
230                                                 Object => $pg1);
231 ok( $ret, "Grant AdminGroup on pg1 to g2: $msg" );
232 ( $ret, $msg ) = $u1->PrincipalObj->GrantRight( Right => 'DelegateRights',
233                                                Object => $RT::System);
234 ok( $ret, "Grant DelegateRights to user: $msg" );
235 ( $ret, $msg ) = $g1->AddMember( $u1->PrincipalId );
236 ok( $ret, "Add test user 1 to g1: $msg" );
237 ( $ret, $msg ) = $g2->AddMember( $u1->PrincipalId );
238 ok( $ret, "Add test user 1 to g2: $msg" );
239 $ace = RT::ACE->new($u1);
240 ( $ret, $msg ) = $ace->LoadByValues(
241     RightName     => 'AdminGroup',
242     Object        => $pg1,
243     PrincipalType => 'Group',
244     PrincipalId   => $g2->PrincipalId
245 );
246 ok( $ret, "Look up ACE to be delegated: $msg" );
247 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
248 ok( $ret, "Delegate AdminGroup on pg1 to pg1: $msg" );
249 ( $ret, $msg ) = $g1->DeleteMember( $u1->PrincipalId );
250 ok( $ret, "Delete test user 1 from g1: $msg" );
251 ok( $pg1->PrincipalObj->HasRight(Right  => 'AdminGroup',
252                                 Object => $pg1),
253     "Test personal group 1 retains AdminGroup right on pg1 after user removed from g1" );
254 ( $ret, $msg ) = $u1->PrincipalObj->RevokeRight( Right => 'DelegateRights',
255                                                 Object => $RT::System );
256 ok( not ($pg1->PrincipalObj->HasRight(Right  => 'AdminGroup',
257                                      Object => $pg1)),
258     "Test personal group 1 lacks AdminGroup right on pg1 after DelegateRights revoked");
259
260 # Corner case - multiple delegation rights and selectivity: u has
261 # DelegateRights globally and on g2 directly and DelegateRights on pg1
262 # through g1, and AdminGroup on pg1 through g2; then global
263 # DelegateRights revoked from u (delegation should remain),
264 # DelegateRights on g2 revoked from u (delegation should remain), and
265 # u removed from g1 (delegation should not remain).
266
267 ( $ret, $msg ) = $g1->AddMember( $u1->PrincipalId );
268 ok( $ret, "Add test user 1 to g1: $msg" );
269 ( $ret, $msg ) = $u1->PrincipalObj->GrantRight( Right => 'DelegateRights',
270                                                Object => $RT::System);
271 ok( $ret, "Grant DelegateRights to user: $msg" );
272 ( $ret, $msg ) = $u1->PrincipalObj->GrantRight( Right => 'DelegateRights',
273                                                Object => $g2);
274 ok( $ret, "Grant DelegateRights on g2 to user: $msg" );
275 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
276 ok( $ret, "Delegate AdminGroup on pg1 to pg1: $msg" );
277 ( $ret, $msg ) = $u1->PrincipalObj->RevokeRight( Right => 'DelegateRights',
278                                                 Object => $RT::System );
279 ok( $pg1->PrincipalObj->HasRight(Right  => 'AdminGroup',
280                                 Object => $pg1),
281     "Test personal group 1 retains AdminGroup right on pg1 after global DelegateRights revoked" );
282 ( $ret, $msg ) = $u1->PrincipalObj->RevokeRight( Right => 'DelegateRights',
283                                                 Object => $g2 );
284 ok( $pg1->PrincipalObj->HasRight(Right  => 'AdminGroup',
285                                 Object => $pg1),
286     "Test personal group 1 retains AdminGroup right on pg1 after DelegateRights on g2 revoked" );
287 ( $ret, $msg ) = $g1->DeleteMember( $u1->PrincipalId );
288 ok( $ret, "Delete test user 1 from g1: $msg" );
289 ok( not ($pg1->PrincipalObj->HasRight(Right  => 'AdminGroup',
290                                      Object => $pg1)),
291     "Test personal group 1 lacks AdminGroup right on pg1 after user removed from g1");
292
293
294
295 # Corner case - indirect delegation rights: u has DelegateRights
296 # through g1 via g3, and ShowConfigTab via g2; then g3 removed from
297 # g1.
298
299 clear_acls_and_groups();
300
301 ( $ret, $msg ) = $g1->PrincipalObj->GrantRight( Right => 'DelegateRights' );
302 ok( $ret, "Grant DelegateRights to g1: $msg" );
303 ( $ret, $msg ) = $g2->PrincipalObj->GrantRight( Right => 'ShowConfigTab' );
304 ok( $ret, "Grant ShowConfigTab to g2: $msg" );
305 ( $ret, $msg ) = $g1->AddMember( $g3->PrincipalId );
306 ok( $ret, "Add g3 to g1: $msg" );
307 ( $ret, $msg ) = $g3->AddMember( $u1->PrincipalId );
308 ok( $ret, "Add test user 1 to g3: $msg" );
309 ( $ret, $msg ) = $g2->AddMember( $u1->PrincipalId );
310 ok( $ret, "Add test user 1 to g2: $msg" );
311
312 $ace = RT::ACE->new($u1);
313 ( $ret, $msg ) = $ace->LoadByValues(
314     RightName     => 'ShowConfigTab',
315     Object        => $RT::System,
316     PrincipalType => 'Group',
317     PrincipalId   => $g2->PrincipalId
318 );
319 ok( $ret, "Look up ACE to be delegated: $msg" );
320 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
321 ok( $ret, "Delegate ShowConfigTab to pg1: $msg" );
322
323 ( $ret, $msg ) = $g1->DeleteMember( $g3->PrincipalId );
324 ok( $ret, "Delete g3 from g1: $msg" );
325 ok( not ($pg1->PrincipalObj->HasRight(Right  => 'ShowConfigTab',
326                                      Object => $RT::System)),
327          "Test personal group 1 lacks ShowConfigTab right after g3 removed from g1");
328
329 # Corner case - indirect delegation rights: u has DelegateRights
330 # through g1 via g3, and ShowConfigTab via g2; then DelegateRights
331 # revoked from g1.
332
333 ( $ret, $msg ) = $g1->AddMember( $g3->PrincipalId );
334 ok( $ret, "Add g3 to g1: $msg" );
335 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
336 ok( $ret, "Delegate ShowConfigTab to pg1: $msg" );
337 ( $ret, $msg ) = $g1->PrincipalObj->RevokeRight ( Right => 'DelegateRights' );
338 ok( $ret, "Revoke DelegateRights from g1: $msg" );
339
340 ok( not ($pg1->PrincipalObj->HasRight(Right  => 'ShowConfigTab',
341                                      Object => $RT::System)),
342          "Test personal group 1 lacks ShowConfigTab right after DelegateRights revoked from g1");
343
344
345
346 # Corner case - delegation of DelegateRights: u1 has DelegateRights
347 # via g1 and delegates DelegateRights to pg1; u2 has DelegateRights
348 # via pg1 and ShowConfigTab via g2; then u1 removed from g1.
349
350 clear_acls_and_groups();
351
352 ( $ret, $msg ) = $g1->PrincipalObj->GrantRight( Right => 'DelegateRights' );
353 ok( $ret, "Grant DelegateRights to g1: $msg" );
354 ( $ret, $msg ) = $g2->PrincipalObj->GrantRight( Right => 'ShowConfigTab' );
355 ok( $ret, "Grant ShowConfigTab to g2: $msg" );
356 ( $ret, $msg ) = $g1->AddMember( $u1->PrincipalId );
357 ok( $ret, "Add test user 1 to g1: $msg" );
358 $ace = RT::ACE->new($u1);
359 ( $ret, $msg ) = $ace->LoadByValues(
360     RightName     => 'DelegateRights',
361     Object        => $RT::System,
362     PrincipalType => 'Group',
363     PrincipalId   => $g1->PrincipalId
364 );
365 ok( $ret, "Look up ACE to be delegated: $msg" );
366 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
367 ok( $ret, "Delegate DelegateRights to pg1: $msg" );
368
369 ( $ret, $msg ) = $pg1->AddMember( $u2->PrincipalId );
370 ok( $ret, "Add test user 2 to pg1: $msg" );
371 ( $ret, $msg ) = $g2->AddMember( $u2->PrincipalId );
372 ok( $ret, "Add test user 2 to g2: $msg" );
373 $ace = RT::ACE->new($u2);
374 ( $ret, $msg ) = $ace->LoadByValues(
375     RightName     => 'ShowConfigTab',
376     Object        => $RT::System,
377     PrincipalType => 'Group',
378     PrincipalId   => $g2->PrincipalId
379 );
380 ok( $ret, "Look up ACE to be delegated: $msg" );
381 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg2->PrincipalId );
382 ok( $ret, "Delegate ShowConfigTab to pg2: $msg" );
383
384 ok( $pg2->PrincipalObj->HasRight(Right  => 'ShowConfigTab',
385                                  Object => $RT::System),
386     "Test personal group 2 has ShowConfigTab right after delegation");
387 ( $ret, $msg ) = $g1->DeleteMember( $u1->PrincipalId );
388 ok( $ret, "Delete u1 from g1: $msg" );
389 ok( not ($pg2->PrincipalObj->HasRight(Right  => 'ShowConfigTab',
390                                       Object => $RT::System)),
391          "Test personal group 2 lacks ShowConfigTab right after u1 removed from g1");
392
393 # Corner case - delegation of DelegateRights: u1 has DelegateRights
394 # via g1 and delegates DelegateRights to pg1; u2 has DelegateRights
395 # via pg1 and ShowConfigTab via g2; then DelegateRights revoked from
396 # g1.
397
398 ( $ret, $msg ) = $g1->AddMember( $u1->PrincipalId );
399 ok( $ret, "Add u1 to g1: $msg" );
400 $ace = RT::ACE->new($u1);
401 ( $ret, $msg ) = $ace->LoadByValues(
402     RightName     => 'DelegateRights',
403     Object        => $RT::System,
404     PrincipalType => 'Group',
405     PrincipalId   => $g1->PrincipalId
406 );
407 ok( $ret, "Look up ACE to be delegated: $msg" );
408 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg1->PrincipalId );
409 ok( $ret, "Delegate DelegateRights to pg1: $msg" );
410 $ace = RT::ACE->new($u2);
411 ( $ret, $msg ) = $ace->LoadByValues(
412     RightName     => 'ShowConfigTab',
413     Object        => $RT::System,
414     PrincipalType => 'Group',
415     PrincipalId   => $g2->PrincipalId
416 );
417 ok( $ret, "Look up ACE to be delegated: $msg" );
418 ( $ret, $msg ) = $ace->Delegate( PrincipalId => $pg2->PrincipalId );
419 ok( $ret, "Delegate ShowConfigTab to pg2: $msg" );
420
421 ( $ret, $msg ) = $g1->PrincipalObj->RevokeRight ( Right => 'DelegateRights' );
422 ok( $ret, "Revoke DelegateRights from g1: $msg" );
423 ok( not ($pg2->PrincipalObj->HasRight(Right  => 'ShowConfigTab',
424                                       Object => $RT::System)),
425          "Test personal group 2 lacks ShowConfigTab right after DelegateRights revoked from g1");
426
427
428
429
430 #######
431
432 sub clear_acls_and_groups {
433     # Revoke all rights granted to our cast
434     my $acl = RT::ACL->new($RT::SystemUser);
435     foreach (@principals) {
436         $acl->LimitToPrincipal(Type => $$_->PrincipalObj->PrincipalType,
437                                Id => $$_->PrincipalObj->Id);
438     }
439     while (my $ace = $acl->Next()) {
440         $ace->Delete();
441     }
442
443     # Remove all group memberships
444     my $members = RT::GroupMembers->new($RT::SystemUser);
445     foreach (@groups) {
446         $members->LimitToMembersOfGroup( $$_->PrincipalId );
447     }
448     while (my $member = $members->Next()) {
449         $member->Delete();
450     }
451
452     $acl->RedoSearch();
453     ok( $acl->Count() == 0,
454        "All principals have no rights after clearing ACLs" );
455     $members->RedoSearch();
456     ok( $members->Count() == 0,
457        "All groups have no members after clearing groups" );
458 }