import rt 3.2.2
[freeside.git] / rt / lib / RT / CurrentUser.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::CurrentUser - an RT object representing the current user
49
50 =head1 SYNOPSIS
51
52   use RT::CurrentUser
53
54
55 =head1 DESCRIPTION
56
57
58 =head1 METHODS
59
60
61 =begin testing
62
63 ok (require RT::CurrentUser);
64
65 =end testing
66
67 =cut
68
69
70 package RT::CurrentUser;
71
72 use RT::Record;
73 use RT::I18N;
74
75 use strict;
76 use base qw/RT::Record/;
77
78 # {{{ sub _Init 
79
80 #The basic idea here is that $self->CurrentUser is always supposed
81 # to be a CurrentUser object. but that's hard to do when we're trying to load
82 # the CurrentUser object
83
84 sub _Init {
85     my $self = shift;
86     my $User = shift;
87
88     $self->{'table'} = "Users";
89
90     if ( defined($User) ) {
91
92         if (   UNIVERSAL::isa( $User, 'RT::User' )
93             || UNIVERSAL::isa( $User, 'RT::CurrentUser' ) )
94         {
95             $self->Load( $User->id );
96
97         }
98         elsif ( ref($User) ) {
99             $RT::Logger->crit(
100                 "RT::CurrentUser->new() called with a bogus argument: $User");
101         }
102         else {
103             $self->Load($User);
104         }
105     }
106
107     $self->_BuildTableAttributes();
108
109 }
110 # }}}
111
112 # {{{ sub Create
113
114 sub Create {
115     my $self = shift;
116     return (0, $self->loc('Permission Denied'));
117 }
118
119 # }}}
120
121 # {{{ sub Delete
122
123 sub Delete {
124     my $self = shift;
125     return (0, $self->loc('Permission Denied'));
126 }
127
128 # }}}
129
130 # {{{ sub UserObj
131
132 =head2 UserObj
133
134   Returns the RT::User object associated with this CurrentUser object.
135
136 =cut
137
138 sub UserObj {
139     my $self = shift;
140     
141         use RT::User;
142         my $user = RT::User->new($self);
143
144         unless ($user->Load($self->Id)) {
145             $RT::Logger->err($self->loc("Couldn't load [_1] from the users database.\n", $self->Id));
146         }
147     return ($user);
148 }
149 # }}}
150
151 # {{{ sub PrincipalObj 
152
153 =head2 PrincipalObj
154
155     Returns this user's principal object.  this is just a helper routine for
156     $self->UserObj->PrincipalObj
157
158 =cut
159
160 sub PrincipalObj {
161     my $self = shift;
162     return($self->UserObj->PrincipalObj);
163 }
164
165
166 # }}}
167
168
169 # {{{ sub PrincipalId 
170
171 =head2 PrincipalId
172
173     Returns this user's principal Id.  this is just a helper routine for
174     $self->UserObj->PrincipalId
175
176 =cut
177
178 sub PrincipalId {
179     my $self = shift;
180     return($self->UserObj->PrincipalId);
181 }
182
183
184 # }}}
185
186
187 # {{{ sub _Accessible 
188
189
190  sub _CoreAccessible  {
191      {
192          Name           => { 'read' => 1 },
193            Gecos        => { 'read' => 1 },
194            RealName     => { 'read' => 1 },
195            Lang     => { 'read' => 1 },
196            Password     => { 'read' => 0, 'write' => 0 },
197           EmailAddress => { 'read' => 1, 'write' => 0 }
198      };
199   
200 }
201 # }}}
202
203 # {{{ sub LoadByEmail
204
205 =head2 LoadByEmail
206
207 Loads a User into this CurrentUser object.
208 Takes the email address of the user to load.
209
210 =cut
211
212 sub LoadByEmail  {
213     my $self = shift;
214     my $identifier = shift;
215
216     $identifier = RT::User::CanonicalizeEmailAddress(undef, $identifier);
217         
218     $self->LoadByCol("EmailAddress",$identifier);
219     
220 }
221 # }}}
222
223 # {{{ sub LoadByGecos
224
225 =head2 LoadByGecos
226
227 Loads a User into this CurrentUser object.
228 Takes a unix username as its only argument.
229
230 =cut
231
232 sub LoadByGecos  {
233     my $self = shift;
234     my $identifier = shift;
235         
236     $self->LoadByCol("Gecos",$identifier);
237     
238 }
239 # }}}
240
241 # {{{ sub LoadByName
242
243 =head2 LoadByName
244
245 Loads a User into this CurrentUser object.
246 Takes a Name.
247 =cut
248
249 sub LoadByName {
250     my $self = shift;
251     my $identifier = shift;
252     $self->LoadByCol("Name",$identifier);
253     
254 }
255 # }}}
256
257 # {{{ sub Load 
258
259 =head2 Load
260
261 Loads a User into this CurrentUser object.
262 Takes either an integer (users id column reference) or a Name
263 The latter is deprecated. Instead, you should use LoadByName.
264 Formerly, this routine also took email addresses. 
265
266 =cut
267
268 sub Load  {
269   my $self = shift;
270   my $identifier = shift;
271
272   #if it's an int, load by id. otherwise, load by name.
273   if ($identifier !~ /\D/) {
274     $self->SUPER::LoadById($identifier);
275   }
276
277   elsif (UNIVERSAL::isa($identifier,"RT::User")) {
278          # DWIM if they pass a user in
279          $self->SUPER::LoadById($identifier->Id);
280   } 
281   else {
282       # This is a bit dangerous, we might get false authen if somebody
283       # uses ambigous userids or real names:
284       $self->LoadByCol("Name",$identifier);
285   }
286 }
287
288 # }}}
289
290 # {{{ sub IsPassword
291
292 =head2 IsPassword
293
294 Takes a password as a string.  Passes it off to IsPassword in this
295 user's UserObj.  If it is the user's password and the user isn't
296 disabled, returns 1.
297
298 Otherwise, returns undef.
299
300 =cut
301
302 sub IsPassword { 
303   my $self = shift;
304   my $value = shift;
305   
306   return ($self->UserObj->IsPassword($value)); 
307 }
308
309 # }}}
310
311 # {{{ sub Privileged
312
313 =head2 Privileged
314
315 Returns true if the current user can be granted rights and be
316 a member of groups.
317
318 =cut
319
320 sub Privileged {
321     my $self = shift;
322     return ($self->UserObj->Privileged());
323 }
324
325 # }}}
326
327
328 # {{{ sub HasRight
329
330 =head2 HasRight
331
332 calls $self->UserObj->HasRight with the arguments passed in
333
334 =cut
335
336 sub HasRight {
337   my $self = shift;
338   return ($self->UserObj->HasRight(@_));
339 }
340
341 # }}}
342
343 # {{{ Localization
344
345 =head2 LanguageHandle
346
347 Returns this current user's langauge handle. Should take a language
348 specification. but currently doesn't
349
350 =begin testing
351
352 ok (my $cu = RT::CurrentUser->new('root'));
353 ok (my $lh = $cu->LanguageHandle);
354 ok ($lh != undef);
355 ok ($lh->isa('Locale::Maketext'));
356 ok ($cu->loc('TEST_STRING') eq "Concrete Mixer", "Localized TEST_STRING into English");
357 ok ($lh = $cu->LanguageHandle('fr'));
358 ok ($cu->loc('Before') eq "Avant", "Localized TEST_STRING into Frenc");
359
360 =end testing
361
362 =cut 
363
364 sub LanguageHandle {
365     my $self = shift;
366     if (   ( !defined $self->{'LangHandle'} )
367         || ( !UNIVERSAL::can( $self->{'LangHandle'}, 'maketext' ) )
368         || (@_) ) {
369         if ( (!$RT::SystemUser || $self->id == $RT::SystemUser->id() )) {
370             @_ = qw(en-US);
371         }
372
373         elsif ( $self->Lang ) {
374             push @_, $self->Lang;
375         }
376         $self->{'LangHandle'} = RT::I18N->get_handle(@_);
377     }
378
379     # Fall back to english.
380     unless ( $self->{'LangHandle'} ) {
381         die "We couldn't get a dictionary. Nye mogu naidti slovar. No puedo encontrar dictionario.";
382     }
383     return ( $self->{'LangHandle'} );
384 }
385
386 sub loc {
387     my $self = shift;
388     return '' if $_[0] eq '';
389
390     my $handle = $self->LanguageHandle;
391
392     if (@_ == 1) {
393         # pre-scan the lexicon hashes to return _AUTO keys verbatim,
394         # to keep locstrings containing '[' and '~' from tripping over Maketext
395         return $_[0] unless grep { exists $_->{$_[0]} } @{ $handle->_lex_refs };
396     }
397
398     return $handle->maketext(@_);
399 }
400
401 sub loc_fuzzy {
402     my $self = shift;
403     return '' if $_[0] eq '';
404
405     # XXX: work around perl's deficiency when matching utf8 data
406     return $_[0] if Encode::is_utf8($_[0]);
407     my $result = $self->LanguageHandle->maketext_fuzzy(@_);
408
409     return($result);
410 }
411 # }}}
412
413
414 =head2 CurrentUser
415
416 Return  the current currentuser object
417
418 =cut
419
420 sub CurrentUser {
421     my $self = shift;
422     return($self);
423
424 }
425
426
427 eval "require RT::CurrentUser_Vendor";
428 die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Vendor.pm});
429 eval "require RT::CurrentUser_Local";
430 die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Local.pm});
431
432 1;
433