diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2017-09-28 17:37:46 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2017-09-28 17:37:46 +0200 |
commit | 2b909591125d027c46ea1b2e9802f54fb50f5dac (patch) | |
tree | 6920abfabf660df1d6f1b724bcb64bfca5fce6b1 | |
parent | 4ad4d3eeac2aba0cb1544c72296d51234e6e1d7b (diff) | |
download | sourceyard-2b909591125d027c46ea1b2e9802f54fb50f5dac.tar.gz sourceyard-2b909591125d027c46ea1b2e9802f54fb50f5dac.tar.bz2 |
Implement "upgrade password" feature.
* lib/App/Sourceyard/Password.pm (method, upgradable): new methods
* lib/Sourceyard/Controller/Account.pm (user_login): Upgrade password
hash if allowed and necessary.
* sourceyard.conf: Add auth.upgrade_hash
-rw-r--r-- | lib/App/Sourceyard/Password.pm | 39 | ||||
-rw-r--r-- | lib/Sourceyard/Controller/Account.pm | 13 | ||||
-rw-r--r-- | sourceyard.conf | 2 |
3 files changed, 41 insertions, 13 deletions
diff --git a/lib/App/Sourceyard/Password.pm b/lib/App/Sourceyard/Password.pm index 7cc2a6a..2952cee 100644 --- a/lib/App/Sourceyard/Password.pm +++ b/lib/App/Sourceyard/Password.pm @@ -105,15 +105,20 @@ sub check { } } -my @encrypt_methods = ( - { name => 'sha512', prefix => '$6$rounds=5000$', length => 16 }, - { name => 'sha256', prefix => '$5$', length => 16 }, - { name => 'blowfish', prefix => '$2a$10$', length => 22, - crypt => sub { return eval { bcrypt($_[0], $_[1]) } } }, - { name => 'md5', prefix => '$1$', length => 12 }, - { name => 'des', length => 2 } +my %encrypt_method = ( + sha512 => { prefix => '$6$rounds=5000$', length => 16 }, + sha256 => { prefix => '$5$', length => 16 }, + blowfish => { + prefix => '$2a$10$', + length => 22, + crypt => sub { return eval { bcrypt($_[0], $_[1]) } } + }, + md5 => { prefix => '$1$', length => 12 }, + des => { length => 2 } ); +my @encrypt_pref = qw(sha512 sha256 blowfish md5 des); + sub _gensalt { my ($self, $length) = @_; my $source = new Crypt::Random::Seed(NonBlocking => 1); @@ -123,7 +128,8 @@ sub _gensalt { sub _encrypt { my ($self, $plaintext) = @_; my $hash; - foreach my $meth (@encrypt_methods) { + foreach my $name (@encrypt_pref) { + my $meth = $encrypt_method{$name} or die "no such method: $name"; my $prefix = $meth->{prefix} || ''; my $salt = $prefix . $self->_gensalt($meth->{length}); $hash = &{exists($meth->{crypt}) ? $meth->{crypt} : \&CORE::crypt} @@ -133,4 +139,21 @@ sub _encrypt { return $hash; } +sub method { + my ($self) = @_; + + foreach my $name (@encrypt_pref) { + my $meth = $encrypt_method{$name} or die "no such method: $name"; + my $prefix = $meth->{prefix} || ''; + return $name + if substr($self->{_hash}, 0, length($prefix)) eq $prefix; + } + return undef; +} + +sub upgradable { + my ($self) = @_; + return $self->method ne $encrypt_pref[0]; +} + 1; diff --git a/lib/Sourceyard/Controller/Account.pm b/lib/Sourceyard/Controller/Account.pm index 554fbdc..91ae131 100644 --- a/lib/Sourceyard/Controller/Account.pm +++ b/lib/Sourceyard/Controller/Account.pm @@ -30,11 +30,14 @@ sub user_login { my $user = new Sourceyard::User($self, $username); if ($user && $user->user_pw->check($password)) { - # FIXME - # if ($self->config->get(qw(auth upgrade_hash))) { - # $res->user_pw($self->pwencrypt($password)); - # $res->update; - # } + if ($user->user_pw->upgradable) { + $self->app->log->info($user->user_name . ': password needs upgrading'); + if ($self->config->get(qw(auth upgrade_hash))) { + $self->app->log->info($user->user_name . ': password upgraded'); + $user->user_pw(new App::Sourceyard::Password($password)); + $user->update; + } + } $self->set_user($user); $self->redirect_to($return_url); } else { diff --git a/sourceyard.conf b/sourceyard.conf index 121d48c..2b13fc2 100644 --- a/sourceyard.conf +++ b/sourceyard.conf @@ -35,3 +35,5 @@ [core] acl = sourceyard.acl +[auth] + upgrade_hash = 1 |