3 # Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
5 # (Except where explictly superceded by other copyright notices)
7 # This work is made available to you under the terms of Version 2 of
8 # the GNU General Public License. A copy of that license should have
9 # been provided with this software, but in any event can be snarfed
12 # This work is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # General Public License for more details.
17 # Unless otherwise specified, all modifications, corrections or
18 # extensions to this work which alter its source code become the
19 # property of Best Practical Solutions, LLC when submitted for
20 # inclusion in the work.
26 RT::Users - Collection of RT::User objects
40 ok(require RT::Users);
47 no warnings qw(redefine);
52 $self->{'table'} = 'Users';
53 $self->{'primary_key'} = 'id';
57 my @result = $self->SUPER::_Init(@_);
58 # By default, order by name
59 $self->OrderBy( ALIAS => 'main',
63 $self->{'princalias'} = $self->NewAlias('Principals');
65 $self->Join( ALIAS1 => 'main',
67 ALIAS2 => $self->{'princalias'},
70 $self->Limit( ALIAS => $self->{'princalias'},
71 FIELD => 'PrincipalType',
79 =head2 PrincipalsAlias
81 Returns the string that represents this Users object's primary "Principals" alias.
88 return($self->{'princalias'});
97 A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
98 we're explicitly trying to see them.
105 #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
106 unless ( $self->{'find_disabled_rows'} ) {
107 $self->LimitToEnabled();
109 return ( $self->SUPER::_DoSearch(@_) );
114 # {{{ sub LimitToEnabled
116 =head2 LimitToEnabled
118 Only find items that haven\'t been disabled
125 $self->Limit( ALIAS => $self->{'princalias'},
137 Takes one argument. an email address. limits the returned set to
145 $self->Limit( FIELD => 'EmailAddress', VALUE => "$addr" );
152 =head2 MemberOfGroup PRINCIPAL_ID
154 takes one argument, a group's principal id. Limits the returned set
155 to members of a given group
163 return $self->loc("No group specified") if ( !defined $group );
165 my $groupalias = $self->NewAlias('CachedGroupMembers');
167 # Join the principal to the groups table
168 $self->Join( ALIAS1 => $self->{'princalias'},
170 ALIAS2 => $groupalias,
171 FIELD2 => 'MemberId' );
173 $self->Limit( ALIAS => "$groupalias",
181 # {{{ LimitToPrivileged
183 =head2 LimitToPrivileged
185 Limits to users who can be made members of ACLs and groups
189 sub LimitToPrivileged {
192 my $priv = RT::Group->new( $self->CurrentUser );
193 $priv->LoadSystemInternalGroup('Privileged');
194 unless ( $priv->Id ) {
195 $RT::Logger->crit("Couldn't find a privileged users group");
197 $self->MemberOfGroup( $priv->PrincipalId );
204 =head2 WhoHaveRight { Right => 'name', Object => $rt_object , IncludeSuperusers => undef, IncludeSubgroupMembers => undef, IncludeSystemRights => undef }
208 ok(my $users = RT::Users->new($RT::SystemUser));
209 $users->WhoHaveRight(Object =>$RT::System, Right =>'SuperUser');
210 ok($users->Count == 1, "There is one privileged superuser - Found ". $users->Count );
211 # TODO: this wants more testing
217 find all users who the right Right for this group, either individually
218 or as members of groups
228 my %args = ( Right => undef,
230 IncludeSystemRights => undef,
231 IncludeSuperusers => undef,
232 IncludeSubgroupMembers => 1,
235 if (defined $args{'ObjectType'} || defined $args{'ObjectId'}) {
236 $RT::Logger->crit("$self WhoHaveRight called with the Obsolete ObjectId/ObjectType API");
240 my $Groups = RT::Groups->new($RT::SystemUser);
241 $Groups->WithRight(Right=> $args{'Right'},
242 Object => $args{'Object'},
243 IncludeSystemRights => $args{'IncludeSystemRights'},
244 IncludeSuperusers => $args{'IncludeSuperusers'});
245 while (my $Group = $Groups->Next()) {
246 push @privgroups, $Group->Id();
251 $self->WhoBelongToGroups(Groups => \@privgroups,
252 IncludeSubgroupMembers => $args{'IncludeSubgroupMembers'});
255 # We don't have any group that matches -- make it impossible.
256 $self->Limit( FIELD => 'Id', VALUE => 'IS', OPERATOR => 'NULL' );
262 # {{{ WhoBelongToGroups
264 =head2 WhoBelongToGroups { Groups => ARRAYREF, IncludeSubgroupMembers => 1 }
268 sub WhoBelongToGroups {
270 my %args = ( Groups => undef,
271 IncludeSubgroupMembers => 1,
274 # Unprivileged users can't be granted real system rights.
275 # is this really the right thing to be saying?
276 $self->LimitToPrivileged();
278 my $userprinc = $self->{'princalias'};
281 # The cachedgroupmembers table is used for unrolling group memberships to allow fast lookups
282 # if we bind to CachedGroupMembers, we'll find all members of groups recursively.
283 # if we don't we'll find only 'direct' members of the group in question
285 if ( $args{'IncludeSubgroupMembers'} ) {
286 $cgm = $self->NewAlias('CachedGroupMembers');
289 $cgm = $self->NewAlias('GroupMembers');
292 # {{{ Tie the users we're returning ($userprinc) to the groups that have rights granted to them ($groupprinc)
293 $self->Join( ALIAS1 => $cgm, FIELD1 => 'MemberId',
294 ALIAS2 => $userprinc, FIELD2 => 'id' );
297 # my $and_check_groups = "($cgm.GroupId = NULL";
298 foreach my $groupid (@{$args{'Groups'}}) {
299 $self->Limit(ALIAS => $cgm, FIELD => 'GroupId', VALUE => $groupid, QUOTEVALUE => 0, ENTRYAGGREGATOR=> 'OR')
301 #$and_check_groups .= " OR $cgm.GroupId = $groupid";
303 #$and_check_groups .= ")";
305 #$self->_AddSubClause("WhichGroup", $and_check_groups);