merging rt \3.8.8 to HEAD
[freeside.git] / rt / lib / RT / User_Overlay.pm
index 0f28568..2115c32 100644 (file)
@@ -916,6 +916,42 @@ sub _GenerateRandomNextChar {
     return ($i);
 }
 
+sub SafeSetPassword {
+    my $self = shift;
+    my %args = (
+        Current      => undef,
+        New          => undef,
+        Confirmation => undef,
+        @_,
+    );
+    return (1) unless defined $args{'New'} && length $args{'New'};
+
+    my %cond = $self->CurrentUserRequireToSetPassword;
+
+    unless ( $cond{'CanSet'} ) {
+        return (0, $self->loc('You can not set password.') .' '. $cond{'Reason'} );
+    }
+
+    my $error = '';    
+    if ( $cond{'RequireCurrent'} && !$self->CurrentUser->IsPassword($args{'Current'}) ) {
+        if ( defined $args{'Current'} && length $args{'Current'} ) {
+            $error = $self->loc("Please enter your current password correctly.");
+        }
+        else {
+            $error = $self->loc("Please enter your current password.");
+        }
+    } elsif ( $args{'New'} ne $args{'Confirmation'} ) {
+        $error = $self->loc("Passwords do not match.");
+    }
+
+    if ( $error ) {
+        $error .= ' '. $self->loc('Password has not been set.');
+        return (0, $error);
+    }
+
+    return $self->SetPassword( $args{'New'} );
+}
+
 =head3 SetPassword
 
 Takes a string. Checks the string's length and sets this user's password 
@@ -1034,7 +1070,7 @@ sub IsPassword {
     }
 
     #  if it's a historical password we say ok.
-    if ($self->__Value('Password') eq crypt($value, $self->__Value('Password'))
+    if ($self->__Value('Password') eq crypt(encode_utf8($value), $self->__Value('Password'))
         or $self->_GeneratePasswordBase64($value) eq $self->__Value('Password'))
     {
         # ...but upgrade the legacy password inplace.
@@ -1047,6 +1083,35 @@ sub IsPassword {
     return (undef);
 }
 
+sub CurrentUserRequireToSetPassword {
+    my $self = shift;
+
+    my %res = (
+        CanSet => 1,
+        Reason => '',
+        RequireCurrent => 1,
+    );
+
+    if ( RT->Config->Get('WebExternalAuth')
+        && !RT->Config->Get('WebFallbackToInternalAuth')
+    ) {
+        $res{'CanSet'} = 0;
+        $res{'Reason'} = $self->loc("External authentication enabled.");
+    }
+    elsif ( !$self->CurrentUser->HasPassword ) {
+        if ( $self->CurrentUser->id == ($self->id||0) ) {
+            # don't require current password if user has no
+            $res{'RequireCurrent'} = 0;
+        }
+        else {
+            $res{'CanSet'} = 0;
+            $res{'Reason'} = $self->loc("Your password is not set.");
+        }
+    }
+
+    return %res;
+}
+
 =head3 AuthToken
 
 Returns an authentication string associated with the user. This