import of rt 3.0.4
[freeside.git] / rt / lib / RT / Users_Overlay.pm
1 # BEGIN LICENSE BLOCK
2
3 # Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
4
5 # (Except where explictly superceded by other copyright notices)
6
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
10 # from www.gnu.org
11
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.
16
17
18 # Unless otherwise specified, all modifications, corrections or
19 # extensions to this work which alter its source code become the
20 # property of Best Practical Solutions, LLC when submitted for
21 # inclusion in the work.
22
23
24 # END LICENSE BLOCK
25 =head1 NAME
26
27   RT::Users - Collection of RT::User objects
28
29 =head1 SYNOPSIS
30
31   use RT::Users;
32
33
34 =head1 DESCRIPTION
35
36
37 =head1 METHODS
38
39 =begin testing
40
41 ok(require RT::Users);
42
43 =end testing
44
45 =cut
46
47 use strict;
48 no warnings qw(redefine);
49
50 # {{{ sub _Init 
51 sub _Init {
52     my $self = shift;
53     $self->{'table'} = 'Users';
54         $self->{'primary_key'} = 'id';
55
56
57
58     my @result =          $self->SUPER::_Init(@_);
59     # By default, order by name
60     $self->OrderBy( ALIAS => 'main',
61                     FIELD => 'Name',
62                     ORDER => 'ASC' );
63
64     $self->{'princalias'} = $self->NewAlias('Principals');
65
66     $self->Join( ALIAS1 => 'main',
67                  FIELD1 => 'id',
68                  ALIAS2 => $self->{'princalias'},
69                  FIELD2 => 'id' );
70
71     $self->Limit( ALIAS    => $self->{'princalias'},
72                   FIELD    => 'PrincipalType',
73                   OPERATOR => '=',
74                   VALUE    => 'User' );
75     return (@result);
76 }
77
78 # }}}
79
80 # {{{ sub _DoSearch 
81
82 =head2 _DoSearch
83
84   A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
85 we're explicitly trying to see them.
86
87 =cut
88
89 sub _DoSearch {
90     my $self = shift;
91
92     #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
93     unless ( $self->{'find_disabled_rows'} ) {
94         $self->LimitToEnabled();
95     }
96     return ( $self->SUPER::_DoSearch(@_) );
97
98 }
99
100 # }}}
101 # {{{ sub LimitToEnabled
102
103 =head2 LimitToEnabled
104
105 Only find items that haven\'t been disabled
106
107 =cut
108
109 sub LimitToEnabled {
110     my $self = shift;
111
112     $self->Limit( ALIAS    => $self->{'princalias'},
113                   FIELD    => 'Disabled',
114                   VALUE    => '0',
115                   OPERATOR => '=' );
116 }
117
118 # }}}
119
120 # {{{ LimitToEmail
121
122 =head2 LimitToEmail
123
124 Takes one argument. an email address. limits the returned set to
125 that email address
126
127 =cut
128
129 sub LimitToEmail {
130     my $self = shift;
131     my $addr = shift;
132     $self->Limit( FIELD => 'EmailAddress', VALUE => "$addr" );
133 }
134
135 # }}}
136
137 # {{{ MemberOfGroup
138
139 =head2 MemberOfGroup PRINCIPAL_ID
140
141 takes one argument, a group's principal id. Limits the returned set
142 to members of a given group
143
144 =cut
145
146 sub MemberOfGroup {
147     my $self  = shift;
148     my $group = shift;
149
150     return $self->loc("No group specified") if ( !defined $group );
151
152     my $groupalias = $self->NewAlias('CachedGroupMembers');
153
154     # Join the principal to the groups table
155     $self->Join( ALIAS1 => $self->{'princalias'},
156                  FIELD1 => 'id',
157                  ALIAS2 => $groupalias,
158                  FIELD2 => 'MemberId' );
159
160     $self->Limit( ALIAS    => "$groupalias",
161                   FIELD    => 'GroupId',
162                   VALUE    => "$group",
163                   OPERATOR => "=" );
164 }
165
166 # }}}
167
168 # {{{ LimitToPrivileged
169
170 =head2 LimitToPrivileged
171
172 Limits to users who can be made members of ACLs and groups
173
174 =cut
175
176 sub LimitToPrivileged {
177     my $self = shift;
178
179     my $priv = RT::Group->new( $self->CurrentUser );
180     $priv->LoadSystemInternalGroup('Privileged');
181     unless ( $priv->Id ) {
182         $RT::Logger->crit("Couldn't find a privileged users group");
183     }
184     $self->MemberOfGroup( $priv->PrincipalId );
185 }
186
187 # }}}
188
189 # {{{ WhoHaveRight
190
191 =head2 WhoHaveRight { Right => 'name', Object => $rt_object , IncludeSuperusers => undef, IncludeSubgroupMembers => undef, IncludeSystemRights => undef }
192
193 =begin testing
194
195 ok(my $users = RT::Users->new($RT::SystemUser));
196 $users->WhoHaveRight(Object =>$RT::System, Right =>'SuperUser');
197 ok($users->Count == 1, "There is one privileged superuser - Found ". $users->Count );
198 # TODO: this wants more testing
199
200
201 =end testing
202
203
204 find all users who the right Right for this group, either individually
205 or as members of groups
206
207
208
209
210
211 =cut
212
213 sub WhoHaveRight {
214     my $self = shift;
215     my %args = ( Right                  => undef,
216                  Object =>              => undef,
217                  IncludeSystemRights    => undef,
218                  IncludeSuperusers      => undef,
219                  IncludeSubgroupMembers => 1,
220                  @_ );
221
222     if (defined $args{'ObjectType'} || defined $args{'ObjectId'}) {
223         $RT::Logger->crit("$self WhoHaveRight called with the Obsolete ObjectId/ObjectType API");
224         return(undef);
225     }
226         my @privgroups;
227         my $Groups = RT::Groups->new($RT::SystemUser);
228         $Groups->WithRight(Right=> $args{'Right'},
229                      Object => $args{'Object'},
230                      IncludeSystemRights => $args{'IncludeSystemRights'},
231                      IncludeSuperusers => $args{'IncludeSuperusers'});
232         while (my $Group = $Groups->Next()) {
233                 push @privgroups, $Group->Id();
234         }
235
236         $self->WhoBelongToGroups(Groups => \@privgroups,
237                                  IncludeSubgroupMembers => $args{'IncludeSubgroupMembers'});
238 }
239
240 # }}}
241
242 # {{{ WhoBelongToGroups 
243
244 =head2 WhoBelongToGroups { Groups => ARRAYREF, IncludeSubgroupMembers => 1 }
245
246 =cut
247
248 sub WhoBelongToGroups {
249     my $self = shift;
250     my %args = ( Groups                 => undef,
251                  IncludeSubgroupMembers => 1,
252                  @_ );
253
254     # Unprivileged users can't be granted real system rights. 
255     # is this really the right thing to be saying?
256     $self->LimitToPrivileged();
257
258     my $userprinc  = $self->{'princalias'};
259     my $cgm;
260
261     # The cachedgroupmembers table is used for unrolling group memberships to allow fast lookups 
262     # if we bind to CachedGroupMembers, we'll find all members of groups recursively.
263     # if we don't we'll find only 'direct' members of the group in question
264
265     if ( $args{'IncludeSubgroupMembers'} ) {
266         $cgm = $self->NewAlias('CachedGroupMembers');
267     }
268     else {
269         $cgm = $self->NewAlias('GroupMembers');
270     }
271
272     # {{{ Tie the users we're returning ($userprinc) to the groups that have rights granted to them ($groupprinc)
273     $self->Join( ALIAS1 => $cgm, FIELD1 => 'MemberId',
274                  ALIAS2 => $userprinc, FIELD2 => 'id' );
275     # }}} 
276
277  #   my $and_check_groups = "($cgm.GroupId = NULL";
278     foreach my $groupid (@{$args{'Groups'}}) {
279         $self->Limit(ALIAS => $cgm, FIELD => 'GroupId', VALUE => $groupid, QUOTEVALUE => 0, ENTRYAGGREGATOR=> 'OR')
280
281         #$and_check_groups .= " OR $cgm.GroupId = $groupid";
282     }
283     #$and_check_groups .= ")";
284
285     #$self->_AddSubClause("WhichGroup", $and_check_groups);
286 }
287 # }}}
288
289
290 1;