[freeside-commits] branch 21563 updated. 120718856665ca90ad852535d1155f8ea8ecb6b6

Ivan ivan at 420.am
Thu May 9 01:42:56 PDT 2013


The branch, 21563 has been updated
       via  120718856665ca90ad852535d1155f8ea8ecb6b6 (commit)
      from  d8843f184a7f6ee87eec99724f2d6430c1df34ea (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 120718856665ca90ad852535d1155f8ea8ecb6b6
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Thu May 9 01:42:39 2013 -0700

    NG auth: pw changes, RT#21563

diff --git a/FS/FS/Auth/internal.pm b/FS/FS/Auth/internal.pm
index 5d9170e..bb116ce 100644
--- a/FS/FS/Auth/internal.pm
+++ b/FS/FS/Auth/internal.pm
@@ -2,29 +2,32 @@ package FS::Auth::internal;
 #use base qw( FS::Auth );
 
 use strict;
-use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash);
+use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash en_base64 de_base64);
 use FS::Record qw( qsearchs );
 use FS::access_user;
 
 sub authenticate {
   my($self, $username, $check_password ) = @_;
 
-  my $access_user = qsearchs('access_user', { 'username' => $username,
-                                              'disabled' => '',
-                                            }
-                            )
+  my $access_user =
+    ref($username) ? $username
+                   : qsearchs('access_user', { 'username' => $username,
+                                               'disabled' => '',
+                                             }
+                             )
     or return 0;
 
   if ( $access_user->_password_encoding eq 'bcrypt' ) {
 
     my( $cost, $salt, $hash ) = split(',', $access_user->_password);
 
-    my $check_hash = bcrypt_hash( { key_nul => 1,
-                                    cost    => $cost,
-                                    salt    => $salt,
-                                  },
-                                  $check_password
-                                );
+    my $check_hash = en_base64( bcrypt_hash( { key_nul => 1,
+                                               cost    => $cost,
+                                               salt    => de_base64($salt),
+                                             },
+                                             $check_password
+                                           )
+                              );
 
     $hash eq $check_hash;
 
@@ -39,7 +42,35 @@ sub authenticate {
 
 }
 
-#sub change_password {
-#}
+sub change_password {
+  my($self, $access_user, $new_password) = @_;
+
+  $self->change_password_fields( $access_user, $new_password );
+
+  $access_user->replace;
+
+}
+
+sub change_password_fields {
+  my($self, $access_user, $new_password) = @_;
+
+  $access_user->_password_encoding('bcrypt');
+
+  my $cost = 8;
+
+  my $salt = pack( 'C*', map int(rand(256)), 1..16 );
+
+  my $hash = bcrypt_hash( { key_nul => 1,
+                            cost    => $cost,
+                            salt    => $salt,
+                          },
+                          $new_password,
+                        );
+
+  $access_user->_password(
+    join(',', $cost, en_base64($salt), en_base64($hash) )
+  );
+
+}
 
 1;
diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm
index 509cc09..cdee377 100644
--- a/FS/FS/access_user.pm
+++ b/FS/FS/access_user.pm
@@ -4,6 +4,7 @@ use strict;
 use base qw( FS::m2m_Common FS::option_Common ); 
 use vars qw( $DEBUG $me $conf $htpasswd_file );
 use FS::UID;
+use FS::Auth;
 use FS::Conf;
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::access_user_pref;
@@ -563,7 +564,27 @@ sub is_system_user {
     fs_signup
     fs_bootstrap
     fs_selfserv
-) );
+  ) );
+}
+
+=item change_password NEW_PASSWORD
+
+=cut
+
+sub change_password {
+  #my( $self, $password ) = @_;
+  #FS::Auth->auth_class->change_password( $self, $password );
+  FS::Auth->auth_class->change_password( @_ );
+}
+
+=item change_password_fields NEW_PASSWORD
+
+=cut
+
+sub change_password_fields {
+  #my( $self, $password ) = @_;
+  #FS::Auth->auth_class->change_password_fields( $self, $password );
+  FS::Auth->auth_class->change_password_fields( @_ );
 }
 
 =back
