import of rt 3.0.9
[freeside.git] / rt / lib / RT / Users_Overlay.pm
1 # BEGIN LICENSE BLOCK
2
3 # Copyright (c) 1996-2003 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 # 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.
21
22
23 # END LICENSE BLOCK
24 =head1 NAME
25
26   RT::Users - Collection of RT::User objects
27
28 =head1 SYNOPSIS
29
30   use RT::Users;
31
32
33 =head1 DESCRIPTION
34
35
36 =head1 METHODS
37
38 =begin testing
39
40 ok(require RT::Users);
41
42 =end testing
43
44 =cut
45
46 use strict;
47 no warnings qw(redefine);
48
49 # {{{ sub _Init 
50 sub _Init {
51     my $self = shift;
52     $self->{'table'} = 'Users';
53         $self->{'primary_key'} = 'id';
54
55
56
57     my @result =          $self->SUPER::_Init(@_);
58     # By default, order by name
59     $self->OrderBy( ALIAS => 'main',
60                     FIELD => 'Name',
61                     ORDER => 'ASC' );
62
63     $self->{'princalias'} = $self->NewAlias('Principals');
64
65     $self->Join( ALIAS1 => 'main',
66                  FIELD1 => 'id',
67                  ALIAS2 => $self->{'princalias'},
68                  FIELD2 => 'id' );
69
70     $self->Limit( ALIAS    => $self->{'princalias'},
71                   FIELD    => 'PrincipalType',
72                   OPERATOR => '=',
73                   VALUE    => 'User' );
74     return (@result);
75 }
76
77 # }}}
78
79 =head2 PrincipalsAlias
80
81 Returns the string that represents this Users object's primary "Principals" alias.
82
83
84 =cut
85
86 sub PrincipalsAlias {
87     my $self = shift;
88     return($self->{'princalias'});
89
90 }
91
92
93 # {{{ sub _DoSearch 
94
95 =head2 _DoSearch
96
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.
99
100 =cut
101
102 sub _DoSearch {
103     my $self = shift;
104
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();
108     }
109     return ( $self->SUPER::_DoSearch(@_) );
110
111 }
112
113 # }}}
114 # {{{ sub LimitToEnabled
115
116 =head2 LimitToEnabled
117
118 Only find items that haven\'t been disabled
119
120 =cut
121
122 sub LimitToEnabled {
123     my $self = shift;
124
125     $self->Limit( ALIAS    => $self->{'princalias'},
126                   FIELD    => 'Disabled',
127                   VALUE    => '0',
128                   OPERATOR => '=' );
129 }
130
131 # }}}
132
133 # {{{ LimitToEmail
134
135 =head2 LimitToEmail
136
137 Takes one argument. an email address. limits the returned set to
138 that email address
139
140 =cut
141
142 sub LimitToEmail {
143     my $self = shift;
144     my $addr = shift;
145     $self->Limit( FIELD => 'EmailAddress', VALUE => "$addr" );
146 }
147
148 # }}}
149
150 # {{{ MemberOfGroup
151
152 =head2 MemberOfGroup PRINCIPAL_ID
153
154 takes one argument, a group's principal id. Limits the returned set
155 to members of a given group
156
157 =cut
158
159 sub MemberOfGroup {
160     my $self  = shift;
161     my $group = shift;
162
163     return $self->loc("No group specified") if ( !defined $group );
164
165     my $groupalias = $self->NewAlias('CachedGroupMembers');
166
167     # Join the principal to the groups table
168     $self->Join( ALIAS1 => $self->{'princalias'},
169                  FIELD1 => 'id',
170                  ALIAS2 => $groupalias,
171                  FIELD2 => 'MemberId' );
172
173     $self->Limit( ALIAS    => "$groupalias",
174                   FIELD    => 'GroupId',
175                   VALUE    => "$group",
176                   OPERATOR => "=" );
177 }
178
179 # }}}
180
181 # {{{ LimitToPrivileged
182
183 =head2 LimitToPrivileged
184
185 Limits to users who can be made members of ACLs and groups
186
187 =cut
188
189 sub LimitToPrivileged {
190     my $self = shift;
191
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");
196     }
197     $self->MemberOfGroup( $priv->PrincipalId );
198 }
199
200 # }}}
201
202 # {{{ WhoHaveRight
203
204 =head2 WhoHaveRight { Right => 'name', Object => $rt_object , IncludeSuperusers => undef, IncludeSubgroupMembers => undef, IncludeSystemRights => undef }
205
206 =begin testing
207
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
212
213
214 =end testing
215
216
217 find all users who the right Right for this group, either individually
218 or as members of groups
219
220
221
222
223
224 =cut
225
226 sub WhoHaveRight {
227     my $self = shift;
228     my %args = ( Right                  => undef,
229                  Object =>              => undef,
230                  IncludeSystemRights    => undef,
231                  IncludeSuperusers      => undef,
232                  IncludeSubgroupMembers => 1,
233                  @_ );
234
235     if (defined $args{'ObjectType'} || defined $args{'ObjectId'}) {
236         $RT::Logger->crit("$self WhoHaveRight called with the Obsolete ObjectId/ObjectType API");
237         return(undef);
238     }
239         my @privgroups;
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();
247         }
248
249
250     if (@privgroups) {
251         $self->WhoBelongToGroups(Groups => \@privgroups,
252                                  IncludeSubgroupMembers => $args{'IncludeSubgroupMembers'});
253     }
254     else {
255         # We don't have any group that matches -- make it impossible.
256         $self->Limit( FIELD => 'Id', VALUE => 'IS', OPERATOR => 'NULL' );
257     }
258 }
259
260 # }}}
261
262 # {{{ WhoBelongToGroups 
263
264 =head2 WhoBelongToGroups { Groups => ARRAYREF, IncludeSubgroupMembers => 1 }
265
266 =cut
267
268 sub WhoBelongToGroups {
269     my $self = shift;
270     my %args = ( Groups                 => undef,
271                  IncludeSubgroupMembers => 1,
272                  @_ );
273
274     # Unprivileged users can't be granted real system rights. 
275     # is this really the right thing to be saying?
276     $self->LimitToPrivileged();
277
278     my $userprinc  = $self->{'princalias'};
279     my $cgm;
280
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
284
285     if ( $args{'IncludeSubgroupMembers'} ) {
286         $cgm = $self->NewAlias('CachedGroupMembers');
287     }
288     else {
289         $cgm = $self->NewAlias('GroupMembers');
290     }
291
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' );
295     # }}} 
296
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')
300
301         #$and_check_groups .= " OR $cgm.GroupId = $groupid";
302     }
303     #$and_check_groups .= ")";
304
305     #$self->_AddSubClause("WhichGroup", $and_check_groups);
306 }
307 # }}}
308
309
310 1;