[Rt-commit] rt branch, 4.4/reduce-cached-ticket-role-group-members, updated. rt-4.4.4-16-g9d8eb13de8

? sunnavy sunnavy at bestpractical.com
Fri Nov 1 13:44:22 EDT 2019


The branch, 4.4/reduce-cached-ticket-role-group-members has been updated
       via  9d8eb13de87cbe306b66ab70431db18c723b4658 (commit)
      from  b6b5e65bd680742fa1b0b99f8f8ec92645c85d9e (commit)

Summary of changes:
 lib/RT/Interface/Web/QueryBuilder/Tree.pm  |  4 ++
 lib/RT/SQL.pm                              |  2 +-
 lib/RT/SearchBuilder.pm                    |  4 +-
 lib/RT/SearchBuilder/Role/Roles.pm         | 66 +++++++++++++++++++-----------
 share/html/Elements/SelectMatch            | 21 ++++++++--
 share/html/Search/Elements/PickBasics      |  1 +
 share/html/Search/Elements/PickCustomRoles |  1 +
 7 files changed, 68 insertions(+), 31 deletions(-)

- Log -----------------------------------------------------------------
commit 9d8eb13de87cbe306b66ab70431db18c723b4658
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Oct 26 02:52:33 2019 +0800

    Support shallow searches for ticket roles
    
    As user defined groups could be added to ticket roles, sometimes people
    want to search users that are directly added to ticket roles instead of
    via user defined groups, which shallow searches are right for.

diff --git a/lib/RT/Interface/Web/QueryBuilder/Tree.pm b/lib/RT/Interface/Web/QueryBuilder/Tree.pm
index 1ab187794f..c5bc42fb91 100644
--- a/lib/RT/Interface/Web/QueryBuilder/Tree.pm
+++ b/lib/RT/Interface/Web/QueryBuilder/Tree.pm
@@ -278,6 +278,10 @@ sub ParseSQL {
         }
         $main_key = $lcfield{ lc $main_key };
 
+        if ( $op =~ /^SHALLOW\s+/i && ($main_key !~ /(?:Requestor|Owner|AdminCc|Cc|CustomRole)/) ) {
+            push @results, [ $args{'CurrentUser'}->loc("Unsupported operator: [_1]", $op), -1 ];
+        }
+
         # Hardcode value for IS / IS NOT
         $value = 'NULL' if $op =~ /^IS( NOT)?$/i;
 
