74d44e30459c63d099f349477e651ce0b0eb07ba
[freeside.git] / rt / lib / RT / CurrentUser.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2 #
3 # COPYRIGHT:
4 #
5 # This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
6 #                                          <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
26 # 02110-1301 or visit their web page on the internet at
27 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 #
29 #
30 # CONTRIBUTION SUBMISSION POLICY:
31 #
32 # (The following paragraph is not intended to limit the rights granted
33 # to you to modify and distribute this software under the terms of
34 # the GNU General Public License and is only of importance to you if
35 # you choose to contribute your changes and enhancements to the
36 # community by submitting them to Best Practical Solutions, LLC.)
37 #
38 # By intentionally submitting any modifications, corrections or
39 # derivatives to this work, or any other work intended for use with
40 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 # you are the copyright holder for those contributions and you grant
42 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 # royalty-free, perpetual, license to use, copy, create derivative
44 # works based on those contributions, and sublicense and distribute
45 # those contributions and any derivatives thereof.
46 #
47 # END BPS TAGGED BLOCK }}}
48
49 =head1 NAME
50
51   RT::CurrentUser - an RT object representing the current user
52
53 =head1 SYNOPSIS
54
55     use RT::CurrentUser;
56
57     # load
58     my $current_user = RT::CurrentUser->new;
59     $current_user->Load(...);
60     # or
61     my $current_user = RT::CurrentUser->new( $user_obj );
62     # or
63     my $current_user = RT::CurrentUser->new( $address || $name || $id );
64
65     # manipulation
66     $current_user->UserObj->SetName('new_name');
67
68
69 =head1 DESCRIPTION
70
71 B<Read-only> subclass of L<RT::User> class. Used to define the current
72 user. You should pass an instance of this class to constructors of
73 many RT classes, then the instance used to check ACLs and localize
74 strings.
75
76 =head1 METHODS
77
78 See also L<RT::User> for a list of methods this class has.
79
80 =head2 new
81
82 Returns new CurrentUser object. Unlike all other classes of RT it takes
83 either subclass of C<RT::User> class object or scalar value that is
84 passed to Load method.
85
86 =cut
87
88
89 package RT::CurrentUser;
90
91 use strict;
92 use warnings;
93
94 use base qw/RT::User/;
95
96 use RT::I18N;
97
98 #The basic idea here is that $self->CurrentUser is always supposed
99 # to be a CurrentUser object. but that's hard to do when we're trying to load
100 # the CurrentUser object
101
102 sub _Init {
103     my $self = shift;
104     my $User = shift;
105
106     $self->{'table'} = "Users";
107
108     if ( defined $User ) {
109
110         if ( UNIVERSAL::isa( $User, 'RT::User' ) ) {
111             $self->LoadById( $User->id );
112         }
113         elsif ( ref $User ) {
114             $RT::Logger->crit(
115                 "RT::CurrentUser->new() called with a bogus argument: $User");
116         }
117         else {
118             $self->Load( $User );
119         }
120     }
121
122     $self->_BuildTableAttributes;
123
124 }
125
126 =head2 Create, Delete and Set*
127
128 As stated above it's a subclass of L<RT::User>, but this class is read-only
129 and calls to these methods are illegal. Return 'permission denied' message
130 and log an error.
131
132 =cut
133
134 sub Create {
135     my $self = shift;
136     $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation');
137     return (0, $self->loc('Permission Denied'));
138 }
139
140 sub Delete {
141     my $self = shift;
142     $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation');
143     return (0, $self->loc('Permission Denied'));
144 }
145
146 sub _Set {
147     my $self = shift;
148     $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation');
149     return (0, $self->loc('Permission Denied'));
150 }
151
152 =head2 UserObj
153
154 Returns the L<RT::User> object associated with this CurrentUser object.
155
156 =cut
157
158 sub UserObj {
159     my $self = shift;
160
161     my $user = RT::User->new( $self );
162     unless ( $user->LoadById( $self->Id ) ) {
163         $RT::Logger->error("Couldn't load " . $self->Id . " from the users database.");
164     }
165     return $user;
166 }
167
168 sub _CoreAccessible  {
169      {
170          Name           => { 'read' => 1 },
171            Gecos        => { 'read' => 1 },
172            RealName     => { 'read' => 1 },
173            Lang     => { 'read' => 1 },
174            Password     => { 'read' => 0, 'write' => 0 },
175           EmailAddress => { 'read' => 1, 'write' => 0 }
176      };
177   
178 }
179
180 =head2 LoadByGecos
181
182 Loads a User into this CurrentUser object.
183 Takes a unix username as its only argument.
184
185 =cut
186
187 sub LoadByGecos  {
188     my $self = shift;
189     return $self->LoadByCol( "Gecos", shift );
190 }
191
192 =head2 LoadByName
193
194 Loads a User into this CurrentUser object.
195 Takes a Name.
196
197 =cut
198
199 sub LoadByName {
200     my $self = shift;
201     return $self->LoadByCol( "Name", shift );
202 }
203
204 =head2 LanguageHandle
205
206 Returns this current user's langauge handle. Should take a language
207 specification. but currently doesn't
208
209 =cut 
210
211 sub LanguageHandle {
212     my $self = shift;
213     if (   !defined $self->{'LangHandle'}
214         || !UNIVERSAL::can( $self->{'LangHandle'}, 'maketext' )
215         || @_ )
216     {
217         if ( my $lang = $self->Lang ) {
218             push @_, $lang;
219         }
220         elsif ( $self->id && ($self->id == (RT->SystemUser->id||0) || $self->id == (RT->Nobody->id||0)) ) {
221             # don't use ENV magic for system users
222             push @_, 'en';
223         }
224
225         $self->{'LangHandle'} = RT::I18N->get_handle(@_);
226     }
227
228     # Fall back to english.
229     unless ( $self->{'LangHandle'} ) {
230         die "We couldn't get a dictionary. Ne mogu naidti slovar. No puedo encontrar dictionario.";
231     }
232     return $self->{'LangHandle'};
233 }
234
235 sub loc {
236     my $self = shift;
237     return '' if !defined $_[0] || $_[0] eq '';
238
239     my $handle = $self->LanguageHandle;
240
241     if (@_ == 1) {
242         # If we have no [_1] replacements, and the key does not appear
243         # in the lexicon, unescape (using ~) and return it verbatim, as
244         # an optimization.
245         my $unescaped = $_[0];
246         $unescaped =~ s!~(.)!$1!g;
247         return $unescaped unless grep exists $_->{$_[0]}, @{ $handle->_lex_refs };
248     }
249
250     return $handle->maketext(@_);
251 }
252
253 sub loc_fuzzy {
254     my $self = shift;
255     return '' if !defined $_[0] || $_[0] eq '';
256
257     return $self->LanguageHandle->maketext_fuzzy( @_ );
258 }
259
260 =head2 CurrentUser
261
262 Return the current currentuser object
263
264 =cut
265
266 sub CurrentUser {
267     return shift;
268 }
269
270 sub CustomFieldLookupType {
271     return "RT::User";
272 }
273
274 RT::Base->_ImportOverlays();
275
276 1;