RT#39481: Password Maximum Length
[freeside.git] / FS / FS / ClientAPI / MyAccount.pm
index 7e1720d..33a8e61 100644 (file)
@@ -2995,12 +2995,6 @@ sub myaccount_passwd {
         )
     && ! $svc_acct->check_password($p->{'old_password'});
 
-    # should move password length checks into is_password_allowed
-  $error = 'Password too short.'
-    if length($p->{'new_password'}) < ($conf->config('passwordmin') || 6);
-  $error = 'Password too long.'
-    if length($p->{'new_password'}) > ($conf->config('passwordmax') || 8);
-
   $error ||= $svc_acct->is_password_allowed($p->{'new_password'})
          ||  $svc_acct->set_password($p->{'new_password'})
          ||  $svc_acct->replace();
@@ -3017,6 +3011,8 @@ sub myaccount_passwd {
                            )
   ) {
     #svc_acct was successful but this one returns an error?  "shouldn't happen"
+    #don't recheck is_password_allowed here; if the svc_acct password was
+    #legal, that's good enough
     $error ||= $contact->change_password($p->{'new_password'});
   }
 
@@ -3298,7 +3294,8 @@ sub process_reset_passwd {
 
   if ( $contact ) {
 
-    my $error = $contact->change_password($p->{'new_password'});
+    my $error = $contact->is_password_allowed($p->{'new_password'})
+            ||  $contact->change_password($p->{'new_password'});
 
     return { %$info, 'error' => $error }; # if $error;
 
@@ -3311,6 +3308,45 @@ sub process_reset_passwd {
 
 }
 
+sub validate_passwd {
+  my $p = shift;
+
+  my %result;
+  %result = ( 'fieldid' => $p->{'fieldid'} )
+    if $p->{'fieldid'} =~ /^\w+$/;
+
+  return { %result, 'password_invalid' => 'Enter new password' }
+    unless length($p->{'check_password'});
+
+  my $svc_acct;
+  if ($p->{'svcnum'}) {
+    # false laziness with myaccount_passwd
+    my($context, $session, $custnum) = _custoragent_session_custnum($p);
+    return { %result, 'error' => $session } if $context eq 'error';
+
+    $custnum =~ /^(\d+)$/ or die "illegal custnum";
+    my $search = " AND custnum = $1";
+    $search .= " AND agentnum = ". $session->{'agentnum'} if $context eq 'agent';
+
+    $svc_acct = qsearchs( {
+      'table'     => 'svc_acct',
+      'addl_from' => 'LEFT JOIN cust_svc  USING ( svcnum  ) '.
+                     'LEFT JOIN cust_pkg  USING ( pkgnum  ) '.
+                     'LEFT JOIN cust_main USING ( custnum ) ',
+      'hashref'   => { 'svcnum' => $p->{'svcnum'}, },
+      'extra_sql' => $search, #important
+    } )
+      or return { %result, 'error' => "Service not found" };
+    # end false laziness
+  }
+
+  $svc_acct ||= new FS::svc_acct {};
+
+  my $error = $svc_acct->is_password_allowed($p->{'check_password'});
+  return { %result, 'password_invalid' => $error } if $error;
+  return { %result, 'password_valid' => 1 };
+}
+
 sub list_tickets {
   my $p = shift;
   my($context, $session, $custnum) = _custoragent_session_custnum($p);