4 use RT::Test nodata => 1, tests => 64;
5 my ($baseurl, $m) = RT::Test->started_ok;
7 my $url = $m->rt_base_url;
9 # create user and queue
10 my $user_obj = RT::User->new(RT->SystemUser);
11 my ($ok, $msg) = $user_obj->LoadOrCreateByEmail('customer@example.com');
12 ok($ok, 'ACL test user creation');
13 $user_obj->SetName('customer');
14 $user_obj->SetPrivileged(1);
15 ($ok, $msg) = $user_obj->SetPassword('customer');
16 $user_obj->PrincipalObj->GrantRight(Right => 'ModifySelf');
17 my $currentuser = RT::CurrentUser->new($user_obj);
19 my $queue = RT::Queue->new(RT->SystemUser);
20 $queue->Create(Name => 'SearchQueue'.$$);
22 $user_obj->PrincipalObj->GrantRight(Right => $_, Object => $queue)
23 for qw/SeeQueue ShowTicket OwnTicket/;
25 # grant the user all these rights so we can make sure that the group rights
26 # are checked and not these as well
27 $user_obj->PrincipalObj->GrantRight(Right => $_, Object => $RT::System)
28 for qw/SubscribeDashboard CreateOwnDashboard SeeOwnDashboard ModifyOwnDashboard DeleteOwnDashboard/;
29 # create and test groups (outer < inner < user)
30 my $inner_group = RT::Group->new(RT->SystemUser);
31 ($ok, $msg) = $inner_group->CreateUserDefinedGroup(Name => "inner", Description => "inner group");
32 ok($ok, "created inner group: $msg");
34 my $outer_group = RT::Group->new(RT->SystemUser);
35 ($ok, $msg) = $outer_group->CreateUserDefinedGroup(Name => "outer", Description => "outer group");
36 ok($ok, "created outer group: $msg");
38 ($ok, $msg) = $outer_group->AddMember($inner_group->PrincipalId);
39 ok($ok, "added inner as a member of outer: $msg");
41 ($ok, $msg) = $inner_group->AddMember($user_obj->PrincipalId);
42 ok($ok, "added user as a member of member: $msg");
44 ok($outer_group->HasMember($inner_group->PrincipalId), "outer has inner");
45 ok(!$outer_group->HasMember($user_obj->PrincipalId), "outer doesn't have user directly");
46 ok($outer_group->HasMemberRecursively($inner_group->PrincipalId), "outer has inner recursively");
47 ok($outer_group->HasMemberRecursively($user_obj->PrincipalId), "outer has user recursively");
49 ok(!$inner_group->HasMember($outer_group->PrincipalId), "inner doesn't have outer");
50 ok($inner_group->HasMember($user_obj->PrincipalId), "inner has user");
51 ok(!$inner_group->HasMemberRecursively($outer_group->PrincipalId), "inner doesn't have outer, even recursively");
52 ok($inner_group->HasMemberRecursively($user_obj->PrincipalId), "inner has user recursively");
54 ok $m->login(customer => 'customer'), "logged in";
57 $m->follow_link_ok({ id => 'home-dashboard_create'});
58 $m->form_name('ModifyDashboard');
59 is_deeply([$m->current_form->find_input('Privacy')->possible_values], ["RT::User-" . $user_obj->Id], "the only selectable privacy is user");
60 $m->content_lacks('Delete', "Delete button hidden because we are creating");
62 $user_obj->PrincipalObj->GrantRight(Right => 'CreateGroupDashboard', Object => $inner_group);
64 $m->follow_link_ok({ id => 'home-dashboard_create'});
65 $m->form_name('ModifyDashboard');
66 is_deeply([$m->current_form->find_input('Privacy')->possible_values], ["RT::User-" . $user_obj->Id, "RT::Group-" . $inner_group->Id], "the only selectable privacies are user and inner group (not outer group)");
67 $m->field("Name" => 'broken dashboard');
68 $m->field("Privacy" => "RT::Group-" . $inner_group->Id);
69 $m->content_lacks('Delete', "Delete button hidden because we are creating");
70 $m->click_button(value => 'Create');
71 $m->content_contains("saved", "we lack SeeGroupDashboard, so we end up back at the index.");
73 $user_obj->PrincipalObj->GrantRight(
74 Right => 'SeeGroupDashboard',
75 Object => $inner_group,
77 $m->follow_link_ok({ id => 'home-dashboard_create'});
78 $m->form_name('ModifyDashboard');
79 $m->field("Name" => 'inner dashboard');
80 $m->field("Privacy" => "RT::Group-" . $inner_group->Id);
81 $m->click_button(value => 'Create');
82 $m->content_lacks("Permission Denied", "we now have SeeGroupDashboard");
83 $m->content_contains("Saved dashboard inner dashboard");
84 $m->content_lacks('Delete', "Delete button hidden because we lack DeleteDashboard");
86 my $dashboard = RT::Dashboard->new($currentuser);
87 my ($id) = $m->content =~ /name="id" value="(\d+)"/;
88 ok($id, "got an ID, $id");
89 $dashboard->LoadById($id);
90 is($dashboard->Name, "inner dashboard");
92 is($dashboard->Privacy, 'RT::Group-' . $inner_group->Id, "correct privacy");
93 is($dashboard->PossibleHiddenSearches, 0, "all searches are visible");
96 $m->get_ok("/Dashboards/Modify.html?id=$id");
97 $m->content_contains("inner dashboard", "we now have SeeGroupDashboard right");
98 $m->content_lacks("Permission Denied");
99 $m->content_contains('Subscription', "Subscription link not hidden because we have SubscribeDashboard");
102 $m->get_ok("/Dashboards/index.html");
103 $m->content_contains("inner dashboard", "We can see the inner dashboard from the UI");
105 $m->get_ok("/Prefs/DashboardsInMenu.html");
106 $m->content_contains("inner dashboard", "Can also see it in the menu options");
108 my ($group) = grep {$_->isa("RT::Group") and $_->Id == $inner_group->Id}
109 RT::Dashboard->new($currentuser)->_PrivacyObjects;
110 ok($group, "Found the group in the privacy objects list");
112 my @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
115 ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id],
116 "We can load from ourselves (SeeOwnDashboard) and a group we are with SeeGroupDashboard"
119 # If you are granted SeeGroupDashboard globally, you can only see
120 # dashboards in groups you are in.
121 $user_obj->PrincipalObj->RevokeRight(
122 Right => 'SeeGroupDashboard',
123 Object => $inner_group,
125 $user_obj->PrincipalObj->GrantRight(
126 Right => 'SeeGroupDashboard',
127 Object => RT->System,
129 $m->get_ok("/Dashboards/index.html");
130 $m->content_contains("inner dashboard", "Having SeeGroupDashboard gobally is fine for groups you are in");
131 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
134 ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id],
135 "SeeGroupDashboard globally still works for groups you are in"
138 $inner_group->DeleteMember($user_obj->PrincipalObj->Id);
139 ok(!$outer_group->HasMemberRecursively($user_obj->PrincipalId), "outer no longer has user recursively");
140 ok(!$inner_group->HasMemberRecursively($user_obj->PrincipalId), "inner no longer has user recursively");
141 $m->get_ok("/Dashboards/index.html");
142 $m->content_lacks("inner dashboard", "But global SeeGroupDashboard isn't enough for other groups");
144 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
147 ["RT::User-".$user_obj->Id],
148 "We only have our SeeOwnDashboard right, as we are no longer in inner"
151 # Similarly, if you're a SuperUser, you still only see dashboards for
152 # groups you belong to
153 $user_obj->PrincipalObj->RevokeRight(
154 Right => 'SeeGroupDashboard',
155 Object => RT->System,
157 $user_obj->PrincipalObj->GrantRight(
158 Right => 'SuperUser',
159 Object => RT->System,
161 $m->get_ok("/Dashboards/index.html");
162 $m->content_lacks("inner dashboard", "Superuser can't see dashboards in groups they're not in");
163 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
166 ["RT::User-".$user_obj->Id, "RT::System-1"],
167 "We pick up the system-level SeeDashboard right from superuser"
169 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading(IncludeSuperuserGroups => 0);
172 ["RT::User-".$user_obj->Id, "RT::System-1"],
173 "IncludeSuperusers only cuts out _group_ dashboard objects for loading, not user and system ones"
176 $inner_group->AddMember($user_obj->PrincipalId);
177 $m->get_ok("/Dashboards/index.html");
178 $m->content_contains("inner dashboard", "Superuser can see dashboards in groups they are in");
179 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
182 ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id, "RT::System-1"],
183 "Becoming a member of the group makes it a possibility"
185 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading(IncludeSuperuserGroups => 0);
188 ["RT::User-".$user_obj->Id, "RT::System-1"],
189 "But only via superuser"
192 $m->get_ok("/Dashboards/index.html");
193 $m->content_contains("inner dashboard", "The dashboards list includes superuser rights");
194 $m->get_ok("/Prefs/DashboardsInMenu.html");
195 $m->content_lacks("inner dashboard", "But the menu skips them");