diff --git a/httemplate/edit/access_user.html b/httemplate/edit/access_user.html
index 86ce253..b087943 100644
--- a/httemplate/edit/access_user.html
+++ b/httemplate/edit/access_user.html
@@ -3,8 +3,7 @@
                  'table'  => 'access_user',
                  'fields' => [
                                'username',
-                               { field=>'_password', type=>'password' },
-                               { field=>'_password2', type=>'password' },
+                               @pw_fields,
                                'last',
                                'first',
                                { field=>'user_custnum', type=>'search-cust_main', },
@@ -50,6 +49,13 @@
 die "access denied"
   unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
 
+my @pw_fields =
+  FS::Auth->auth_class->can('change_password')
+    ? ( { field=>'_password',  type=>'password' },
+        { field=>'_password2', type=>'password' },
+      )
+    : ();
+
 my $check_user_custnum_search = <<END;
   <SCRIPT TYPE="text/javascript">
     function check_user_custnum_search(what) {
diff --git a/httemplate/edit/process/access_user.html b/httemplate/edit/process/access_user.html
index 8e7e70a..7fc7c25 100644
--- a/httemplate/edit/process/access_user.html
+++ b/httemplate/edit/process/access_user.html
@@ -3,14 +3,15 @@
 %    print $cgi->redirect(popurl(2) . "access_user.html?" . $cgi->query_string);
 %  } else {
 <%   include( 'elements/process.html',
-                 'table'       => 'access_user',
-                 'viewall_dir' => 'browse',
-                 'copy_on_empty' => [ '_password' ],
+                 'table'          => 'access_user',
+                 'viewall_dir'    => 'browse',
+                 'copy_on_empty'  => [ '_password', '_password_encoding' ],
                  'clear_on_error' => [ '_password', '_password2' ],
-                 'process_m2m' => { 'link_table'   => 'access_usergroup',
-                                    'target_table' => 'access_group',
-                                  },
-                 'precheck_callback'=> \&precheck_callback,
+                 'process_m2m'    => { 'link_table'   => 'access_usergroup',
+                                       'target_table' => 'access_group',
+                                     },
+                 'precheck_callback'        => \&precheck_callback,
+                 'post_new_object_callback' => \&post_new_object_callback,
              )
 %>
 %   }
@@ -26,11 +27,24 @@ if ( FS::Conf->new->exists('disable_acl_changes') ) {
 
 sub precheck_callback {
   my $cgi = shift;
+
   my $o = FS::access_user->new({username => $cgi->param('username')});
   if( $o->is_system_user and !$cgi->param('usernum') ) {
     $cgi->param('username','');
     return "username '".$o->username."' reserved for system account."
   }
+
   return '';
 }
+
+sub post_new_object_callback {
+  my( $cgi, $access_user ) = @_;
+
+  if ( length($cgi->param('_password')) ) {
+    my $password = scalar($cgi->param('_password'));
+    $access_user->change_password_fields($password);
+  }
+
+}
+
 </%init>
diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html
index fb1ee7a..2afbdd0 100644
--- a/httemplate/edit/process/elements/process.html
+++ b/httemplate/edit/process/elements/process.html
@@ -70,6 +70,9 @@ Example:
    #return an error string or empty for no error
    'precheck_callback' => sub { my( $cgi ) = @_; },
 
+   #after the new object is created
+   'post_new_object_callback' => sub { my( $cgi, $object ) = @_; },
+
    #after everything's inserted
    'noerror_callback' => sub { my( $cgi, $object ) = @_; },
 
@@ -226,6 +229,10 @@ foreach my $value ( @values ) {
       }
     }
 
+    if ( $opt{'post_new_object_callback'} ) {
+      &{ $opt{'post_new_object_callback'} }( $cgi, $new );
+    }
+
     if ( $opt{'agent_virt'} ) {
 
       if ( ! $new->agentnum
diff --git a/httemplate/pref/pref-process.html b/httemplate/pref/pref-process.html
index 242e122..962ee51 100644
--- a/httemplate/pref/pref-process.html
+++ b/httemplate/pref/pref-process.html
@@ -13,35 +13,35 @@ if ( FS::Conf->new->exists('disable_acl_changes') ) {
 }
 
 my $error = '';
-my $access_user = '';
 
-if ( grep { $cgi->param($_) !~ /^\s*$/ }
-          qw(_password new_password new_password2)
+if ( FS::Auth->auth_class->can('change_password')
+       && grep { $cgi->param($_) !~ /^\s*$/ }
+            qw(_password new_password new_password2)
    ) {
 
-  $access_user = qsearchs( 'access_user', {
-    'usernum'   => $FS::CurrentUser::CurrentUser->usernum,
-    'username'  => $FS::CurrentUser::CurrentUser->username,
-    '_password' => scalar($cgi->param('_password')),
-  } );
+  if ( $cgi->param('new_password') ne $cgi->param('new_password2') ) {
+    $error = "New passwords don't match";
 
-  $error = 'Current password incorrect; password not changed'
-    unless $access_user;
+  } elsif ( ! length($cgi->param('new_password')) ) {
+    $error = 'No new password entered';
 
-  $error ||= "New passwords don't match"
-    unless $cgi->param('new_password') eq $cgi->param('new_password2');
+  } elsif ( ! FS::Auth->authenticate( $FS::CurrentUser::CurrentUser,
+                                      scalar($cgi->param('_password')) )
+          ) {
+    $error = 'Current password incorrect; password not changed';
 
-  $error ||= "No new password entered"
-   unless length($cgi->param('new_password'));
+  } else {
 
-  $access_user->_password($cgi->param('new_password')) unless $error;
+    $error = $FS::CurrentUser::CurrentUser->change_password(
+      scalar($cgi->param('new_password'))
+    );
 
-} else {
-
-  $access_user = $FS::CurrentUser::CurrentUser;
+  }
 
 }
 
+my $access_user = $FS::CurrentUser::CurrentUser;
+
 #well, if you got your password change wrong, you don't get anything else
 #changed right now.  but it should be sticky on the form
 unless ( $error ) { # if ($access_user) {
diff --git a/httemplate/pref/pref.html b/httemplate/pref/pref.html
index 9861c3f..dc44db0 100644
--- a/httemplate/pref/pref.html
+++ b/httemplate/pref/pref.html
@@ -4,28 +4,30 @@
 
 <% include('/elements/error.html') %>
 
+% if ( FS::Auth->auth_class->can('change_password') ) {
 
-<% mt('Change password (leave blank for no change)') |h %>
-<% ntable("#cccccc",2) %>
+    <% mt('Change password (leave blank for no change)') |h %>
+    <% ntable("#cccccc",2) %>
 
-  <TR>
-    <TH ALIGN="right">Current password: </TH>
-    <TD><INPUT TYPE="password" NAME="_password"></TD>
-  </TR>
+      <TR>
+        <TH ALIGN="right">Current password: </TH>
+        <TD><INPUT TYPE="password" NAME="_password"></TD>
+      </TR>
 
-  <TR>
-    <TH ALIGN="right">New password: </TH>
-    <TD><INPUT TYPE="password" NAME="new_password"></TD>
-  </TR>
+      <TR>
+        <TH ALIGN="right">New password: </TH>
+        <TD><INPUT TYPE="password" NAME="new_password"></TD>
+      </TR>
 
-  <TR>
-   <TH ALIGN="right">Re-enter new password: </TH>
-   <TD><INPUT TYPE="password" NAME="new_password2"></TD>
-  </TR>
+      <TR>
+       <TH ALIGN="right">Re-enter new password: </TH>
+       <TD><INPUT TYPE="password" NAME="new_password2"></TD>
+      </TR>
 
-</TABLE>
-<BR>
+    </TABLE>
+    <BR>
 
+% }
 
 Interface
 <% ntable("#cccccc",2) %>

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Auth/internal.pm                        |   57 +++++++++++++++++++------
 FS/FS/access_user.pm                          |   23 ++++++++++-
 httemplate/edit/access_user.html              |   10 ++++-
 httemplate/edit/process/access_user.html      |   28 +++++++++---
 httemplate/edit/process/elements/process.html |    7 +++
 httemplate/pref/pref-process.html             |   36 ++++++++--------
 httemplate/pref/pref.html                     |   34 ++++++++-------
 7 files changed, 138 insertions(+), 57 deletions(-)




More information about the freeside-commits mailing list