Add argon2id password auth (through DB)

This commit is contained in:
Citlali del Rey 2023-02-22 21:58:58 -08:00
parent e999d1309e
commit 5bb8febfa2
Signed by: nullobsi
GPG Key ID: 933A1F44222C2634
7 changed files with 74 additions and 17 deletions

View File

@ -11,6 +11,8 @@ WriteMakefile(
'Mojo::Pg' => '4.27',
'Mojo::SQLite' => '3.009',
'Crypt::Random' => '1.25',
'Crypt::Argon2' => '0.013',
'Bytes::Random::Secure' => '0.29',
'Number::Bytes::Human' => '0.11',
},
test => {TESTS => 't/*.t'}

View File

@ -37,6 +37,11 @@ sub startup($self) {
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) {
if ($dbtype eq "postgres") {

View File

@ -21,24 +21,44 @@ sub auth($c) {
my $config = $c->config;
my $connStr = $config->{'ldap'}->{'uri'};
my $bindDN = $config->{'ldap'}->{'dnBase'};
$bindDN =~ s/%u/$username/;
if ($config->{auth} eq 'ldap') {
my $connStr = $config->{'ldap'}->{'uri'};
my $bindDN = $config->{'ldap'}->{'dnBase'};
$bindDN =~ s/%u/$username/;
return Mojo::IOLoop->subprocess->run_p(sub {
my $ldap= Net::LDAPS->new($connStr, verify=>'none', version=>3) or die "$@";
my $mesg = $ldap->bind($bindDN, password=>$password);
$mesg->code and die $mesg->error;
})->then(sub ($res) {
return $c->users->getOrMake($username);
})->then(sub ($res) {
$c->session->{uid} = $res;
$c->flash(msg => "Logged in.");
$c->redirect_to('/my');
})->catch(sub ($err) {
$c->flash(msg => "Login failed.");
$c->redirect_to('/login');
});
return Mojo::IOLoop->subprocess->run_p(sub {
my $ldap= Net::LDAPS->new($connStr, verify=>'none', version=>3) or die "$@";
my $mesg = $ldap->bind($bindDN, password=>$password);
$mesg->code and die $mesg->error;
})->then(sub ($res) {
return $c->users->getOrMake($username);
})->then(sub ($res) {
$c->session->{uid} = $res;
$c->flash(msg => "Logged in.");
$c->redirect_to('/my');
})->catch(sub ($err) {
$c->flash(msg => "Login failed.");
$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) {

View File

@ -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;

View File

@ -6,6 +6,18 @@ use experimental qw/signatures/;
use Mojo::JSON qw/decode_json encode_json/;
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) {
$date =~ s/ /T/;

1
schema/dbauth.psql Normal file
View File

@ -0,0 +1 @@
ALTER TABLE users ADD pass varchar(512);

1
schema/dbauth.sql Normal file
View File

@ -0,0 +1 @@
alter table users add pass text;