X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Flib%2FRT%2FCurrentUser.pm;h=74d44e30459c63d099f349477e651ce0b0eb07ba;hp=4ca2f98919f79b206787753d052ab30d6ee29fb0;hb=7322f2afedcc2f427e997d1535a503613a83f088;hpb=63a268637b2d51a8766412617724b9436439deb6 diff --git a/rt/lib/RT/CurrentUser.pm b/rt/lib/RT/CurrentUser.pm index 4ca2f9891..74d44e304 100755 --- a/rt/lib/RT/CurrentUser.pm +++ b/rt/lib/RT/CurrentUser.pm @@ -1,194 +1,181 @@ -# BEGIN LICENSE BLOCK -# -# Copyright (c) 1996-2003 Jesse Vincent -# -# (Except where explictly superceded by other copyright notices) -# +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# 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. -# -# Unless otherwise specified, all modifications, corrections or -# extensions to this work which alter its source code become the -# property of Best Practical Solutions, LLC when submitted for -# inclusion in the work. -# -# -# END LICENSE BLOCK +# +# 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., 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 +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# 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 }}} + =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 vars qw/@ISA/; -@ISA= qw(RT::Record); +use warnings; + +use base qw/RT::User/; -# {{{ sub _Init +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 # the CurrentUser object -sub _Init { - my $self = shift; - my $Name = shift; +sub _Init { + my $self = shift; + my $User = shift; + + $self->{'table'} = "Users"; + + if ( defined $User ) { + + if ( UNIVERSAL::isa( $User, 'RT::User' ) ) { + $self->LoadById( $User->id ); + } + elsif ( ref $User ) { + $RT::Logger->crit( + "RT::CurrentUser->new() called with a bogus argument: $User"); + } + else { + $self->Load( $User ); + } + } - $self->{'table'} = "Users"; - - if (defined($Name)) { - $self->Load($Name); - } - - $self->CurrentUser($self); + $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 { - my $self = shift; - - unless ($self->{'UserObj'}) { - use RT::User; - $self->{'UserObj'} = RT::User->new($self); - unless ($self->{'UserObj'}->Load($self->Id)) { - $RT::Logger->err($self->loc("Couldn't load [_1] from the users database.\n", $self->Id)); - } - - } - return ($self->{'UserObj'}); -} -# }}} - -# {{{ sub PrincipalObj - -=head2 PrincipalObj - - Returns this user's principal object. this is just a helper routine for - $self->UserObj->PrincipalObj - -=cut - -sub PrincipalObj { +sub _Set { my $self = shift; - return($self->UserObj->PrincipalObj); + $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation'); + return (0, $self->loc('Permission Denied')); } +=head2 UserObj -# }}} - - -# {{{ sub PrincipalId - -=head2 PrincipalId - - Returns this user's principal Id. this is just a helper routine for - $self->UserObj->PrincipalId +Returns the L object associated with this CurrentUser object. =cut -sub PrincipalId { +sub UserObj { my $self = shift; - return($self->UserObj->PrincipalId); -} - - -# }}} - -# {{{ sub _Accessible -sub _Accessible { - my $self = shift; - my %Cols = ( - Name => 'read', - Gecos => 'read', - RealName => 'read', - Password => 'neither', - EmailAddress => 'read', - Privileged => 'read', - IsAdministrator => 'read' - ); - return($self->SUPER::_Accessible(@_, %Cols)); + 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 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 _CoreAccessible { + { + Name => { 'read' => 1 }, + Gecos => { 'read' => 1 }, + RealName => { 'read' => 1 }, + Lang => { 'read' => 1 }, + Password => { 'read' => 0, 'write' => 0 }, + EmailAddress => { 'read' => 1, 'write' => 0 } + }; + } -# }}} - -# {{{ sub LoadByGecos =head2 LoadByGecos @@ -199,155 +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); - } - 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 ( !defined $self->{'LangHandle'} + || !UNIVERSAL::can( $self->{'LangHandle'}, 'maketext' ) + || @_ ) + { + if ( my $lang = $self->Lang ) { + push @_, $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."; + unless ( $self->{'LangHandle'} ) { + 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(@_); @@ -355,20 +252,25 @@ sub loc { sub loc_fuzzy { my $self = shift; - return '' if $_[0] eq ''; + return '' if !defined $_[0] || $_[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 $self->LanguageHandle->maketext_fuzzy( @_ ); +} + +=head2 CurrentUser + +Return the current currentuser object + +=cut + +sub CurrentUser { + return shift; +} - return($result); +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; -