1 package FS::Auth::internal;
2 #use base qw( FS::Auth );
5 use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash en_base64 de_base64);
6 use FS::Record qw( qsearchs );
10 my($self, $username, $check_password, $totp_code ) = @_;
13 ref($username) ? $username
14 : qsearchs('access_user', { 'username' => $username,
21 if ( $access_user->_password_encoding eq 'bcrypt' ) {
23 my( $cost, $salt, $hash ) = split(',', $access_user->_password);
25 my $check_hash = en_base64( bcrypt_hash( { key_nul => 1,
27 salt => de_base64($salt),
33 $pw_check = $hash eq $check_hash;
37 return 0 if $access_user->_password eq 'notyet'
38 || $access_user->_password eq '';
40 $pw_check = $access_user->_password eq $check_password;
44 return $pw_check if ! $pw_check || ! length($access_user->totp_secret32);
47 $access_user->google_auth->verify( $totp_code, 1 );
53 my($self, $access_user, $new_password) = @_;
55 # do nothing if the password is unchanged
56 #XXX breaks password changes in employee edit ($access_user object already
57 # has new [plaintext] password)
58 #return if $self->authenticate( $access_user, $new_password );
60 $self->change_password_fields( $access_user, $new_password );
62 $access_user->replace;
66 sub change_password_fields {
67 my($self, $access_user, $new_password) = @_;
69 $access_user->_password_encoding('bcrypt');
73 my $salt = pack( 'C*', map int(rand(256)), 1..16 );
75 my $hash = bcrypt_hash( { key_nul => 1,
82 $access_user->_password(
83 join(',', $cost, en_base64($salt), en_base64($hash) )