[Rt-commit] rt branch, 4.2/warn-on-case-sensitive-searches, created. rt-4.1.8-494-g8af952e

Ruslan Zakirov ruz at bestpractical.com
Sat Jun 1 08:27:13 EDT 2013


The branch, 4.2/warn-on-case-sensitive-searches has been created
        at  8af952ea52b7475234ba9903e4f0469be4f8cf5d (commit)

- Log -----------------------------------------------------------------
commit 56aa584210bb5c7697be237640ff9efc45ee23c7
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri May 24 18:34:41 2013 -0400

    Users should not force insensitive all joined limits, as well

diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index fc17854..be9e59c 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -226,7 +226,7 @@ sub LimitToUnprivileged {
 sub Limit {
     my $self = shift;
     my %args = @_;
-    $args{'CASESENSITIVE'} = 0 unless exists $args{'CASESENSITIVE'};
+    $args{'CASESENSITIVE'} = 0 unless exists $args{'CASESENSITIVE'} or $args{'ALIAS'};
     return $self->SUPER::Limit( %args );
 }
 

commit c3c06440c2eccd489c618fd7daac8a75459dbc78
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Apr 18 22:01:27 2013 +0400

    warn on case sensitive searches
    
    Because of historical reasons, RT's searches were marked as case
    sensitive in RT::SearchBuilder::Limit, although callers often expected
    them to be case insensitive.
    
    Mixing case sensitive and case insensitive searches by the same column
    causes problems on Pg and Oracle -- especially as the case-sensitivity
    of the search and any indexes may cause them to not be used.
    
    This adds code to catch, for specific columns, cases where CASESENSITIVE
    is not explicitly specified, and throws a warning.

diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index 6397055..6021c20 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -747,6 +747,9 @@ injection attacks when we pass through user specified values.
 
 =cut
 
+my %check_case_sensitivity = (
+);
+
 my %deprecated = (
     groups => {
         type => 'Name',
@@ -757,7 +760,6 @@ my %deprecated = (
 sub Limit {
     my $self = shift;
     my %ARGS = (
-        CASESENSITIVE => 1,
         OPERATOR => '=',
         @_,
     );
@@ -801,6 +803,16 @@ sub Limit {
         );
     }
 
+    unless ( exists $ARGS{CASESENSITIVE} ) {
+        if ( $table && $check_case_sensitivity{ lc $table }{ lc $ARGS{'FIELD'} } ) {
+            RT->Logger->warning(
+                "Case sensitive search by $table.$ARGS{'FIELD'}"
+                ." at ". (caller)[1] . " line ". (caller)[2]
+            );
+        }
+        $ARGS{'CASESENSITIVE'} = 1;
+    }
+
     return $self->SUPER::Limit( %ARGS );
 }
 

commit b8019b409642ff46efe8e5b9aa38f9a85146ebac
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri May 24 17:51:27 2013 -0400

    Force group names to be case-insensitive

diff --git a/lib/RT/Action/CreateTickets.pm b/lib/RT/Action/CreateTickets.pm
index 9381a51..8817adb 100644
--- a/lib/RT/Action/CreateTickets.pm
+++ b/lib/RT/Action/CreateTickets.pm
@@ -129,7 +129,7 @@ A convoluted example:
 
     my $groups = RT::Groups->new(RT->SystemUser);
     $groups->LimitToUserDefinedGroups();
-    $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => "$name");
+    $groups->Limit(FIELD => "Name", OPERATOR => "=", VALUE => $name, CASESENSITIVE => 0);
     $groups->WithMember($TransactionObj->CreatorObj->Id);
 
     my $groupid = $groups->First->Id;
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index e82d885..430da7f 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -3564,7 +3564,7 @@ sub GetPrincipalsMap {
                 my $class = $object->RecordClassFromLookupType;
                 if ($class and $class->DOES("RT::Record::Role::Roles")) {
                     $roles->LimitToRolesForObject(RT->System);
-                    $roles->Limit( FIELD => "Name", VALUE => $_ )
+                    $roles->Limit( FIELD => "Name", VALUE => $_, CASESENSITIVE => 0 )
                         for $class->Roles;
                 } else {
                     # No roles to show; so show nothing
@@ -3603,7 +3603,7 @@ sub GetPrincipalsMap {
                 FIELD2 => 'GroupId'
             );
             $Users->Limit( ALIAS => $groups, FIELD => 'Domain', VALUE => 'ACLEquivalence' );
-            $Users->Limit( ALIAS => $groups, FIELD => 'Name', VALUE => 'UserEquiv' );
+            $Users->Limit( ALIAS => $groups, FIELD => 'Name', VALUE => 'UserEquiv', CASESENSITIVE => 0 );
 
             push @map, [
                 'Users' => $Users,  # loc_left_pair
diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index 6021c20..1b0c134 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -748,6 +748,7 @@ injection attacks when we pass through user specified values.
 =cut
 
 my %check_case_sensitivity = (
+    groups => { 'name' => 1 },
 );
 
 my %deprecated = (
diff --git a/lib/RT/SearchBuilder/Role/Roles.pm b/lib/RT/SearchBuilder/Role/Roles.pm
index b1a3294..f2c85fb 100644
--- a/lib/RT/SearchBuilder/Role/Roles.pm
+++ b/lib/RT/SearchBuilder/Role/Roles.pm
@@ -137,6 +137,7 @@ sub _RoleGroupsJoin {
         ALIAS           => $groups,
         FIELD           => 'Name',
         VALUE           => $name,
+        CASESENSITIVE   => 0,
     ) if $name;
 
     $self->{'_sql_role_group_aliases'}{ $args{'Class'} .'-'. $name } = $groups
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index d23e8d3..b98da44 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -2459,7 +2459,7 @@ sub CurrentUserCanSee {
         my $groups = RT::Groups->new( RT->SystemUser );
         $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role' );
         foreach ( @tmp ) {
-            $groups->Limit( FIELD => 'Name', VALUE => $_ );
+            $groups->Limit( FIELD => 'Name', VALUE => $_, CASESENSITIVE => 0 );
         }
         my $principal_alias = $groups->Join(
             ALIAS1 => 'main',
@@ -2565,6 +2565,7 @@ sub CurrentUserCanSee {
                     FIELD           => 'Name',
                     VALUE           => $role,
                     ENTRYAGGREGATOR => 'AND',
+                    CASESENSITIVE   => 0,
                 );
             }
             $limit_queues->( 'AND', @$queues ) if ref $queues;
diff --git a/share/html/Admin/Elements/EditRights b/share/html/Admin/Elements/EditRights
index b66309b..9f694e9 100644
--- a/share/html/Admin/Elements/EditRights
+++ b/share/html/Admin/Elements/EditRights
@@ -175,7 +175,7 @@ for my $category (@$Principals) {
 if ($obj->isa('RT::Group') and $obj->Domain eq 'UserDefined') {
     my $subgroups = $obj->GroupMembersObj( Recursively => 1 );
     $subgroups->LimitToUserDefinedGroups;
-    $subgroups->Limit( FIELD => 'Name', OPERATOR => '!=', VALUE => $obj->Name );
+    $subgroups->Limit( FIELD => 'Name', OPERATOR => '!=', VALUE => $obj->Name, CASESENSITIVE => 0 );
 
     if ( $subgroups->Count ) {
         my $inc = join ", ", map $_->Name, @{$subgroups->ItemsArrayRef};
diff --git a/share/html/Admin/Groups/Modify.html b/share/html/Admin/Groups/Modify.html
index 7cf046a..e9c404c 100644
--- a/share/html/Admin/Groups/Modify.html
+++ b/share/html/Admin/Groups/Modify.html
@@ -136,7 +136,7 @@ if ($Group->Id) {
     # Warn about duplicate groups
     my $dupcheck = RT::Groups->new(RT->SystemUser);
     $dupcheck->LimitToUserDefinedGroups();
-    $dupcheck->Limit( FIELD => 'Name', VALUE => $Group->Name );
+    $dupcheck->Limit( FIELD => 'Name', VALUE => $Group->Name, CASESENSITIVE => 0 );
     if ($dupcheck->Count > 1) {
         push @warnings, loc("There is more than one group with the name '[_1]'.  This may cause inconsistency in parts of the admin interface, and therefore it's recommended you rename the conflicting groups.", $Group->Name);
     }
diff --git a/share/html/Helpers/Autocomplete/Groups b/share/html/Helpers/Autocomplete/Groups
index 0446c50..1908ad5 100644
--- a/share/html/Helpers/Autocomplete/Groups
+++ b/share/html/Helpers/Autocomplete/Groups
@@ -73,6 +73,7 @@ $groups->Limit(
     FIELD           => 'Name',
     OPERATOR        => $op,
     VALUE           => $term,
+    CASESENSITIVE   => 0,
 );
 
 # Exclude groups we don't want
diff --git a/share/html/REST/1.0/Forms/group/ns b/share/html/REST/1.0/Forms/group/ns
index 907324d..7801214 100644
--- a/share/html/REST/1.0/Forms/group/ns
+++ b/share/html/REST/1.0/Forms/group/ns
@@ -54,7 +54,7 @@ $id
 use RT::Groups;
 
 my $groups = RT::Groups->new($session{CurrentUser});
-$groups->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id);
+$groups->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id, CASESENSITIVE => 0);
 if ($groups->Count == 0) {
     return (0, "No group named $id exists.");
 }

commit 03e31ca3d734d66b0e62036939d689c37b8b56b9
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 22 16:43:34 2013 +0400

    case insensitive search by Groups.Domain

diff --git a/etc/upgrade/3.9.2/content b/etc/upgrade/3.9.2/content
index 27c91a7..1851a9e 100644
--- a/etc/upgrade/3.9.2/content
+++ b/etc/upgrade/3.9.2/content
@@ -30,7 +30,8 @@ our @Initial = (
         my $groups = RT::Groups->new(RT->SystemUser);
         $groups->Limit( FIELD    => 'Domain',
                         OPERATOR => '=',
-                        VALUE    => 'Personal'
+                        VALUE    => 'Personal',
+                        CASESENSITIVE => 0,
                       );
         while ( my $group = $groups->Next ) {
             my $members = $group->MembersObj();
diff --git a/etc/upgrade/4.0.1/content b/etc/upgrade/4.0.1/content
index 14da329..c3056d7 100644
--- a/etc/upgrade/4.0.1/content
+++ b/etc/upgrade/4.0.1/content
@@ -16,6 +16,7 @@ our @Initial = (
                      FIELD           => 'Domain',
                      OPERATOR        => '=',
                      VALUE           => 'Personal',
+                     CASESENSITIVE   => 0,
                     );
 
         while ( my $ace = $acl->Next ) {
@@ -29,7 +30,8 @@ our @Initial = (
         my $groups = RT::Groups->new(RT->SystemUser);
         $groups->Limit( FIELD    => 'Domain',
                         OPERATOR => '=',
-                        VALUE    => 'Personal'
+                        VALUE    => 'Personal',
+                        CASESENSITIVE   => 0,
                       );
         while ( my $group = $groups->Next ) {
             my $members = $group->MembersObj();
diff --git a/etc/upgrade/4.0.9/content b/etc/upgrade/4.0.9/content
index 246b1eb..6f526ce 100644
--- a/etc/upgrade/4.0.9/content
+++ b/etc/upgrade/4.0.9/content
@@ -35,7 +35,8 @@ our @Initial = (
         my $groups = RT::Groups->new(RT->SystemUser);
         $groups->Limit( FIELD    => 'Domain',
                         OPERATOR => '=',
-                        VALUE    => 'Personal'
+                        VALUE    => 'Personal',
+                        CASESENSITIVE => 0,
                       );
         $groups->LimitToDeleted;
         while ( my $group = $groups->Next ) {
diff --git a/etc/upgrade/shrink_transactions_table.pl b/etc/upgrade/shrink_transactions_table.pl
index 173ddee..601c297 100644
--- a/etc/upgrade/shrink_transactions_table.pl
+++ b/etc/upgrade/shrink_transactions_table.pl
@@ -76,6 +76,7 @@ $txns->Limit(
     FIELD => 'Domain',
     OPERATOR => '=',
     VALUE => 'ACLEquivalence',
+    CASESENSITIVE => 0,
     QUOTEVALUE => 1,
     ENTRYAGGREGATOR => 'AND',
 );
diff --git a/lib/RT/Groups.pm b/lib/RT/Groups.pm
index 8d30dde..1cfad14 100644
--- a/lib/RT/Groups.pm
+++ b/lib/RT/Groups.pm
@@ -141,7 +141,7 @@ Return only SystemInternal Groups, such as "privileged" "unprivileged" and "ever
 
 sub LimitToSystemInternalGroups {
     my $self = shift;
-    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'SystemInternal');
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'SystemInternal', CASESENSITIVE => 0 );
     # All system internal groups have the same instance. No reason to limit down further
     #$self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '0');
 }
@@ -158,7 +158,7 @@ Return only UserDefined Groups
 
 sub LimitToUserDefinedGroups {
     my $self = shift;
-    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0 );
     # All user-defined groups have the same instance. No reason to limit down further
     #$self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '');
 }
@@ -178,7 +178,7 @@ L</LimitToRolesForSystem>.
 sub LimitToRolesForObject {
     my $self   = shift;
     my $object = shift;
-    $self->Limit(FIELD => 'Domain',   OPERATOR => '=', VALUE => ref($object) . "-Role");
+    $self->Limit(FIELD => 'Domain',   OPERATOR => '=', VALUE => ref($object) . "-Role", CASESENSITIVE => 0 );
     $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => $object->id)
         if $object->id and not ref($object) eq "RT::System";
 }
@@ -198,7 +198,7 @@ sub LimitToRolesForQueue {
         Instead => "LimitToRolesForObject",
         Remove => "4.4",
     );
-    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::Queue-Role');
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
     $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => $queue);
 }
 
@@ -219,7 +219,7 @@ sub LimitToRolesForTicket {
         Instead => "LimitToRolesForObject",
         Remove => "4.4",
     );
-    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::Ticket-Role');
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::Ticket-Role', CASESENSITIVE => 0 );
     $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => $Ticket);
 }
 
@@ -239,7 +239,7 @@ sub LimitToRolesForSystem {
         Instead => "LimitToRolesForObject",
         Remove => "4.4",
     );
-    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::System-Role');
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RT::System-Role', CASESENSITIVE => 0 );
 }
 
 
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 430da7f..d2fd60b 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -3602,7 +3602,7 @@ sub GetPrincipalsMap {
                 ALIAS2 => $group_members,
                 FIELD2 => 'GroupId'
             );
-            $Users->Limit( ALIAS => $groups, FIELD => 'Domain', VALUE => 'ACLEquivalence' );
+            $Users->Limit( ALIAS => $groups, FIELD => 'Domain', VALUE => 'ACLEquivalence', CASESENSITIVE => 0 );
             $Users->Limit( ALIAS => $groups, FIELD => 'Name', VALUE => 'UserEquiv', CASESENSITIVE => 0 );
 
             push @map, [
diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index 1b0c134..d60df5b 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -748,7 +748,7 @@ injection attacks when we pass through user specified values.
 =cut
 
 my %check_case_sensitivity = (
-    groups => { 'name' => 1 },
+    groups => { 'name' => 1, domain => 1 },
 );
 
 my %deprecated = (
diff --git a/lib/RT/SearchBuilder/Role/Roles.pm b/lib/RT/SearchBuilder/Role/Roles.pm
index f2c85fb..6bf239b 100644
--- a/lib/RT/SearchBuilder/Role/Roles.pm
+++ b/lib/RT/SearchBuilder/Role/Roles.pm
@@ -131,6 +131,7 @@ sub _RoleGroupsJoin {
         ALIAS           => $groups,
         FIELD           => 'Domain',
         VALUE           => $args{'Class'} .'-Role',
+        CASESENSITIVE   => 0,
     );
     $self->Limit(
         LEFTJOIN        => $groups,
diff --git a/lib/RT/Shredder/Queue.pm b/lib/RT/Shredder/Queue.pm
index 80a1c84..46fea2f 100644
--- a/lib/RT/Shredder/Queue.pm
+++ b/lib/RT/Shredder/Queue.pm
@@ -76,7 +76,7 @@ sub __DependsOn
 
 # Queue role groups( Cc, AdminCc )
     $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role' );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     push( @$list, $objs );
 
diff --git a/lib/RT/Shredder/Ticket.pm b/lib/RT/Shredder/Ticket.pm
index c532486..7c8da55 100644
--- a/lib/RT/Shredder/Ticket.pm
+++ b/lib/RT/Shredder/Ticket.pm
@@ -77,7 +77,7 @@ sub __DependsOn
 
 # Ticket role groups( Owner, Requestors, Cc, AdminCc )
     $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role' );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role', CASESENSITIVE => 0 );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     push( @$list, $objs );
 
diff --git a/lib/RT/Shredder/User.pm b/lib/RT/Shredder/User.pm
index 67443e7..eb5b3d6 100644
--- a/lib/RT/Shredder/User.pm
+++ b/lib/RT/Shredder/User.pm
@@ -99,7 +99,7 @@ sub __DependsOn
 # ACL equivalence group
 # don't use LoadACLEquivalenceGroup cause it may not exists any more
     my $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence' );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence', CASESENSITIVE => 0 );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     push( @$list, $objs );
 
diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index afeb9db..f92e812 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -726,7 +726,10 @@ sub load_or_create_user {
         my $groups_alias = $gms->Join(
             FIELD1 => 'GroupId', TABLE2 => 'Groups', FIELD2 => 'id',
         );
-        $gms->Limit( ALIAS => $groups_alias, FIELD => 'Domain', VALUE => 'UserDefined' );
+        $gms->Limit(
+            ALIAS => $groups_alias, FIELD => 'Domain', VALUE => 'UserDefined',
+            CASESENSITIVE => 0,
+        );
         $gms->Limit( FIELD => 'MemberId', VALUE => $obj->id );
         while ( my $group_member_record = $gms->Next ) {
             $group_member_record->Delete;
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index b98da44..541cea6 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -977,7 +977,8 @@ sub _WatcherMembershipLimit {
         ALIAS           => $groups,
         FIELD           => 'Domain',
         VALUE           => 'RT::Ticket-Role',
-        ENTRYAGGREGATOR => 'AND'
+        ENTRYAGGREGATOR => 'AND',
+        CASESENSITIVE   => 0,
     );
 
     $self->Join(
@@ -2457,7 +2458,7 @@ sub CurrentUserCanSee {
     if ( my @tmp = grep $_ ne 'Owner' && !ref $roles{ $_ }, keys %roles ) {
 
         my $groups = RT::Groups->new( RT->SystemUser );
-        $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role' );
+        $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
         foreach ( @tmp ) {
             $groups->Limit( FIELD => 'Name', VALUE => $_, CASESENSITIVE => 0 );
         }
diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 5391184..d904ff4 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -1456,6 +1456,7 @@ sub WatchedQueues {
                             FIELD => 'Domain',
                             VALUE => 'RT::Queue-Role',
                             ENTRYAGGREGATOR => 'AND',
+                            CASESENSITIVE => 0,
                           );
     if (grep { $_ eq 'Cc' } @roles) {
         $watched_queues->Limit(
diff --git a/sbin/rt-dump-metadata.in b/sbin/rt-dump-metadata.in
index edb0cd1..11bd01f 100644
--- a/sbin/rt-dump-metadata.in
+++ b/sbin/rt-dump-metadata.in
@@ -138,7 +138,8 @@ foreach my $class (@classes) {
         $objects->Limit(
             FIELD    => 'Domain',
             OPERATOR => '=',
-            VALUE    => 'UserDefined'
+            VALUE    => 'UserDefined',
+            CASESENSITIVE => 0,
         ) if $class eq 'Groups';
     }
 
diff --git a/share/html/Admin/Elements/SelectGroups b/share/html/Admin/Elements/SelectGroups
index 2661a02..c7641c5 100644
--- a/share/html/Admin/Elements/SelectGroups
+++ b/share/html/Admin/Elements/SelectGroups
@@ -53,7 +53,7 @@
 
 <%INIT>
 my $groups = RT::Groups->new($session{'CurrentUser'});
-$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain);
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain, CASESENSITIVE => 0 );
 
 </%INIT>
 <%ARGS>
diff --git a/share/html/Admin/Queues/People.html b/share/html/Admin/Queues/People.html
index e7cdd47..97c7f14 100644
--- a/share/html/Admin/Queues/People.html
+++ b/share/html/Admin/Queues/People.html
@@ -176,7 +176,8 @@ if ( $ARGS{'GroupString'} ) {
     $Groups = RT::Groups->new( $session{'CurrentUser'} );
     $Groups->Limit( FIELD    => 'Domain',
                     OPERATOR => '=',
-                    VALUE    => 'UserDefined'
+                    VALUE    => 'UserDefined',
+                    CASESENSITIVE => 0,
                   );
     $Groups->Limit( FIELD    => $ARGS{'GroupField'},
                     VALUE    => $ARGS{'GroupString'},
diff --git a/share/html/Elements/ShowMemberships b/share/html/Elements/ShowMemberships
index 1985302..8cc8b0a 100644
--- a/share/html/Elements/ShowMemberships
+++ b/share/html/Elements/ShowMemberships
@@ -71,12 +71,14 @@ $GroupMembers->Limit(
     FIELD      => 'Domain',
     OPERATOR   => '=',
     VALUE      => 'SystemInternal',
+    CASESENSITIVE => 0,
 );
 $GroupMembers->Limit(
     ALIAS      => $alias,
     FIELD      => 'Domain',
     OPERATOR   => '=',
     VALUE      => 'UserDefined',
+    CASESENSITIVE => 0,
 );
 $GroupMembers->OrderByCols(
     { ALIAS => $alias, FIELD => 'Domain' },
diff --git a/share/html/Search/Elements/SelectGroup b/share/html/Search/Elements/SelectGroup
index 42a9c37..fae0ea5 100644
--- a/share/html/Search/Elements/SelectGroup
+++ b/share/html/Search/Elements/SelectGroup
@@ -56,7 +56,7 @@
 
 <%INIT>
 my $groups = RT::Groups->new($session{'CurrentUser'});
-$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain);
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain, CASESENSITIVE => 0);
 
 </%INIT>
 <%ARGS>
diff --git a/share/html/Ticket/Elements/AddWatchers b/share/html/Ticket/Elements/AddWatchers
index 8e11ba2..8055e24 100644
--- a/share/html/Ticket/Elements/AddWatchers
+++ b/share/html/Ticket/Elements/AddWatchers
@@ -116,7 +116,7 @@ if ($UserString) {
 
 if ($GroupString) {
     $Groups = RT::Groups->new($session{'CurrentUser'});
-    $Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+    $Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0);
     $Groups->Limit(FIELD => $GroupField, VALUE => $GroupString, OPERATOR => $GroupOp);
      }
 
diff --git a/t/web/owner_disabled_group_19221.t b/t/web/owner_disabled_group_19221.t
index d41decf..73b3194 100644
--- a/t/web/owner_disabled_group_19221.t
+++ b/t/web/owner_disabled_group_19221.t
@@ -122,7 +122,7 @@ diag "Check WithMember and WithoutMember recursively";
 {
     my $with = RT::Groups->new( RT->SystemUser );
     $with->WithMember( PrincipalId => $user->PrincipalObj->Id, Recursively => 1 );
-    $with->Limit( FIELD => 'domain', OPERATOR => '=', VALUE => 'UserDefined' );
+    $with->Limit( FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0 );
     is_deeply(
         [map {$_->Name} @{$with->ItemsArrayRef}],
         ['Disabled Group','Supergroup'],
@@ -131,7 +131,7 @@ diag "Check WithMember and WithoutMember recursively";
 
     my $without = RT::Groups->new( RT->SystemUser );
     $without->WithoutMember( PrincipalId => $user->PrincipalObj->Id, Recursively => 1 );
-    $without->Limit( FIELD => 'domain', OPERATOR => '=', VALUE => 'UserDefined' );
+    $without->Limit( FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0 );
     is_deeply(
         [map {$_->Name} @{$without->ItemsArrayRef}],
         [],

commit e247054814fd7e8fab9b499768222f2b69488007
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sun Apr 21 16:33:02 2013 +0400

    catch and fix case sensitive searches by CF name

diff --git a/lib/RT/Articles.pm b/lib/RT/Articles.pm
index d69eabf..defed2a 100644
--- a/lib/RT/Articles.pm
+++ b/lib/RT/Articles.pm
@@ -314,7 +314,8 @@ sub LimitCustomField {
             $self->Limit( ALIAS => $fields,
                           FIELD => 'Name',
                           VALUE => $args{'FIELD'},
-                          ENTRYAGGREGATOR  => 'OR');
+                          ENTRYAGGREGATOR  => 'OR',
+                          CASESENSITIVE => 0);
             $self->Limit(
                 ALIAS => $fields,
                 FIELD => 'LookupType',
diff --git a/lib/RT/CustomFields.pm b/lib/RT/CustomFields.pm
index 3108b84..c337f99 100644
--- a/lib/RT/CustomFields.pm
+++ b/lib/RT/CustomFields.pm
@@ -129,7 +129,7 @@ sub LimitToGrouping {
             return $self->Limit( FIELD => 'id', VALUE => 0, ENTRYAGGREGATOR => 'AND' );
         }
         foreach ( @$list ) {
-            $self->Limit( FIELD => 'Name', VALUE => $_ );
+            $self->Limit( FIELD => 'Name', VALUE => $_, CASESENSITIVE => 0 );
         }
     } else {
         my @list = map {@$_} grep defined && ref($_) eq 'ARRAY',
@@ -142,6 +142,7 @@ sub LimitToGrouping {
                 OPERATOR => '!=',
                 VALUE => $_,
                 ENTRYAGGREGATOR => 'AND',
+                CASESENSITIVE => 0,
             );
         }
 
diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index d60df5b..f720cee 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -324,6 +324,7 @@ sub _CustomFieldJoinByName {
         LEFTJOIN        => $CFs,
         ENTRYAGGREGATOR => 'AND',
         FIELD           => 'Name',
+        CASESENSITIVE   => 0,
         VALUE           => $cf,
     );
 
@@ -749,6 +750,7 @@ injection attacks when we pass through user specified values.
 
 my %check_case_sensitivity = (
     groups => { 'name' => 1, domain => 1 },
+    customfields => { 'name' => 1 },
 );
 
 my %deprecated = (
@@ -805,7 +807,9 @@ sub Limit {
     }
 
     unless ( exists $ARGS{CASESENSITIVE} ) {
-        if ( $table && $check_case_sensitivity{ lc $table }{ lc $ARGS{'FIELD'} } ) {
+        if ( $ARGS{'OPERATOR'} !~ /IS/i
+            && $table && $check_case_sensitivity{ lc $table }{ lc $ARGS{'FIELD'} }
+        ) {
             RT->Logger->warning(
                 "Case sensitive search by $table.$ARGS{'FIELD'}"
                 ." at ". (caller)[1] . " line ". (caller)[2]
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 541cea6..69af181 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1070,7 +1070,7 @@ sub _CustomFieldDecipher {
     elsif ( $field =~ /\D/ ) {
         $queue = '';
         my $cfs = RT::CustomFields->new( $self->CurrentUser );
-        $cfs->Limit( FIELD => 'Name', VALUE => $field );
+        $cfs->Limit( FIELD => 'Name', VALUE => $field, CASESENSITIVE => 0 );
         $cfs->LimitToLookupType('RT::Queue-RT::Ticket');
 
         # if there is more then one field the current user can
diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index 1d2773e..e947a4b 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -1406,7 +1406,7 @@ sub LoadCustomFieldByIdentifier {
 
     my $CFs = RT::CustomFields->new( $self->CurrentUser );
     $CFs->SetContextObject( $self->Object );
-    $CFs->Limit( FIELD => 'Name', VALUE => $field );
+    $CFs->Limit( FIELD => 'Name', VALUE => $field, CASESENSITIVE => 0 );
     $CFs->LimitToLookupType($self->CustomFieldLookupType);
     $CFs->LimitToGlobalOrObjectId($self->Object->QueueObj->id);
     return $CFs->First || RT::CustomField->new( $self->CurrentUser );
diff --git a/t/customfields/ip.t b/t/customfields/ip.t
index 60e68a4..2537b1e 100644
--- a/t/customfields/ip.t
+++ b/t/customfields/ip.t
@@ -26,7 +26,7 @@ my $cf;
 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
 {
     my $cfs = RT::CustomFields->new($RT::SystemUser);
-    $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+    $cfs->Limit( FIELD => 'Name', VALUE => 'IP', CASESENSITIVE => 0 );
     is( $cfs->Count, 1, "found one CF with name 'IP'" );
 
     $cf = $cfs->First;
diff --git a/t/customfields/iprange.t b/t/customfields/iprange.t
index 943e412..c99d1f1 100644
--- a/t/customfields/iprange.t
+++ b/t/customfields/iprange.t
@@ -21,7 +21,7 @@ my $cf;
 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
 {
     my $cfs = RT::CustomFields->new( $RT::SystemUser );
-    $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+    $cfs->Limit( FIELD => 'Name', VALUE => 'IP', CASESENSITIVE => 0 );
     is( $cfs->Count, 1, "found one CF with name 'IP'" );
 
     $cf = $cfs->First;
diff --git a/t/customfields/iprangev6.t b/t/customfields/iprangev6.t
index 3b8a4d6..3d73a23 100644
--- a/t/customfields/iprangev6.t
+++ b/t/customfields/iprangev6.t
@@ -21,7 +21,7 @@ my $cf;
 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
 {
     my $cfs = RT::CustomFields->new( $RT::SystemUser );
-    $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+    $cfs->Limit( FIELD => 'Name', VALUE => 'IP', CASESENSITIVE => 0 );
     is( $cfs->Count, 1, "found one CF with name 'IP'" );
 
     $cf = $cfs->First;
diff --git a/t/customfields/ipv6.t b/t/customfields/ipv6.t
index ad34f42..9c82d0d 100644
--- a/t/customfields/ipv6.t
+++ b/t/customfields/ipv6.t
@@ -26,7 +26,7 @@ my $cf;
 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
 {
     my $cfs = RT::CustomFields->new($RT::SystemUser);
-    $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+    $cfs->Limit( FIELD => 'Name', VALUE => 'IP', CASESENSITIVE => 0 );
     is( $cfs->Count, 1, "found one CF with name 'IP'" );
 
     $cf = $cfs->First;

commit dc2eb2537d7d77ee59de6a00f02d415ce0fdf404
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri May 24 19:29:06 2013 -0400

    Make queue names case-insensitive

diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index f720cee..60464ba 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -750,6 +750,7 @@ injection attacks when we pass through user specified values.
 
 my %check_case_sensitivity = (
     groups => { 'name' => 1, domain => 1 },
+    queues => { 'name' => 1 },
     customfields => { 'name' => 1 },
 );
 
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 69af181..80baeca 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1208,7 +1208,7 @@ sub OrderByCols {
                     TABLE2 => 'Queues',
                     FIELD2 => 'id',
                 );
-                push @res, { %$row, ALIAS => $alias, FIELD => "Name" };
+                push @res, { %$row, ALIAS => $alias, FIELD => "Name", CASESENSITIVE => 0 };
             } elsif ( ( $meta->[0] eq 'ENUM' && ($meta->[1]||'') eq 'User' )
                 || ( $meta->[0] eq 'WATCHERFIELD' && ($meta->[1]||'') eq 'Owner' )
             ) {
diff --git a/share/html/REST/1.0/Forms/queue/ns b/share/html/REST/1.0/Forms/queue/ns
index 3ea6bf2..35dbf09 100644
--- a/share/html/REST/1.0/Forms/queue/ns
+++ b/share/html/REST/1.0/Forms/queue/ns
@@ -54,7 +54,7 @@ $id
 use RT::Queues;
 
 my $queues = RT::Queues->new($session{CurrentUser});
-$queues->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id);
+$queues->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id, CASESENSITIVE => 0 );
 if ($queues->Count == 0) {
     return (0, "No queue named $id exists.");
 }

commit f84ea7f91f6cb3d99719a594100c8695836b5516
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri May 24 19:29:28 2013 -0400

    Force user names and email addresses to be case-insensitive

diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index 60464ba..299a743 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -751,6 +751,7 @@ injection attacks when we pass through user specified values.
 my %check_case_sensitivity = (
     groups => { 'name' => 1, domain => 1 },
     queues => { 'name' => 1 },
+    users => { 'name' => 1, emailaddress => 1 },
     customfields => { 'name' => 1 },
 );
 
diff --git a/lib/RT/Shredder/Plugin/Users.pm b/lib/RT/Shredder/Plugin/Users.pm
index 244a262..b45c685 100644
--- a/lib/RT/Shredder/Plugin/Users.pm
+++ b/lib/RT/Shredder/Plugin/Users.pm
@@ -183,6 +183,7 @@ sub Run
         $objs->Limit( FIELD => 'Name',
                   OPERATOR => 'MATCHES',
                   VALUE => $self->{'opt'}{'name'},
+                  CASESENSITIVE => 0,
                 );
     }
     if( $self->{'opt'}{'member_of'} ) {
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 80baeca..a9990b2 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1219,7 +1219,7 @@ sub OrderByCols {
                     TABLE2 => 'Users',
                     FIELD2 => 'id',
                 );
-                push @res, { %$row, ALIAS => $alias, FIELD => "Name" };
+                push @res, { %$row, ALIAS => $alias, FIELD => "Name", CASESENSITIVE => 0 };
             } else {
                 push @res, $row;
             }
diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index be9e59c..f00b1f4 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -163,7 +163,7 @@ that email address
 sub LimitToEmail {
     my $self = shift;
     my $addr = shift;
-    $self->Limit( FIELD => 'EmailAddress', VALUE => "$addr" );
+    $self->Limit( FIELD => 'EmailAddress', VALUE => $addr, CASESENSITIVE => 0 );
 }
 
 

commit 833ee1c522b61c00d5702e07112bd72a3bd3e2b5
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 22 18:54:13 2013 +0400

    handle case sensitivity in manually generated SQL

diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index aceb23a..7911f83 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -1234,6 +1234,14 @@ sub _LogSQLStatement {
     push @{$self->{'StatementLog'}} , ([Time::HiRes::time(), $statement, [@bind], $duration, HTML::Mason::Exception->new->as_string]);
 }
 
+# helper in a few cases where we do SQL by hand
+sub __MakeClauseCaseInsensitive {
+    my $self = shift;
+    return join ' ', @_ unless $self->CaseSensitive;
+    my ($field, $op, $value) = $self->_MakeClauseCaseInsensitive(@_);
+    return "$field $op $value";
+}
+
 __PACKAGE__->FinalizeDatabaseType;
 
 RT::Base->_ImportOverlays();
diff --git a/lib/RT/Principal.pm b/lib/RT/Principal.pm
index e87a3cb..14b0e74 100644
--- a/lib/RT/Principal.pm
+++ b/lib/RT/Principal.pm
@@ -576,14 +576,17 @@ sub _HasRoleRightQuery {
     ;
 
     if ( $args{'Roles'} ) {
-        $query .= "AND (" . join( ' OR ', map "Groups.Name = '$_'", @{ $args{'Roles'} } ) . ")";
+        $query .= "AND (" . join( ' OR ',
+            map $RT::Handle->__MakeClauseCaseInsensitive('Groups.Name', '=', "'$_'"),
+            @{ $args{'Roles'} }
+        ) . ")";
     }
 
     my (@object_clauses);
     foreach my $obj ( @{ $args{'EquivObjects'} } ) {
         my $type = ref($obj) ? ref($obj) : $obj;
 
-        my $clause = "Groups.Domain = '$type-Role'";
+        my $clause = $RT::Handle->__MakeClauseCaseInsensitive('Groups.Domain', '=', "'$type-Role'");
 
         if ( my $id = eval { $obj->id } ) {
             $clause .= " AND Groups.Instance = $id";
diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index f00b1f4..2bc21ee 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -440,7 +440,9 @@ sub WhoHaveRoleRight
                   VALUE => RT->SystemUser->id
                 );
 
-    $self->_AddSubClause( "WhichRole", "(". join( ' OR ', map "$groups.Name = '$_'", @roles ) .")" );
+    $self->_AddSubClause( "WhichRole", "(". join( ' OR ',
+        map $RT::Handle->__MakeClauseCaseInsensitive("$groups.Name", '=', "'$_'"), @roles
+    ) .")" );
 
     my @groups_clauses = $self->_RoleClauses( $groups, @objects );
     $self->_AddSubClause( "WhichObject", "(". join( ' OR ', @groups_clauses ) .")" )
@@ -460,7 +462,7 @@ sub _RoleClauses {
         my $id;
         $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id;
 
-        my $role_clause = "$groups.Domain = '$type-Role'";
+        my $role_clause = $RT::Handle->__MakeClauseCaseInsensitive("$groups.Domain", '=', "'$type-Role'");
         $role_clause   .= " AND $groups.Instance = $id" if $id;
         push @groups_clauses, "($role_clause)";
     }

commit 8af952ea52b7475234ba9903e4f0469be4f8cf5d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri May 31 19:44:24 2013 +0400

    use LimitToUserDefinedGroups method instead of Limit

diff --git a/share/html/Admin/Queues/People.html b/share/html/Admin/Queues/People.html
index 97c7f14..9c17d48 100644
--- a/share/html/Admin/Queues/People.html
+++ b/share/html/Admin/Queues/People.html
@@ -174,11 +174,7 @@ if ( $ARGS{'UserString'} ) {
 
 if ( $ARGS{'GroupString'} ) {
     $Groups = RT::Groups->new( $session{'CurrentUser'} );
-    $Groups->Limit( FIELD    => 'Domain',
-                    OPERATOR => '=',
-                    VALUE    => 'UserDefined',
-                    CASESENSITIVE => 0,
-                  );
+    $Groups->LimitToUserDefinedGroups;
     $Groups->Limit( FIELD    => $ARGS{'GroupField'},
                     VALUE    => $ARGS{'GroupString'},
                     OPERATOR => $ARGS{'GroupOp'}
diff --git a/share/html/Ticket/Elements/AddWatchers b/share/html/Ticket/Elements/AddWatchers
index 8055e24..28e2d4b 100644
--- a/share/html/Ticket/Elements/AddWatchers
+++ b/share/html/Ticket/Elements/AddWatchers
@@ -116,7 +116,7 @@ if ($UserString) {
 
 if ($GroupString) {
     $Groups = RT::Groups->new($session{'CurrentUser'});
-    $Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0);
+    $Groups->LimitToUserDefinedGroups;
     $Groups->Limit(FIELD => $GroupField, VALUE => $GroupString, OPERATOR => $GroupOp);
      }
 
diff --git a/t/web/owner_disabled_group_19221.t b/t/web/owner_disabled_group_19221.t
index 73b3194..b71fc5b 100644
--- a/t/web/owner_disabled_group_19221.t
+++ b/t/web/owner_disabled_group_19221.t
@@ -122,7 +122,7 @@ diag "Check WithMember and WithoutMember recursively";
 {
     my $with = RT::Groups->new( RT->SystemUser );
     $with->WithMember( PrincipalId => $user->PrincipalObj->Id, Recursively => 1 );
-    $with->Limit( FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0 );
+    $with->LimitToUserDefinedGroups;
     is_deeply(
         [map {$_->Name} @{$with->ItemsArrayRef}],
         ['Disabled Group','Supergroup'],
@@ -131,7 +131,7 @@ diag "Check WithMember and WithoutMember recursively";
 
     my $without = RT::Groups->new( RT->SystemUser );
     $without->WithoutMember( PrincipalId => $user->PrincipalObj->Id, Recursively => 1 );
-    $without->Limit( FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0 );
+    $without->LimitToUserDefinedGroups;
     is_deeply(
         [map {$_->Name} @{$without->ItemsArrayRef}],
         [],

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


More information about the Rt-commit mailing list