import rt 3.2.2
[freeside.git] / rt / lib / RT / Users_Overlay.pm
1 # {{{ BEGIN BPS TAGGED BLOCK
2
3 # COPYRIGHT:
4 #  
5 # This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC 
6 #                                          <jesse@bestpractical.com>
7
8 # (Except where explicitly superseded by other copyright notices)
9
10
11 # LICENSE:
12
13 # This work is made available to you under the terms of Version 2 of
14 # the GNU General Public License. A copy of that license should have
15 # been provided with this software, but in any event can be snarfed
16 # from www.gnu.org.
17
18 # This work is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 # General Public License for more details.
22
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27
28 # CONTRIBUTION SUBMISSION POLICY:
29
30 # (The following paragraph is not intended to limit the rights granted
31 # to you to modify and distribute this software under the terms of
32 # the GNU General Public License and is only of importance to you if
33 # you choose to contribute your changes and enhancements to the
34 # community by submitting them to Best Practical Solutions, LLC.)
35
36 # By intentionally submitting any modifications, corrections or
37 # derivatives to this work, or any other work intended for use with
38 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
39 # you are the copyright holder for those contributions and you grant
40 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
41 # royalty-free, perpetual, license to use, copy, create derivative
42 # works based on those contributions, and sublicense and distribute
43 # those contributions and any derivatives thereof.
44
45 # }}} END BPS TAGGED BLOCK
46 =head1 NAME
47
48   RT::Users - Collection of RT::User objects
49
50 =head1 SYNOPSIS
51
52   use RT::Users;
53
54
55 =head1 DESCRIPTION
56
57
58 =head1 METHODS
59
60 =begin testing
61
62 ok(require RT::Users);
63
64 =end testing
65
66 =cut
67
68 use strict;
69 no warnings qw(redefine);
70
71 # {{{ sub _Init 
72 sub _Init {
73     my $self = shift;
74     $self->{'table'} = 'Users';
75         $self->{'primary_key'} = 'id';
76
77
78
79     my @result =          $self->SUPER::_Init(@_);
80     # By default, order by name
81     $self->OrderBy( ALIAS => 'main',
82                     FIELD => 'Name',
83                     ORDER => 'ASC' );
84
85     $self->{'princalias'} = $self->NewAlias('Principals');
86
87     $self->Join( ALIAS1 => 'main',
88                  FIELD1 => 'id',
89                  ALIAS2 => $self->{'princalias'},
90                  FIELD2 => 'id' );
91
92     return (@result);
93 }
94
95 # }}}
96
97 =head2 PrincipalsAlias
98
99 Returns the string that represents this Users object's primary "Principals" alias.
100
101
102 =cut
103
104 sub PrincipalsAlias {
105     my $self = shift;
106     return($self->{'princalias'});
107
108 }
109
110
111 # {{{ sub _DoSearch 
112
113 =head2 _DoSearch
114
115   A subclass of DBIx::SearchBuilder::_DoSearch that makes sure that _Disabled rows never get seen unless
116 we're explicitly trying to see them.
117
118 =cut
119
120 sub _DoSearch {
121     my $self = shift;
122
123     #unless we really want to find disabled rows, make sure we\'re only finding enabled ones.
124     unless ( $self->{'find_disabled_rows'} ) {
125         $self->LimitToEnabled();
126     }
127     return ( $self->SUPER::_DoSearch(@_) );
128
129 }
130
131 # }}}
132 # {{{ sub LimitToEnabled
133
134 =head2 LimitToEnabled
135
136 Only find items that haven\'t been disabled
137
138 =cut
139
140 sub LimitToEnabled {
141     my $self = shift;
142
143     $self->Limit( ALIAS    => $self->{'princalias'},
144                   FIELD    => 'Disabled',
145                   VALUE    => '0',
146                   OPERATOR => '=' );
147 }
148
149 # }}}
150
151 # {{{ LimitToEmail
152
153 =head2 LimitToEmail
154
155 Takes one argument. an email address. limits the returned set to
156 that email address
157
158 =cut
159
160 sub LimitToEmail {
161     my $self = shift;
162     my $addr = shift;
163     $self->Limit( FIELD => 'EmailAddress', VALUE => "$addr" );
164 }
165
166 # }}}
167
168 # {{{ MemberOfGroup
169
170 =head2 MemberOfGroup PRINCIPAL_ID
171
172 takes one argument, a group's principal id. Limits the returned set
173 to members of a given group
174
175 =cut
176
177 sub MemberOfGroup {
178     my $self  = shift;
179     my $group = shift;
180
181     return $self->loc("No group specified") if ( !defined $group );
182
183     my $groupalias = $self->NewAlias('CachedGroupMembers');
184
185     # Join the principal to the groups table
186     $self->Join( ALIAS1 => $self->{'princalias'},
187                  FIELD1 => 'id',
188                  ALIAS2 => $groupalias,
189                  FIELD2 => 'MemberId' );
190
191     $self->Limit( ALIAS    => "$groupalias",
192                   FIELD    => 'GroupId',
193                   VALUE    => "$group",
194                   OPERATOR => "=" );
195 }
196
197 # }}}
198
199 # {{{ LimitToPrivileged
200
201 =head2 LimitToPrivileged
202
203 Limits to users who can be made members of ACLs and groups
204
205 =cut
206
207 sub LimitToPrivileged {
208     my $self = shift;
209
210     my $priv = RT::Group->new( $self->CurrentUser );
211     $priv->LoadSystemInternalGroup('Privileged');
212     unless ( $priv->Id ) {
213         $RT::Logger->crit("Couldn't find a privileged users group");
214     }
215     $self->MemberOfGroup( $priv->PrincipalId );
216 }
217
218 # }}}
219
220 # {{{ WhoHaveRight
221
222 =head2 WhoHaveRight { Right => 'name', Object => $rt_object , IncludeSuperusers => undef, IncludeSubgroupMembers => undef, IncludeSystemRights => undef }
223
224 =begin testing
225
226 ok(my $users = RT::Users->new($RT::SystemUser));
227 $users->WhoHaveRight(Object =>$RT::System, Right =>'SuperUser');
228 ok($users->Count == 1, "There is one privileged superuser - Found ". $users->Count );
229 # TODO: this wants more testing
230
231
232 =end testing
233
234
235 find all users who the right Right for this group, either individually
236 or as members of groups
237
238
239
240
241
242 =cut
243
244 sub WhoHaveRight {
245     my $self = shift;
246     my %args = ( Right                  => undef,
247                  Object =>              => undef,
248                  IncludeSystemRights    => undef,
249                  IncludeSuperusers      => undef,
250                  IncludeSubgroupMembers => 1,
251                  @_ );
252
253     if (defined $args{'ObjectType'} || defined $args{'ObjectId'}) {
254         $RT::Logger->crit("$self WhoHaveRight called with the Obsolete ObjectId/ObjectType API");
255         return(undef);
256     }
257         my @privgroups;
258         my $Groups = RT::Groups->new($RT::SystemUser);
259         $Groups->WithRight(Right=> $args{'Right'},
260                      Object => $args{'Object'},
261                      IncludeSystemRights => $args{'IncludeSystemRights'},
262                      IncludeSuperusers => $args{'IncludeSuperusers'});
263         while (my $Group = $Groups->Next()) {
264                 push @privgroups, $Group->Id();
265         }
266
267
268     if (@privgroups) {
269         $self->WhoBelongToGroups(Groups => \@privgroups,
270                                  IncludeSubgroupMembers => $args{'IncludeSubgroupMembers'});
271     }
272     else {
273         # We don't have any group that matches -- make it impossible.
274         $self->Limit( FIELD => 'Id', VALUE => 'IS', OPERATOR => 'NULL' );
275     }
276 }
277
278 # }}}
279
280 # {{{ WhoBelongToGroups 
281
282 =head2 WhoBelongToGroups { Groups => ARRAYREF, IncludeSubgroupMembers => 1 }
283
284 =cut
285
286 sub WhoBelongToGroups {
287     my $self = shift;
288     my %args = ( Groups                 => undef,
289                  IncludeSubgroupMembers => 1,
290                  @_ );
291
292     # Unprivileged users can't be granted real system rights. 
293     # is this really the right thing to be saying?
294     $self->LimitToPrivileged();
295
296     my $userprinc  = $self->{'princalias'};
297     my $cgm;
298
299     # The cachedgroupmembers table is used for unrolling group memberships to allow fast lookups 
300     # if we bind to CachedGroupMembers, we'll find all members of groups recursively.
301     # if we don't we'll find only 'direct' members of the group in question
302
303     if ( $args{'IncludeSubgroupMembers'} ) {
304         $cgm = $self->NewAlias('CachedGroupMembers');
305     }
306     else {
307         $cgm = $self->NewAlias('GroupMembers');
308     }
309
310     # {{{ Tie the users we're returning ($userprinc) to the groups that have rights granted to them ($groupprinc)
311     $self->Join( ALIAS1 => $cgm, FIELD1 => 'MemberId',
312                  ALIAS2 => $userprinc, FIELD2 => 'id' );
313     # }}} 
314
315  #   my $and_check_groups = "($cgm.GroupId = NULL";
316     foreach my $groupid (@{$args{'Groups'}}) {
317         $self->Limit(ALIAS => $cgm, FIELD => 'GroupId', VALUE => $groupid, QUOTEVALUE => 0, ENTRYAGGREGATOR=> 'OR')
318
319         #$and_check_groups .= " OR $cgm.GroupId = $groupid";
320     }
321     #$and_check_groups .= ")";
322
323     #$self->_AddSubClause("WhichGroup", $and_check_groups);
324 }
325 # }}}
326
327
328 1;