diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in index 795fced00c1..a0a5899a818 100644 --- a/etc/RT_Config.pm.in +++ b/etc/RT_Config.pm.in @@ -1855,6 +1855,18 @@ will be able to search all your users. Set($AllowUserAutocompleteForUnprivileged, 0); +=item C<$AllowGroupAutocompleteForUnprivileged> + +Defines whether unprivileged users (users of SelfService) are allowed +to autocomplete groups for roles like Requestors or Ccs. Setting this +option to 1 enables autocomplete on user-created group names for self +service users. Users also need the SeeGroup right on each +group for them to appear in the autocomplete suggestions. + +=cut + +Set($AllowGroupAutocompleteForUnprivileged, 0); + =item C<$DefaultSelfServiceSearchResultFormat> C<$DefaultSelfServiceSearchResultFormat> is the default format of diff --git a/share/html/Helpers/Autocomplete/Principals b/share/html/Helpers/Autocomplete/Principals index c403b39a1fd..c455f245816 100644 --- a/share/html/Helpers/Autocomplete/Principals +++ b/share/html/Helpers/Autocomplete/Principals @@ -84,7 +84,8 @@ my $CurrentUser = $session{'CurrentUser'}; # Require privileged users or overriding config $m->abort unless $CurrentUser->Privileged - or RT->Config->Get('AllowUserAutocompleteForUnprivileged'); + or RT->Config->Get('AllowUserAutocompleteForUnprivileged') + or RT->Config->Get('AllowGroupAutocompleteForUnprivileged'); # the API wants a list of ids my @exclude = split /\s*,\s*/, $exclude; @@ -94,65 +95,77 @@ push @exclude, RT->Nobody->id unless $include_nobody; $m->callback( CallbackName => 'ModifyMaxResults', max => \$max ); $max //= 10; -my $users = RT::Users->new($CurrentUser); -$users->SimpleSearch( Privileged => $privileged, - Return => 'Name', - Term => $term, - Max => $max, - Exclude => \@exclude, - ); +my ( $users, $groups ); + +if ( $CurrentUser->Privileged or RT->Config->Get('AllowUserAutocompleteForUnprivileged') ) { + $users = RT::Users->new($CurrentUser); + $users->SimpleSearch( + Privileged => $privileged, + Return => 'Name', + Term => $term, + Max => $max, + Exclude => \@exclude, + ); +} + $m->callback( CallbackName => "ModifyUsersLimit", Users => $users, Term => $term, ARGSRef => \%ARGS, CallbackPage => '/Helpers/Autocomplete/Users' ); $m->callback( CallbackName => "ModifyUsersLimit", Users => $users, Term => $term, ARGSRef => \%ARGS ); -(my $group_term = $term) =~ s/^\s*group\s*:\s*//i; -my $groups = RT::Groups->new( $CurrentUser ); -$groups->RowsPerPage( $max ); -$groups->LimitToUserDefinedGroups(); -$groups->Limit( - FIELD => 'Name', - OPERATOR => 'STARTSWITH', - VALUE => $group_term, - CASESENSITIVE => 0, -); +if ( $CurrentUser->Privileged or RT->Config->Get('AllowGroupAutocompleteForUnprivileged') ) { + ( my $group_term = $term ) =~ s/^\s*group\s*:\s*//i; + $groups = RT::Groups->new($CurrentUser); + $groups->RowsPerPage($max); + $groups->LimitToUserDefinedGroups(); + $groups->Limit( + FIELD => 'Name', + OPERATOR => 'STARTSWITH', + VALUE => $group_term, + CASESENSITIVE => 0, + ); -# Exclude groups we don't want -foreach (@exclude) { - $groups->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=', ENTRYAGGREGATOR => 'AND'); + # Exclude groups we don't want + foreach (@exclude) { + $groups->Limit( FIELD => 'id', VALUE => $_, OPERATOR => '!=', ENTRYAGGREGATOR => 'AND' ); + } } $m->callback( CallbackName => "ModifyGroupsLimit", Groups => $groups, Term => $term, ARGSRef => \%ARGS, CallbackPage => '/Helpers/Autocomplete/Groups' ); $m->callback( CallbackName => "ModifyGroupsLimit", Groups => $groups, Term => $term, ARGSRef => \%ARGS ); my @suggestions; -while ( my $user = $users->Next ) { - my $suggestion = { id => $user->id, label => $user->Format, value => $user->EmailAddress || $user->Name }; - $m->callback( - CallbackName => "ModifySuggestion", - suggestion => $suggestion, - user => $user, - CallbackPage => '/Helpers/Autocomplete/Users', - ); - $m->callback( CallbackName => "ModifySuggestion", suggestion => $suggestion, user => $user ); - push @suggestions, $suggestion; +if ($users) { + while ( my $user = $users->Next ) { + my $suggestion = { id => $user->id, label => $user->Format, value => $user->EmailAddress || $user->Name }; + $m->callback( + CallbackName => "ModifySuggestion", + suggestion => $suggestion, + user => $user, + CallbackPage => '/Helpers/Autocomplete/Users', + ); + $m->callback( CallbackName => "ModifySuggestion", suggestion => $suggestion, user => $user ); + push @suggestions, $suggestion; + } } -while ( my $group = $groups->Next ) { - my $label = 'group:' . $group->Name; - - # if group name contains, say, a comma, then use its id instead to avoid - # parsing problems - my $value = $delim && $label =~ $delim ? 'group:' . $group->id : $label; - - my $suggestion = { id => $group->id, label => $label, value => $value }; - $m->callback( - CallbackName => "ModifySuggestion", - suggestion => $suggestion, - group => $group, - CallbackPage => '/Helpers/Autocomplete/Groups', - ); - $m->callback( CallbackName => "ModifySuggestion", suggestion => $suggestion, group => $group ); - push @suggestions, $suggestion; - - last if @suggestions >= $max; +if ($groups) { + while ( my $group = $groups->Next ) { + my $label = 'group:' . $group->Name; + + # if group name contains, say, a comma, then use its id instead to avoid + # parsing problems + my $value = $delim && $label =~ $delim ? 'group:' . $group->id : $label; + + my $suggestion = { id => $group->id, label => $label, value => $value }; + $m->callback( + CallbackName => "ModifySuggestion", + suggestion => $suggestion, + group => $group, + CallbackPage => '/Helpers/Autocomplete/Groups', + ); + $m->callback( CallbackName => "ModifySuggestion", suggestion => $suggestion, group => $group ); + push @suggestions, $suggestion; + + last if @suggestions >= $max; + } } diff --git a/share/html/SelfService/Helpers/Autocomplete/Principals b/share/html/SelfService/Helpers/Autocomplete/Principals new file mode 100644 index 00000000000..ff1277fa5d6 --- /dev/null +++ b/share/html/SelfService/Helpers/Autocomplete/Principals @@ -0,0 +1,48 @@ +%# BEGIN BPS TAGGED BLOCK {{{ +%# +%# COPYRIGHT: +%# +%# This software is Copyright (c) 1996-2019 Best Practical Solutions, LLC +%# +%# +%# (Except where explicitly superseded by other copyright notices) +%# +%# +%# LICENSE: +%# +%# This work is made available to you under the terms of Version 2 of +%# the GNU General Public License. A copy of that license should have +%# been provided with this software, but in any event can be snarfed +%# from www.gnu.org. +%# +%# This work is distributed in the hope that it will be useful, but +%# WITHOUT ANY WARRANTY; without even the implied warranty of +%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%# General Public License for more details. +%# +%# You should have received a copy of the GNU General Public License +%# along with this program; if not, write to the Free Software +%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +%# 02110-1301 or visit their web page on the internet at +%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +%# +%# +%# CONTRIBUTION SUBMISSION POLICY: +%# +%# (The following paragraph is not intended to limit the rights granted +%# to you to modify and distribute this software under the terms of +%# the GNU General Public License and is only of importance to you if +%# you choose to contribute your changes and enhancements to the +%# community by submitting them to Best Practical Solutions, LLC.) +%# +%# By intentionally submitting any modifications, corrections or +%# derivatives to this work, or any other work intended for use with +%# Request Tracker, to Best Practical Solutions, LLC, you confirm that +%# you are the copyright holder for those contributions and you grant +%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +%# royalty-free, perpetual, license to use, copy, create derivative +%# works based on those contributions, and sublicense and distribute +%# those contributions and any derivatives thereof. +%# +%# END BPS TAGGED BLOCK }}} +% $m->comp('/Helpers/Autocomplete/Principals', %ARGS);