X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Flib%2FRT%2FCurrentUser.pm;h=74d44e30459c63d099f349477e651ce0b0eb07ba;hp=d147fe62e9d752605d75f74a048faf725cf1ee3a;hb=7322f2afedcc2f427e997d1535a503613a83f088;hpb=d39d52aac8f38ea9115628039f0df5aa3ac826de diff --git a/rt/lib/RT/CurrentUser.pm b/rt/lib/RT/CurrentUser.pm index d147fe62e..74d44e304 100755 --- a/rt/lib/RT/CurrentUser.pm +++ b/rt/lib/RT/CurrentUser.pm @@ -1,38 +1,40 @@ -# {{{ BEGIN BPS TAGGED BLOCK -# +# BEGIN BPS TAGGED BLOCK {{{ +# # COPYRIGHT: -# -# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC -# -# +# +# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC +# +# # (Except where explicitly superseded by other copyright notices) -# -# +# +# # LICENSE: -# +# # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed # from www.gnu.org. -# +# # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# # CONTRIBUTION SUBMISSION POLICY: -# +# # (The following paragraph is not intended to limit the rights granted # to you to modify and distribute this software under the terms of # the GNU General Public License and is only of importance to you if # you choose to contribute your changes and enhancements to the # community by submitting them to Best Practical Solutions, LLC.) -# +# # By intentionally submitting any modifications, corrections or # derivatives to this work, or any other work intended for use with # Request Tracker, to Best Practical Solutions, LLC, you confirm that @@ -41,41 +43,57 @@ # royalty-free, perpetual, license to use, copy, create derivative # works based on those contributions, and sublicense and distribute # those contributions and any derivatives thereof. -# -# }}} END BPS TAGGED BLOCK +# +# END BPS TAGGED BLOCK }}} + =head1 NAME RT::CurrentUser - an RT object representing the current user =head1 SYNOPSIS - use RT::CurrentUser + use RT::CurrentUser; + + # load + my $current_user = RT::CurrentUser->new; + $current_user->Load(...); + # or + my $current_user = RT::CurrentUser->new( $user_obj ); + # or + my $current_user = RT::CurrentUser->new( $address || $name || $id ); + + # manipulation + $current_user->UserObj->SetName('new_name'); =head1 DESCRIPTION +B subclass of L class. Used to define the current +user. You should pass an instance of this class to constructors of +many RT classes, then the instance used to check ACLs and localize +strings. =head1 METHODS +See also L for a list of methods this class has. -=begin testing - -ok (require RT::CurrentUser); +=head2 new -=end testing +Returns new CurrentUser object. Unlike all other classes of RT it takes +either subclass of C class object or scalar value that is +passed to Load method. =cut package RT::CurrentUser; -use RT::Record; -use RT::I18N; - use strict; -use base qw/RT::Record/; +use warnings; -# {{{ sub _Init +use base qw/RT::User/; + +use RT::I18N; #The basic idea here is that $self->CurrentUser is always supposed # to be a CurrentUser object. but that's hard to do when we're trying to load @@ -87,107 +105,67 @@ sub _Init { $self->{'table'} = "Users"; - if ( defined($User) ) { - - if ( UNIVERSAL::isa( $User, 'RT::User' ) - || UNIVERSAL::isa( $User, 'RT::CurrentUser' ) ) - { - $self->Load( $User->id ); + if ( defined $User ) { + if ( UNIVERSAL::isa( $User, 'RT::User' ) ) { + $self->LoadById( $User->id ); } - elsif ( ref($User) ) { + elsif ( ref $User ) { $RT::Logger->crit( "RT::CurrentUser->new() called with a bogus argument: $User"); } else { - $self->Load($User); + $self->Load( $User ); } } - $self->_BuildTableAttributes(); + $self->_BuildTableAttributes; } -# }}} -# {{{ sub Create +=head2 Create, Delete and Set* + +As stated above it's a subclass of L, but this class is read-only +and calls to these methods are illegal. Return 'permission denied' message +and log an error. + +=cut sub Create { my $self = shift; + $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation'); return (0, $self->loc('Permission Denied')); } -# }}} - -# {{{ sub Delete - sub Delete { my $self = shift; + $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation'); return (0, $self->loc('Permission Denied')); } -# }}} - -# {{{ sub UserObj - -=head2 UserObj - - Returns the RT::User object associated with this CurrentUser object. - -=cut - -sub UserObj { +sub _Set { my $self = shift; - - use RT::User; - my $user = RT::User->new($self); - - unless ($user->Load($self->Id)) { - $RT::Logger->err($self->loc("Couldn't load [_1] from the users database.\n", $self->Id)); - } - return ($user); + $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation'); + return (0, $self->loc('Permission Denied')); } -# }}} -# {{{ sub PrincipalObj - -=head2 PrincipalObj +=head2 UserObj - Returns this user's principal object. this is just a helper routine for - $self->UserObj->PrincipalObj +Returns the L object associated with this CurrentUser object. =cut -sub PrincipalObj { +sub UserObj { my $self = shift; - return($self->UserObj->PrincipalObj); -} - - -# }}} - - -# {{{ sub PrincipalId - -=head2 PrincipalId - - Returns this user's principal Id. this is just a helper routine for - $self->UserObj->PrincipalId -=cut - -sub PrincipalId { - my $self = shift; - return($self->UserObj->PrincipalId); + my $user = RT::User->new( $self ); + unless ( $user->LoadById( $self->Id ) ) { + $RT::Logger->error("Couldn't load " . $self->Id . " from the users database."); + } + return $user; } - -# }}} - - -# {{{ sub _Accessible - - - sub _CoreAccessible { +sub _CoreAccessible { { Name => { 'read' => 1 }, Gecos => { 'read' => 1 }, @@ -198,29 +176,6 @@ sub PrincipalId { }; } -# }}} - -# {{{ sub LoadByEmail - -=head2 LoadByEmail - -Loads a User into this CurrentUser object. -Takes the email address of the user to load. - -=cut - -sub LoadByEmail { - my $self = shift; - my $identifier = shift; - - $identifier = RT::User::CanonicalizeEmailAddress(undef, $identifier); - - $self->LoadByCol("EmailAddress",$identifier); - -} -# }}} - -# {{{ sub LoadByGecos =head2 LoadByGecos @@ -231,168 +186,65 @@ Takes a unix username as its only argument. sub LoadByGecos { my $self = shift; - my $identifier = shift; - - $self->LoadByCol("Gecos",$identifier); - + return $self->LoadByCol( "Gecos", shift ); } -# }}} - -# {{{ sub LoadByName =head2 LoadByName Loads a User into this CurrentUser object. Takes a Name. -=cut - -sub LoadByName { - my $self = shift; - my $identifier = shift; - $self->LoadByCol("Name",$identifier); - -} -# }}} - -# {{{ sub Load - -=head2 Load - -Loads a User into this CurrentUser object. -Takes either an integer (users id column reference) or a Name -The latter is deprecated. Instead, you should use LoadByName. -Formerly, this routine also took email addresses. - -=cut - -sub Load { - my $self = shift; - my $identifier = shift; - - #if it's an int, load by id. otherwise, load by name. - if ($identifier !~ /\D/) { - $self->SUPER::LoadById($identifier); - } - - elsif (UNIVERSAL::isa($identifier,"RT::User")) { - # DWIM if they pass a user in - $self->SUPER::LoadById($identifier->Id); - } - else { - # This is a bit dangerous, we might get false authen if somebody - # uses ambigous userids or real names: - $self->LoadByCol("Name",$identifier); - } -} - -# }}} - -# {{{ sub IsPassword - -=head2 IsPassword - -Takes a password as a string. Passes it off to IsPassword in this -user's UserObj. If it is the user's password and the user isn't -disabled, returns 1. - -Otherwise, returns undef. =cut -sub IsPassword { - my $self = shift; - my $value = shift; - - return ($self->UserObj->IsPassword($value)); -} - -# }}} - -# {{{ sub Privileged - -=head2 Privileged - -Returns true if the current user can be granted rights and be -a member of groups. - -=cut - -sub Privileged { +sub LoadByName { my $self = shift; - return ($self->UserObj->Privileged()); -} - -# }}} - - -# {{{ sub HasRight - -=head2 HasRight - -calls $self->UserObj->HasRight with the arguments passed in - -=cut - -sub HasRight { - my $self = shift; - return ($self->UserObj->HasRight(@_)); + return $self->LoadByCol( "Name", shift ); } -# }}} - -# {{{ Localization - =head2 LanguageHandle Returns this current user's langauge handle. Should take a language specification. but currently doesn't -=begin testing - -ok (my $cu = RT::CurrentUser->new('root')); -ok (my $lh = $cu->LanguageHandle); -ok ($lh != undef); -ok ($lh->isa('Locale::Maketext')); -ok ($cu->loc('TEST_STRING') eq "Concrete Mixer", "Localized TEST_STRING into English"); -ok ($lh = $cu->LanguageHandle('fr')); -ok ($cu->loc('Before') eq "Avant", "Localized TEST_STRING into Frenc"); - -=end testing - =cut sub LanguageHandle { my $self = shift; - if ( ( !defined $self->{'LangHandle'} ) - || ( !UNIVERSAL::can( $self->{'LangHandle'}, 'maketext' ) ) - || (@_) ) { - if ( (!$RT::SystemUser || $self->id == $RT::SystemUser->id() )) { - @_ = qw(en-US); + if ( !defined $self->{'LangHandle'} + || !UNIVERSAL::can( $self->{'LangHandle'}, 'maketext' ) + || @_ ) + { + if ( my $lang = $self->Lang ) { + push @_, $lang; } - - elsif ( $self->Lang ) { - push @_, $self->Lang; + elsif ( $self->id && ($self->id == (RT->SystemUser->id||0) || $self->id == (RT->Nobody->id||0)) ) { + # don't use ENV magic for system users + push @_, 'en'; } + $self->{'LangHandle'} = RT::I18N->get_handle(@_); } # Fall back to english. unless ( $self->{'LangHandle'} ) { - die "We couldn't get a dictionary. Nye mogu naidti slovar. No puedo encontrar dictionario."; + die "We couldn't get a dictionary. Ne mogu naidti slovar. No puedo encontrar dictionario."; } - return ( $self->{'LangHandle'} ); + return $self->{'LangHandle'}; } sub loc { my $self = shift; - return '' if $_[0] eq ''; + return '' if !defined $_[0] || $_[0] eq ''; my $handle = $self->LanguageHandle; if (@_ == 1) { - # pre-scan the lexicon hashes to return _AUTO keys verbatim, - # to keep locstrings containing '[' and '~' from tripping over Maketext - return $_[0] unless grep { exists $_->{$_[0]} } @{ $handle->_lex_refs }; + # If we have no [_1] replacements, and the key does not appear + # in the lexicon, unescape (using ~) and return it verbatim, as + # an optimization. + my $unescaped = $_[0]; + $unescaped =~ s!~(.)!$1!g; + return $unescaped unless grep exists $_->{$_[0]}, @{ $handle->_lex_refs }; } return $handle->maketext(@_); @@ -400,34 +252,25 @@ sub loc { sub loc_fuzzy { my $self = shift; - return '' if $_[0] eq ''; - - # XXX: work around perl's deficiency when matching utf8 data - return $_[0] if Encode::is_utf8($_[0]); - my $result = $self->LanguageHandle->maketext_fuzzy(@_); + return '' if !defined $_[0] || $_[0] eq ''; - return($result); + return $self->LanguageHandle->maketext_fuzzy( @_ ); } -# }}} - =head2 CurrentUser -Return the current currentuser object +Return the current currentuser object =cut sub CurrentUser { - my $self = shift; - return($self); - + return shift; } +sub CustomFieldLookupType { + return "RT::User"; +} -eval "require RT::CurrentUser_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Vendor.pm}); -eval "require RT::CurrentUser_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Local.pm}); +RT::Base->_ImportOverlays(); 1; -