Add argon2id password auth (through DB)
This commit is contained in:
parent
e999d1309e
commit
5bb8febfa2
|
@ -11,6 +11,8 @@ WriteMakefile(
|
||||||
'Mojo::Pg' => '4.27',
|
'Mojo::Pg' => '4.27',
|
||||||
'Mojo::SQLite' => '3.009',
|
'Mojo::SQLite' => '3.009',
|
||||||
'Crypt::Random' => '1.25',
|
'Crypt::Random' => '1.25',
|
||||||
|
'Crypt::Argon2' => '0.013',
|
||||||
|
'Bytes::Random::Secure' => '0.29',
|
||||||
'Number::Bytes::Human' => '0.11',
|
'Number::Bytes::Human' => '0.11',
|
||||||
},
|
},
|
||||||
test => {TESTS => 't/*.t'}
|
test => {TESTS => 't/*.t'}
|
||||||
|
|
|
@ -37,6 +37,11 @@ sub startup($self) {
|
||||||
die "Database type is not supported";
|
die "Database type is not supported";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my @auths = qw/ldap db/;
|
||||||
|
my $auth = $config->{auth};
|
||||||
|
if (not grep $_ eq $auth, @auths) {
|
||||||
|
die "Auth type is not supported";
|
||||||
|
}
|
||||||
|
|
||||||
$self->helper(sql => sub ($app) {
|
$self->helper(sql => sub ($app) {
|
||||||
if ($dbtype eq "postgres") {
|
if ($dbtype eq "postgres") {
|
||||||
|
|
|
@ -21,24 +21,44 @@ sub auth($c) {
|
||||||
|
|
||||||
my $config = $c->config;
|
my $config = $c->config;
|
||||||
|
|
||||||
my $connStr = $config->{'ldap'}->{'uri'};
|
if ($config->{auth} eq 'ldap') {
|
||||||
my $bindDN = $config->{'ldap'}->{'dnBase'};
|
my $connStr = $config->{'ldap'}->{'uri'};
|
||||||
$bindDN =~ s/%u/$username/;
|
my $bindDN = $config->{'ldap'}->{'dnBase'};
|
||||||
|
$bindDN =~ s/%u/$username/;
|
||||||
|
|
||||||
return Mojo::IOLoop->subprocess->run_p(sub {
|
return Mojo::IOLoop->subprocess->run_p(sub {
|
||||||
my $ldap= Net::LDAPS->new($connStr, verify=>'none', version=>3) or die "$@";
|
my $ldap= Net::LDAPS->new($connStr, verify=>'none', version=>3) or die "$@";
|
||||||
my $mesg = $ldap->bind($bindDN, password=>$password);
|
my $mesg = $ldap->bind($bindDN, password=>$password);
|
||||||
$mesg->code and die $mesg->error;
|
$mesg->code and die $mesg->error;
|
||||||
})->then(sub ($res) {
|
})->then(sub ($res) {
|
||||||
return $c->users->getOrMake($username);
|
return $c->users->getOrMake($username);
|
||||||
})->then(sub ($res) {
|
})->then(sub ($res) {
|
||||||
$c->session->{uid} = $res;
|
$c->session->{uid} = $res;
|
||||||
$c->flash(msg => "Logged in.");
|
$c->flash(msg => "Logged in.");
|
||||||
$c->redirect_to('/my');
|
$c->redirect_to('/my');
|
||||||
})->catch(sub ($err) {
|
})->catch(sub ($err) {
|
||||||
$c->flash(msg => "Login failed.");
|
$c->flash(msg => "Login failed.");
|
||||||
$c->redirect_to('/login');
|
$c->redirect_to('/login');
|
||||||
});
|
});
|
||||||
|
} elsif ($config->{auth} eq 'db') {
|
||||||
|
return $c->users->get($username)->then(sub ($uid) {
|
||||||
|
if (!defined $uid) {
|
||||||
|
$c->flash(msg => "Login failed.");
|
||||||
|
return $c->redirect_to('/login');
|
||||||
|
}
|
||||||
|
return $c->users->get_pass_hash($uid)->then(sub ($hash) {
|
||||||
|
if (IpfsUpload::Util::check_pass($password, $hash)) {
|
||||||
|
$c->session->{uid} = $uid;
|
||||||
|
$c->flash(msg => "Logged in.");
|
||||||
|
return $c->redirect_to('/my');
|
||||||
|
}
|
||||||
|
die "Login failed.";
|
||||||
|
});
|
||||||
|
})->catch(sub ($err) {
|
||||||
|
$c->flash(msg => "Login failed.");
|
||||||
|
$c->redirect_to('/login');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub login($c) {
|
sub login($c) {
|
||||||
|
|
|
@ -69,4 +69,20 @@ sub getOrMake($self, $username) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get($self, $username) {
|
||||||
|
return $self->sql->db->select_p('users', ['uid'], {username => $username})->then(sub ($res) {
|
||||||
|
my $val = $res->hash;
|
||||||
|
if (defined $val) {
|
||||||
|
return $val->{uid};
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_pass_hash($self, $uid) {
|
||||||
|
return $self->sql->db->select_p('users', ['pass'], {uid => $uid})->then(sub ($res) {
|
||||||
|
return $res->hash->{pass};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -6,6 +6,18 @@ use experimental qw/signatures/;
|
||||||
use Mojo::JSON qw/decode_json encode_json/;
|
use Mojo::JSON qw/decode_json encode_json/;
|
||||||
use Time::Piece;
|
use Time::Piece;
|
||||||
|
|
||||||
|
use Crypt::Argon2 qw/argon2id_pass argon2id_verify/;
|
||||||
|
use Bytes::Random::Secure qw/random_bytes_hex/;
|
||||||
|
|
||||||
|
sub add_pass($pass) {
|
||||||
|
my $salt = random_bytes_hex(16);
|
||||||
|
my $encoded = argon2id_pass($pass, $salt, '32M', 1, 16);
|
||||||
|
return $encoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub check_pass($pass, $hash) {
|
||||||
|
return argon2id_verify($hash, $pass);
|
||||||
|
}
|
||||||
|
|
||||||
sub date_format($date) {
|
sub date_format($date) {
|
||||||
$date =~ s/ /T/;
|
$date =~ s/ /T/;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE users ADD pass varchar(512);
|
|
@ -0,0 +1 @@
|
||||||
|
alter table users add pass text;
|
Loading…
Reference in New Issue