diff --git a/lib/RT/SQL.pm b/lib/RT/SQL.pm
index b3a396a999..96c9b45ac2 100644
--- a/lib/RT/SQL.pm
+++ b/lib/RT/SQL.pm
@@ -66,7 +66,7 @@ my $re_aggreg      = qr[(?i:AND|OR)];
 my $re_delim       = qr[$RE{delimited}{-delim=>qq{\'\"}}];
 my $re_value       = qr[[+-]?\d+|(?i:NULL)|$re_delim];
 my $re_keyword     = qr[[{}\w\.]+|$re_delim];
-my $re_op          = qr[=|!=|>=|<=|>|<|(?i:IS NOT)|(?i:IS)|(?i:NOT LIKE)|(?i:LIKE)|(?i:NOT STARTSWITH)|(?i:STARTSWITH)|(?i:NOT ENDSWITH)|(?i:ENDSWITH)]; # long to short
+my $re_op          = qr[(?i:SHALLOW )?(?:=|!=|>=|<=|>|<|(?i:IS NOT)|(?i:IS)|(?i:NOT LIKE)|(?i:LIKE)|(?i:NOT STARTSWITH)|(?i:STARTSWITH)|(?i:NOT ENDSWITH)|(?i:ENDSWITH))]; # long to short
 my $re_open_paren  = qr[\(];
 my $re_close_paren = qr[\)];
 
diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index 09a775ec36..a997382439 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -893,14 +893,14 @@ sub Limit {
     }
 
     if (($ARGS{FIELD}||'') =~ /\W/
-          or $ARGS{OPERATOR} !~ /^(=|<|>|!=|<>|<=|>=
+          or $ARGS{OPERATOR} !~ /^((?:SHALLOW\s*)?(?:=|<|>|!=|<>|<=|>=
                                   |(NOT\s*)?LIKE
                                   |(NOT\s*)?(STARTS|ENDS)WITH
                                   |(NOT\s*)?MATCHES
                                   |IS(\s*NOT)?
                                   |(NOT\s*)?IN
                                   |\@\@
-                                  |AGAINST)$/ix) {
+                                  |AGAINST))$/ix) {
         $RT::Logger->crit("Possible SQL injection attack: $ARGS{FIELD} $ARGS{OPERATOR}");
         %ARGS = (
             %ARGS,
diff --git a/lib/RT/SearchBuilder/Role/Roles.pm b/lib/RT/SearchBuilder/Role/Roles.pm
index d7a7d110bd..b8fbaf1c31 100644
--- a/lib/RT/SearchBuilder/Role/Roles.pm
+++ b/lib/RT/SearchBuilder/Role/Roles.pm
@@ -222,6 +222,7 @@ sub RoleLimit {
         VALUE => undef,
         @_
     );
+    my $is_shallow = ( $args{OPERATOR} =~ s/^shallow\s*//i );
 
     my $class = $args{CLASS} || $self->_RoleGroupClass;
 
@@ -314,7 +315,10 @@ sub RoleLimit {
             $uid = $users[0]->id if @users;
 
             my @ids;
-            {
+            if ( $is_shallow ) {
+                @ids = $uid;
+            }
+            else {
                 my $groups = RT::Groups->new( RT->SystemUser );
                 $groups->LimitToUserDefinedGroups;
                 $groups->WithMember( PrincipalId => $uid, Recursively => 1 );
@@ -374,7 +378,10 @@ sub RoleLimit {
         );
         if ($args{FIELD} eq "id") {
             my @ids;
-            {
+            if ( $is_shallow ) {
+                @ids = $args{VALUE};
+            }
+            else {
                 my $groups = RT::Groups->new( RT->SystemUser );
                 $groups->LimitToUserDefinedGroups;
                 $groups->WithMember( PrincipalId => $args{VALUE}, Recursively => 1 );
@@ -392,28 +399,39 @@ sub RoleLimit {
             );
         } else {
 
-            my $cgm_2 = $self->NewAlias('CachedGroupMembers');
-            my $group_members_2 = $self->Join(
-                ALIAS1 => $group_members,
-                FIELD1 => 'MemberId',
-                ALIAS2 => $cgm_2,
-                FIELD2 => 'GroupId',
-            );
-            $self->Limit(
-                LEFTJOIN => $group_members_2,
-                ALIAS => $cgm_2,
-                FIELD => 'Disabled',
-                VALUE => 0,
-                ENTRYAGGREGATOR => 'AND',
-            );
-
-            $users ||= $self->Join(
-                TYPE            => 'LEFT',
-                ALIAS1          => $group_members_2,
-                FIELD1          => 'MemberId',
-                TABLE2          => 'Users',
-                FIELD2          => 'id',
-            );
+            if ( $is_shallow ) {
+                $users ||= $self->Join(
+                    TYPE            => 'LEFT',
+                    ALIAS1          => $group_members,
+                    FIELD1          => 'MemberId',
+                    TABLE2          => 'Users',
+                    FIELD2          => 'id',
+                );
+            }
+            else {
+                my $cgm_2 = $self->NewAlias('CachedGroupMembers');
+                my $group_members_2 = $self->Join(
+                    ALIAS1 => $group_members,
+                    FIELD1 => 'MemberId',
+                    ALIAS2 => $cgm_2,
+                    FIELD2 => 'GroupId',
+                );
+                $self->Limit(
+                    LEFTJOIN => $group_members_2,
+                    ALIAS => $cgm_2,
+                    FIELD => 'Disabled',
+                    VALUE => 0,
+                    ENTRYAGGREGATOR => 'AND',
+                );
+
+                $users ||= $self->Join(
+                    TYPE            => 'LEFT',
+                    ALIAS1          => $group_members_2,
+                    FIELD1          => 'MemberId',
+                    TABLE2          => 'Users',
+                    FIELD2          => 'id',
+                );
+            }
             $self->Limit(
                 %args,
                 ALIAS           => $users,
diff --git a/share/html/Elements/SelectMatch b/share/html/Elements/SelectMatch
index 94cd69e242..551e8ed91e 100644
--- a/share/html/Elements/SelectMatch
+++ b/share/html/Elements/SelectMatch
@@ -46,10 +46,16 @@
 %#
 %# END BPS TAGGED BLOCK }}}
 <select name="<%$Name%>">
-<option value="LIKE" <%$LikeDefault|n%>><%$Like%></option>
-<option value="NOT LIKE" <%$NotLikeDefault|n%>><%$NotLike%></option>
-<option value="=" <%$TrueDefault|n%>><%$True%></option>
-<option value="!=" <%$FalseDefault|n%>><%$False%></option>
+<option value="LIKE" <% $default_is_shallow ? '' : $LikeDefault |n%>><%$Like%></option>
+<option value="NOT LIKE" <% $default_is_shallow ? '' : $NotLikeDefault |n%>><%$NotLike%></option>
+<option value="=" <% $default_is_shallow ? '' : $TrueDefault |n%>><%$True%></option>
+<option value="!=" <% $default_is_shallow ? '' : $FalseDefault |n%>><%$False%></option>
+% if ( $IncludeShallow ) {
+<option value="SHALLOW LIKE" <% $default_is_shallow ? $LikeDefault : '' |n%>><%$ShallowLike%></option>
+<option value="SHALLOW NOT LIKE" <% $default_is_shallow ? $NotLikeDefault : '' |n%>><%$ShallowNotLike%></option>
+<option value="SHALLOW =" <% $default_is_shallow ? $TrueDefault : '' |n%>><%$ShallowTrue%></option>
+<option value="SHALLOW !=" <% $default_is_shallow ? $FalseDefault : '' |n%>><%$ShallowFalse%></option>
+% }
 </select>
 
 <%ARGS>
@@ -59,6 +65,11 @@ $NotLike => loc("doesn't match")
 $True => loc('is')
 $False => loc("isn't")
 $Default => undef
+$IncludeShallow => undef
+$ShallowLike => loc('shallow matches')
+$ShallowNotLike => loc("shallow doesn't match")
+$ShallowTrue => loc('shallow is')
+$ShallowFalse => loc("shallow isn't")
 </%ARGS>
 <%INIT>
 
@@ -79,4 +90,6 @@ elsif ($Default && $Default =~ /notlike|NOT LIKE/i) {
 else {
     $LikeDefault = qq[ selected="selected"];
 }
+
+my $default_is_shallow = ( $Default // '' ) =~ /shallow/i ? 1 : 0;
 </%INIT>
diff --git a/share/html/Search/Elements/PickBasics b/share/html/Search/Elements/PickBasics
index 08f7c949a6..4b02f3ed00 100644
--- a/share/html/Search/Elements/PickBasics
+++ b/share/html/Search/Elements/PickBasics
@@ -152,6 +152,7 @@ my @lines = (
         Op => {
             Type => 'component',
             Path => '/Elements/SelectMatch',
+            Arguments => { IncludeShallow => 1 },
         },
         Value => { Type => 'text', Size => 20 }
     },
diff --git a/share/html/Search/Elements/PickCustomRoles b/share/html/Search/Elements/PickCustomRoles
index f3e96759a0..38f53a2114 100644
--- a/share/html/Search/Elements/PickCustomRoles
+++ b/share/html/Search/Elements/PickCustomRoles
@@ -75,6 +75,7 @@ while ( my $Role = $CustomRoles->Next ) {
         Op => {
             Type => 'component',
             Path => '/Elements/SelectMatch',
+            Arguments => { IncludeShallow => $Role->SingleValue ? 0 : 1 },
         },
         Value => { Type => 'text', Size => 20 },
     );

-----------------------------------------------------------------------


More information about the rt-commit mailing list