use Newslash::Model::Base -base;
use Digest::MD5 qw(md5_hex md5_base64);
+use Crypt::Eksblowfish::Bcrypt qw(bcrypt en_base64 de_base64);
#========================================================================
+=head2 authentification
+
+ my $result = $users->passwords->authentification($nickname, $password);
+
+Return user hash when nickname and password pair is correct.
+
+=cut
+
+sub authentification {
+ my ($self, $nickname, $passwd) = @_;
+ my $users = $self->new_instance_of("Users");
+
+ my $u = $users->select(nickname => $nickname);
+ return if !$u;
+
+ if ($self->compare_password($passwd, $u->{passwd})
+ || $self->_compare_password_compat($passwd, $u->{passwd}, $users->{uid}, 0, 1)) {
+ return $u;
+ }
+ return;
+}
+
+sub _compare_password_compat {
+ # depracated. exists for compatibility.
+ my ($self, $passwd, $hashed_passwd, $uid, $is_plain, $is_enc) = @_;
+
+ if ($is_plain) {
+ return 1 if $passwd eq $md5;
+ }
+
+ if (!$is_enc) {
+ return 1 if md5_hex($passwd) eq $md5;
+
+ my @salts = ('',);
+ for my $salt (@salts) {
+ return 1 if md5_hex("$salt:$uid:$passwd") eq $md5;
+ return 1 if length($salt) && md5_hex("$salt$passwd") eq $md5;
+ }
+ }
+ return;
+}
+
+#========================================================================
+
=head2 nickname_to_matchname
-Convert nickname to matchname.
+ my $matchname = $users->passwords->nickname_to_matchname($nickname);
-nickname consists of almost all alphabet, number, symbol.
+Return matchname converted from nickname.
-matchname consists of lower alphabet and number.
+'nickname' consists of almost all alphabet, number, symbol.
+'matchname'consists of only lower alphabet and number.
=cut
=head2 random_password
-(import from: changePassword)
+ my $passwd = $users->passwords->random_password;
Return new random 8-character password composed of 0..9, A..Z, a..z
(but not including possibly hard-to-read characters [0O1Iil]).
-=over 4
-
-=item Return value
-
-Random password.
-
-=back
-
=cut
sub generate_random_password {
#========================================================================
-=head2 encrypt_password
-
-(import from: encryptPassword)
+=head2 compare_password
-Encrypts given password, using the most recent salt (if any) in
-Slash::Apache::User::PasswordSalt for the current virtual user.
-Currently uses MD5, but could change in the future, so do not
-depend on the implementation.
+ my $result = $users->passwords->compare_password($password, $hashed_password);
-=over 4
+Return 1 when hashed password correspod to password.
-=item Parameters
-
-=over 4
+=cut
-=item PASSWD
+sub compare_password {
+ my ($self, $passwd, $hashed_passwd) = @_;
-Password to be encrypted.
+ # check password hash with Bcrypt
+ if ($md5 =~ m/\$2a?\$\d{2}\$.+/) {
+ return 1 if $md5 eq bcrypt($passwd, $md5);
+ }
+ return;
+}
-=back
+#========================================================================
-=item Return value
+=head2 encrypt_password
-Encrypted password.
+ my $hashed_password = $users->passwords->encrypt_password($passwd);
-=back
+Return encrypted (hashed) password.
=cut
sub encrypt_password {
- my ($self, $passwd, $uid, $salt) = @_;
- $uid ||= '';
- $salt ||= '';
-
- if ($uid) {
- return md5_hex("$salt:$uid:$passwd");
- } else {
- return md5_hex("$salt$passwd");
- }
+ my ($self, $passwd) = @_;
+
+ # newslash's default hash algorythm is bcrypt
+ my $salt = substr(en_base64(md5_hex(rand())), 0, 16);
+ my $setting = '$2a$10$' . en_base64($salt);
+ return bcrypt($passwd, $setting);
}
+
+
1;