X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FUser.pm;h=0094f98074d45c69937ed8afb1e1ed3c713f1d81;hb=ed1f84b4e8f626245995ecda5afcf83092c153b2;hp=f26ace445d4051c452d54b8c3df576ec12569a32;hpb=84f2df8931fa02e63fb21f8f0bb87dd9577b8919;p=freeside.git diff --git a/rt/lib/RT/User.pm b/rt/lib/RT/User.pm index f26ace445..0094f9807 100755 --- a/rt/lib/RT/User.pm +++ b/rt/lib/RT/User.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -81,7 +81,6 @@ use Digest::MD5; use RT::Principals; use RT::ACE; use RT::Interface::Email; -use Encode; use Text::Password::Pronounceable; sub _OverlayAccessible { @@ -102,7 +101,6 @@ sub _OverlayAccessible { AuthSystem => { public => 1, admin => 1 }, Gecos => { public => 1, admin => 1 }, PGPKey => { public => 1, admin => 1 }, - PrivateKey => { admin => 1 }, } } @@ -167,18 +165,10 @@ sub Create { return ( 0, $self->loc("Must specify 'Name' attribute") ); } - #SANITY CHECK THE NAME AND ABORT IF IT'S TAKEN - if (RT->SystemUser) { #This only works if RT::SystemUser has been defined - my $TempUser = RT::User->new(RT->SystemUser); - $TempUser->Load( $args{'Name'} ); - return ( 0, $self->loc('Name in use') ) if ( $TempUser->Id ); - - my ($val, $message) = $self->ValidateEmailAddress( $args{'EmailAddress'} ); - return (0, $message) unless ( $val ); - } else { - $RT::Logger->warning( "$self couldn't check for pre-existing users"); - } - + my ( $val, $msg ) = $self->ValidateName( $args{'Name'} ); + return ( 0, $msg ) unless $val; + ( $val, $msg ) = $self->ValidateEmailAddress( $args{'EmailAddress'} ); + return ( 0, $msg ) unless ($val); $RT::Handle->BeginTransaction(); # Groups deal with principal ids, rather than user ids. @@ -270,6 +260,30 @@ sub Create { return ( $id, $self->loc('User created') ); } +=head2 ValidateName STRING + +Returns either (0, "failure reason") or 1 depending on whether the given +name is valid. + +=cut + +sub ValidateName { + my $self = shift; + my $name = shift; + + return ( 0, $self->loc('empty name') ) unless defined $name && length $name; + + my $TempUser = RT::User->new( RT->SystemUser ); + $TempUser->Load($name); + + if ( $TempUser->id && ( !$self->id || $TempUser->id != $self->id ) ) { + return ( 0, $self->loc('Name in use') ); + } + else { + return 1; + } +} + =head2 ValidatePassword STRING Returns either (0, "failure reason") or 1 depending on whether the given @@ -572,6 +586,25 @@ sub ValidateEmailAddress { } } +=head2 SetName + +Check to make sure someone else isn't using this name already + +=cut + +sub SetName { + my $self = shift; + my $Value = shift; + + my ( $val, $message ) = $self->ValidateName($Value); + if ($val) { + return $self->_Set( Field => 'Name', Value => $Value ); + } + else { + return ( 0, $message ); + } +} + =head2 SetEmailAddress Check to make sure someone else isn't using this email address already @@ -845,7 +878,7 @@ sub _GeneratePassword_sha512 { my $sha = Digest::SHA->new(512); $sha->add($salt); - $sha->add(encode_utf8($password)); + $sha->add(Encode::encode( 'UTF-8', $password)); return join("!", "", "sha512", $salt, $sha->b64digest); } @@ -922,16 +955,16 @@ sub IsPassword { my $hash = MIME::Base64::decode_base64($stored); # Decoding yields 30 byes; first 4 are the salt, the rest are substr(SHA256,0,26) my $salt = substr($hash, 0, 4, ""); - return 0 unless substr(Digest::SHA::sha256($salt . Digest::MD5::md5($value)), 0, 26) eq $hash; + return 0 unless substr(Digest::SHA::sha256($salt . Digest::MD5::md5(Encode::encode( "UTF-8", $value))), 0, 26) eq $hash; } elsif (length $stored == 32) { # Hex nonsalted-md5 - return 0 unless Digest::MD5::md5_hex(encode_utf8($value)) eq $stored; + return 0 unless Digest::MD5::md5_hex(Encode::encode( "UTF-8", $value)) eq $stored; } elsif (length $stored == 22) { # Base64 nonsalted-md5 - return 0 unless Digest::MD5::md5_base64(encode_utf8($value)) eq $stored; + return 0 unless Digest::MD5::md5_base64(Encode::encode( "UTF-8", $value)) eq $stored; } elsif (length $stored == 13) { # crypt() output - return 0 unless crypt(encode_utf8($value), $stored) eq $stored; + return 0 unless crypt(Encode::encode( "UTF-8", $value), $stored) eq $stored; } else { $RT::Logger->warning("Unknown password form"); return 0; @@ -1020,8 +1053,7 @@ sub GenerateAuthString { my $self = shift; my $protect = shift; - my $str = $self->AuthToken . $protect; - utf8::encode($str); + my $str = Encode::encode( "UTF-8", $self->AuthToken . $protect ); return substr(Digest::MD5::md5_hex($str),0,16); } @@ -1038,8 +1070,7 @@ sub ValidateAuthString { my $auth_string = shift; my $protected = shift; - my $str = $self->AuthToken . $protected; - utf8::encode( $str ); + my $str = Encode::encode( "UTF-8", $self->AuthToken . $protected ); return $auth_string eq substr(Digest::MD5::md5_hex($str),0,16); } @@ -1311,10 +1342,8 @@ sub Preferences { my $name = _PrefName (shift); my $default = shift; - my $attr = RT::Attribute->new( $self->CurrentUser ); - $attr->LoadByNameAndObject( Object => $self, Name => $name ); - - my $content = $attr->Id ? $attr->Content : undef; + my ($attr) = $self->Attributes->Named( $name ); + my $content = $attr ? $attr->Content : undef; unless ( ref $content eq 'HASH' ) { return defined $content ? $content : $default; } @@ -1343,9 +1372,8 @@ sub SetPreferences { return (0, $self->loc("No permission to set preferences")) unless $self->CurrentUserCanModify('Preferences'); - my $attr = RT::Attribute->new( $self->CurrentUser ); - $attr->LoadByNameAndObject( Object => $self, Name => $name ); - if ( $attr->Id ) { + my ($attr) = $self->Attributes->Named( $name ); + if ( $attr ) { my ($ok, $msg) = $attr->SetContent( $value ); return (1, "No updates made") if $msg eq "That is already the current value"; @@ -1355,6 +1383,26 @@ sub SetPreferences { } } +=head2 DeletePreferences NAME/OBJ VALUE + +Delete user preferences associated with given object or name. + +=cut + +sub DeletePreferences { + my $self = shift; + my $name = _PrefName( shift ); + + return (0, $self->loc("No permission to set preferences")) + unless $self->CurrentUserCanModify('Preferences'); + + my ($attr) = $self->DeleteAttribute( $name ); + return (0, $self->loc("Preferences were not found")) + unless $attr; + + return 1; +} + =head2 Stylesheet Returns a list of valid stylesheets take from preferences. @@ -1393,7 +1441,7 @@ $user->WatchedQueues('Cc', 'AdminCc'); sub WatchedQueues { my $self = shift; - my @roles = @_ || ('Cc', 'AdminCc'); + my @roles = @_ ? @_ : ('Cc', 'AdminCc'); $RT::Logger->debug('WatcheQueues got user ' . $self->Name); @@ -1595,7 +1643,8 @@ sub SetPrivateKey { my $self = shift; my $key = shift; - unless ($self->CurrentUserCanModify('PrivateKey')) { + # Users should not be able to change their own PrivateKey values + unless ( $self->CurrentUser->HasRight(Right => 'AdminUsers', Object => $RT::System) ) { return (0, $self->loc("Permission Denied")); }