Limit queues by right ModifyTicket also for SuperUser

Hi,

our users have ShowQueue (together with ShowTicket) on many queues and
ModifyTicket on few queues. This results in a long list of queues in the
" Quick search" element.

To help our users to have a better overview of the queues they manage
(where they have ModifyTicket), I wanted to create a MyQueues element
which only list the queues where the users have the ModifyTicket right.

For normal users this is easy by using the
/Elements/QueueSummaryByStatus with “sub {
$_->CurrentUserHasRight(‘ModifyTicket’) }” as queue_filter.

Sadly this doesn’t work for SuperUser as they have ModifyTicket on all
queues by the SuperUser right [1].

Is there any way to limit the queues also for SuperUser to ones that
they have the ModifyTicket right?

Chris

[1] rt/Principal.pm at stable · bestpractical/rt · GitHub

2015/05/19 8:17、Christian Loos cloos@netcologne.de のメール:

Hi,

Hi Christian,

our users have ShowQueue (together with ShowTicket) on many queues and
ModifyTicket on few queues. This results in a long list of queues in the
" Quick search" element.

To help our users to have a better overview of the queues they manage
(where they have ModifyTicket), I wanted to create a MyQueues element
which only list the queues where the users have the ModifyTicket right.

Just in case you missed it, a user can hide queues from that list by clicking the “edit” link next to the “Quick search” header. But I understand if that isn’t going to do it for you. :slight_smile:

For normal users this is easy by using the
/Elements/QueueSummaryByStatus with “sub {
$_->CurrentUserHasRight(‘ModifyTicket’) }” as queue_filter.

Sadly this doesn’t work for SuperUser as they have ModifyTicket on all
queues by the SuperUser right [1].

Is there any way to limit the queues also for SuperUser to ones that
they have the ModifyTicket right?

The first place to check is the code that supports the admin UI for editing a user’s rights. Since SuperUser doesn’t automatically check every checkbox, there must be code that looks at the rights more closely than ->HasRight() to decide what to display. And sure enough there is:

share/html/Admin/Elements/EditRightsCategoryTabs:

Find all the current rights for this principal

my %current_rights;
if ($Principal) {
my $acls = RT::ACL->new($session{‘CurrentUser’});
$acls->LimitToObject( $Context );
$acls->LimitToPrincipal( Id => $Principal->PrincipalId );

while ( my $ace = $acls->Next ) {
    my $right = $ace->RightName;
    $current_rights{$right} = 1;
}

}

This iterates over all the rights granted only to the specific principal, so it does not handle rights granted by group membership, either directly, or recursively. You can use the cached group members table (RT::CachedGroupMembers) to iterate over a user’s recursive group memberships to limit the RT::ACL search down. And of course you can limit the ACL you care about to just ModifyTicket instead of iterating over all of those.

It’s probably about twenty lines of code. I hope there aren’t too many corner cases… like what if the user has ModifyTicket only due to being an AdminCc? Also I’m not sure how slow it’ll be for your system: rights is one place RT does some careful caching. Please let us know how it goes!

Chris

Cheers,
Shawn

signature.asc (801 Bytes)

The first place to check is the code that supports the admin UI for editing a user’s rights. Since SuperUser doesn’t automatically check every checkbox, there must be code that looks at the rights more closely than ->HasRight() to decide what to display. And sure enough there is:

share/html/Admin/Elements/EditRightsCategoryTabs:

Find all the current rights for this principal

my %current_rights;
if ($Principal) {
my $acls = RT::ACL->new($session{‘CurrentUser’});
$acls->LimitToObject( $Context );
$acls->LimitToPrincipal( Id => $Principal->PrincipalId );

while ( my $ace = $acls->Next ) {
    my $right = $ace->RightName;
    $current_rights{$right} = 1;
}

}

This iterates over all the rights granted only to the specific principal, so it does not handle rights granted by group membership, either directly, or recursively. You can use the cached group members table (RT::CachedGroupMembers) to iterate over a user’s recursive group memberships to limit the RT::ACL search down. And of course you can limit the ACL you care about to just ModifyTicket instead of iterating over all of those.

It’s probably about twenty lines of code. I hope there aren’t too many corner cases… like what if the user has ModifyTicket only due to being an AdminCc? Also I’m not sure how slow it’ll be for your system: rights is one place RT does some careful caching. Please let us know how it goes!

I actually found the IncludeGroupMembership option for LimitToPrincipal
and my queue_filter looks like this:

my $queue = shift;
if ($session{CurrentUser}->HasRight(Right => ‘SuperUser’, Object =>
RT->System)) {
my $acls = RT::ACL->new($session{CurrentUser});
$acls->LimitToObject($queue);
$acls->Limit(FIELD => ‘RightName’, VALUE => ‘ModifyTicket’);
$acls->LimitToPrincipal(
Id => $session{CurrentUser}->PrincipalId,
IncludeGroupMembership => 1,
);
return $acls->Count;
} else {
return $queue->CurrentUserHasRight(‘ModifyTicket’);
}

Thanks for the hint.

Chris