X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Flib%2FRT%2FUsers.pm;h=4fe145589502ac0ad6b0e37844fbf7bc3365d2b9;hp=2784fc75762fec12a3df9dc3eeba63353f8fda5b;hb=f2731f7f3883905cd17633f486d2aeb9593173da;hpb=c24d6e2242ae0e026684b8f95decf156aba6e75e diff --git a/rt/lib/RT/Users.pm b/rt/lib/RT/Users.pm index 2784fc757..4fe145589 100755 --- a/rt/lib/RT/Users.pm +++ b/rt/lib/RT/Users.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -69,10 +69,10 @@ package RT::Users; use strict; use warnings; -use RT::User; - use base 'RT::SearchBuilder'; +use RT::User; + sub Table { 'Users'} @@ -86,12 +86,11 @@ sub _Init { FIELD => 'Name', ORDER => 'ASC' ); - $self->{'princalias'} = $self->NewAlias('Principals'); - # XXX: should be generalized - $self->Join( ALIAS1 => 'main', + $self->{'princalias'} = $self->Join( + ALIAS1 => 'main', FIELD1 => 'id', - ALIAS2 => $self->{'princalias'}, + TABLE2 => 'Principals', FIELD2 => 'id' ); $self->Limit( ALIAS => $self->{'princalias'}, FIELD => 'PrincipalType', @@ -118,7 +117,7 @@ sub PrincipalsAlias { =head2 LimitToEnabled -Only find items that haven\'t been disabled +Only find items that haven't been disabled =cut @@ -163,7 +162,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 ); } @@ -226,7 +225,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 ); } @@ -363,7 +362,7 @@ sub _GetEquivObjects } if( $args{'IncludeSystemRights'} ) { - push @objects, 'RT::System'; + push @objects, $RT::System; } push @objects, @{ $args{'EquivObjects'} }; return grep $_, @objects; @@ -441,7 +440,9 @@ sub WhoHaveRoleRight VALUE => RT->SystemUser->id ); - $self->_AddSubClause( "WhichRole", "(". join( ' OR ', map "$groups.Type = '$_'", @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 ) .")" ) @@ -458,14 +459,12 @@ sub _RoleClauses { my @groups_clauses; foreach my $obj ( @objects ) { my $type = ref($obj)? ref($obj): $obj; - my $id; - $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id; - - my $role_clause = "$groups.Domain = '$type-Role'"; - # XXX: Groups.Instance is VARCHAR in DB, we should quote value - # if we want mysql 4.0 use indexes here. we MUST convert that - # field to integer and drop this quotes. - $role_clause .= " AND $groups.Instance = '$id'" if $id; + + my $role_clause = $RT::Handle->__MakeClauseCaseInsensitive("$groups.Domain", '=', "'$type-Role'"); + + if ( my $id = eval { $obj->id } ) { + $role_clause .= " AND $groups.Instance = $id"; + } push @groups_clauses, "($role_clause)"; } return @groups_clauses; @@ -506,12 +505,14 @@ sub WhoHaveGroupRight my ($check_objects) = (''); my @objects = $self->_GetEquivObjects( %args ); + my %seen; if ( @objects ) { my @object_clauses; foreach my $obj ( @objects ) { my $type = ref($obj)? ref($obj): $obj; - my $id; + my $id = 0; $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id; + next if $seen{"$type-$id"}++; my $object_clause = "$acl.ObjectType = '$type'"; $object_clause .= " AND $acl.ObjectId = $id" if $id; @@ -543,44 +544,135 @@ sub WhoHaveGroupRight } -=head2 WhoBelongToGroups { Groups => ARRAYREF, IncludeSubgroupMembers => 1 } +=head2 WhoBelongToGroups { Groups => ARRAYREF, IncludeSubgroupMembers => 1, IncludeUnprivileged => 0 } + +Return members who belong to any of the groups passed in the groups whose IDs +are included in the Groups arrayref. + +If IncludeSubgroupMembers is true (default) then members of any group that's a +member of one of the passed groups are returned. If it's cleared then only +direct member users are returned. + +If IncludeUnprivileged is false (default) then only privileged members are +returned; otherwise either privileged or unprivileged group members may be +returned. =cut -# XXX: should be generalized sub WhoBelongToGroups { my $self = shift; my %args = ( Groups => undef, IncludeSubgroupMembers => 1, + IncludeUnprivileged => 0, @_ ); - # Unprivileged users can't be granted real system rights. - # is this really the right thing to be saying? - $self->LimitToPrivileged(); - + if (!$args{'IncludeUnprivileged'}) { + $self->LimitToPrivileged(); + } my $group_members = $self->_JoinGroupMembers( %args ); - foreach my $groupid (@{$args{'Groups'}}) { - $self->Limit( ALIAS => $group_members, - FIELD => 'GroupId', - VALUE => $groupid, - QUOTEVALUE => 0, - ENTRYAGGREGATOR => 'OR', - ); - } + $self->Limit( + ALIAS => $group_members, + FIELD => 'GroupId', + OPERATOR => 'IN', + VALUE => [ 0, @{$args{'Groups'}} ], + ); } +=head2 SimpleSearch + +Does a 'simple' search of Users against a specified Term. + +This Term is compared to a number of fields using various types of SQL +comparison operators. + +Ensures that the returned collection of Users will have a value for Return. -=head2 NewItem +This method is passed the following. You must specify a Term and a Return. -Returns an empty new RT::User item + Privileged - Whether or not to limit to Privileged Users (0 or 1) + Fields - Hashref of data - defaults to C<$UserSearchFields> emulate that if you want to override + Term - String that is in the fields specified by Fields + Return - What field on the User you want to be sure isn't empty + Exclude - Array reference of ids to exclude + Max - What to limit this collection to =cut -sub NewItem { +sub SimpleSearch { my $self = shift; - return(RT::User->new($self->CurrentUser)); + my %args = ( + Privileged => 0, + Fields => RT->Config->Get('UserSearchFields'), + Term => undef, + Exclude => [], + Return => undef, + Max => 10, + @_ + ); + + return $self unless defined $args{Return} + and defined $args{Term} + and length $args{Term}; + + $self->RowsPerPage( $args{Max} ); + + $self->LimitToPrivileged() if $args{Privileged}; + + while (my ($name, $op) = each %{$args{Fields}}) { + $op = 'STARTSWITH' + unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i; + + if ($name =~ /^CF\.(?:\{(.*)}|(.*))$/) { + my $cfname = $1 || $2; + my $cf = RT::CustomField->new(RT->SystemUser); + my ($ok, $msg) = $cf->LoadByName( Name => $cfname, LookupType => 'RT::User'); + if ( $ok ) { + $self->LimitCustomField( + CUSTOMFIELD => $cf->Id, + OPERATOR => $op, + VALUE => $args{Term}, + ENTRYAGGREGATOR => 'OR', + SUBCLAUSE => 'autocomplete', + ); + } else { + RT->Logger->warning("Asked to search custom field $name but unable to load a User CF with the name $cfname: $msg"); + } + } else { + $self->Limit( + FIELD => $name, + OPERATOR => $op, + VALUE => $args{Term}, + ENTRYAGGREGATOR => 'OR', + SUBCLAUSE => 'autocomplete', + ); + } + } + + # Exclude users we don't want + $self->Limit(FIELD => 'id', OPERATOR => 'NOT IN', VALUE => $args{Exclude} ) + if @{$args{Exclude}}; + + if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) { + $self->Limit( + FIELD => $args{Return}, + OPERATOR => 'IS NOT', + VALUE => 'NULL', + ); + } + else { + $self->Limit( FIELD => $args{Return}, OPERATOR => '!=', VALUE => '' ); + $self->Limit( + FIELD => $args{Return}, + OPERATOR => 'IS NOT', + VALUE => 'NULL', + ENTRYAGGREGATOR => 'AND' + ); + } + + return $self; } + RT::Base->_ImportOverlays(); 1;