RT 4.2.11, ticket#13852
[freeside.git] / rt / t / api / group-rights.t
1 use strict;
2 use warnings;
3 use RT::Test nodata => 1, tests => 114;
4
5 RT::Group->AddRight( General =>
6     'RTxGroupRight' => 'Just a right for testing rights',
7 );
8
9 # this company is split into two halves, the hackers and the non-hackers
10 # herbert is a hacker but eric is not.
11 my $herbert = RT::User->new(RT->SystemUser);
12 my ($ok, $msg) = $herbert->Create(Name => 'herbert');
13 ok($ok, $msg);
14
15 my $eric = RT::User->new(RT->SystemUser);
16 ($ok, $msg) = $eric->Create(Name => 'eric');
17 ok($ok, $msg);
18
19 my $hackers = RT::Group->new(RT->SystemUser);
20 ($ok, $msg) = $hackers->CreateUserDefinedGroup(Name => 'Hackers');
21 ok($ok, $msg);
22
23 my $employees = RT::Group->new(RT->SystemUser);
24 ($ok, $msg) = $employees->CreateUserDefinedGroup(Name => 'Employees');
25 ok($ok, $msg);
26
27 ($ok, $msg) = $employees->AddMember($hackers->PrincipalId);
28 ok($ok, $msg);
29
30 ($ok, $msg) = $hackers->AddMember($herbert->PrincipalId);
31 ok($ok, $msg);
32
33 ($ok, $msg) = $employees->AddMember($eric->PrincipalId);
34 ok($ok, $msg);
35
36 ok($employees->HasMemberRecursively($hackers->PrincipalId), 'employees has member hackers');
37 ok($employees->HasMemberRecursively($herbert->PrincipalId), 'employees has member herbert');
38 ok($employees->HasMemberRecursively($eric->PrincipalId), 'employees has member eric');
39
40 ok($hackers->HasMemberRecursively($herbert->PrincipalId), 'hackers has member herbert');
41 ok(!$hackers->HasMemberRecursively($eric->PrincipalId), 'hackers does not have member eric');
42
43 # There's also a separate group, "Other", which both are a member of.
44 my $other = RT::Group->new(RT->SystemUser);
45 ($ok, $msg) = $other->CreateUserDefinedGroup(Name => 'Other');
46 ok($ok, $msg);
47 ($ok, $msg) = $other->AddMember($eric->PrincipalId);
48 ok($ok, $msg);
49 ($ok, $msg) = $other->AddMember($herbert->PrincipalId);
50 ok($ok, $msg);
51
52
53 # Everyone can SeeGroup on all three groups
54 my $everyone = RT::Group->new( RT->SystemUser );
55 ($ok, $msg) = $everyone->LoadSystemInternalGroup( 'Everyone' );
56 ok($ok, $msg);
57 $everyone->PrincipalObj->GrantRight(Right => 'SeeGroup', Object => $employees);
58 $everyone->PrincipalObj->GrantRight(Right => 'SeeGroup', Object => $hackers);
59 $everyone->PrincipalObj->GrantRight(Right => 'SeeGroup', Object => $other);
60
61 sub CheckRights {
62     my $cu = shift;
63     my %groups = (Employees => 0, Hackers => 0, Other => 0, @_);
64     my $name = $cu->Name;
65
66     my $groups = RT::Groups->new(RT::CurrentUser->new($cu));
67     $groups->LimitToUserDefinedGroups;
68     $groups->ForWhichCurrentUserHasRight(Right => 'RTxGroupRight');
69     my %has_right = map { ($_->Name => 1) } @{ $groups->ItemsArrayRef };
70
71     local $Test::Builder::Level = $Test::Builder::Level + 1;
72     for my $groupname (sort keys %groups) {
73         my $g = RT::Group->new(RT::CurrentUser->new($cu));
74         $g->LoadUserDefinedGroup($groupname);
75         if ($groups{$groupname}) {
76             ok( $g->CurrentUserHasRight("RTxGroupRight"), "$name has right on $groupname (direct query)" );
77             ok( delete $has_right{$groupname},            "..and also in ForWhichCurrentUserHasRight");
78         } else {
79             ok( !$g->CurrentUserHasRight("RTxGroupRight"), "$name doesn't have right on $groupname (direct query)" );
80             ok( !delete $has_right{$groupname},            "..and also not in ForWhichCurrentUserHasRight");
81         }
82     }
83     ok(not(keys %has_right), "ForWhichCurrentUserHasRight has no extra groups");
84 }
85
86 # Neither should have it on any group yet
87 CheckRights($eric);
88 CheckRights($herbert);
89
90
91 # Grant it to employees, on employees.  Both Herbert and Eric will have
92 # it on employees, though Herbert gets it by way of hackers.  Neither
93 # will have it on hackers, because the target does not recurse.
94 $employees->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => $employees);
95 CheckRights($eric,    Employees => 1);
96 CheckRights($herbert, Employees => 1);
97
98
99 # Grant it to employees, on hackers.  This means both Eric and Herbert
100 # will have the right on hackers, but not on employees.
101 $employees->PrincipalObj->RevokeRight(Right => 'RTxGroupRight', Object => $employees);
102 $employees->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => $hackers);
103 CheckRights($eric,    Hackers => 1);
104 CheckRights($herbert, Hackers => 1);
105
106
107 # Grant it to hackers, on employees.  Eric will have it nowhere, and
108 # Herbert will have it on employees.  Note that the target of the right
109 # itself does _not_ recurse down, so Herbert will not have it on
110 # hackers.
111 $employees->PrincipalObj->RevokeRight(Right => 'RTxGroupRight', Object => $hackers);
112 $hackers->PrincipalObj->GrantRight(   Right => 'RTxGroupRight', Object => $employees);
113 CheckRights($eric);
114 CheckRights($herbert, Employees => 1);
115
116
117 # Grant it globally to hackers; herbert will see the right on all
118 # employees, hackers, and other.
119 $hackers->PrincipalObj->RevokeRight(  Right => 'RTxGroupRight', Object => $employees);
120 $hackers->PrincipalObj->GrantRight(   Right => 'RTxGroupRight', Object => RT->System);
121 CheckRights($eric);
122 CheckRights($herbert, Employees => 1, Hackers => 1, Other => 1 );
123
124
125 # Grant it globally to employees; both eric and herbert will see the
126 # right on all employees, hackers, and other.
127 $hackers->PrincipalObj->RevokeRight(  Right => 'RTxGroupRight', Object => RT->System);
128 $employees->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => RT->System);
129 CheckRights($eric,    Employees => 1, Hackers => 1, Other => 1 );
130 CheckRights($herbert, Employees => 1, Hackers => 1, Other => 1 );
131
132
133 # Disable the employees group.  Neither eric nor herbert will see the
134 # right anywhere.
135 $employees->SetDisabled(1);
136 CheckRights($eric);
137 CheckRights($herbert);