summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2017-09-28 17:37:46 +0200
committerSergey Poznyakoff <gray@gnu.org>2017-09-28 17:37:46 +0200
commit2b909591125d027c46ea1b2e9802f54fb50f5dac (patch)
tree6920abfabf660df1d6f1b724bcb64bfca5fce6b1
parent4ad4d3eeac2aba0cb1544c72296d51234e6e1d7b (diff)
downloadsourceyard-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.pm39
-rw-r--r--lib/Sourceyard/Controller/Account.pm13
-rw-r--r--sourceyard.conf2
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

Return to:

Send suggestions and report system problems to the System administrator.