Add username/password auth.

This commit is contained in:
Citlali del Rey 2022-11-05 09:09:12 -07:00
parent b605bd2242
commit 3186adefc9
Signed by: nullobsi
GPG Key ID: 933A1F44222C2634
6 changed files with 74 additions and 17 deletions

View File

@ -6,6 +6,11 @@ database:
type: 'postgres'
connection: 'postgresql://'
# Use ldap auth
ldap:
uri: 'ldaps://127.0.0.1'
dnBase: 'CN=%u,OU=Users,DC=example,DC=org';
ipfs:
# Please add leading slash
gatewayWriteUrl: "http://localhost:5001/"

View File

@ -22,12 +22,20 @@ sub startup($self) {
my $auth = $c->req->headers->authorization;
if (defined $auth) {
$auth =~ s/Bearer //;
my $uid = $c->users->id($auth);
my $uid = $c->users->id_from_token($auth);
if (defined $uid) {
$c->stash(uid => $uid);
return $c->$cb();
}
}
# Try session auth
my $uid = $c->session->{uid};
if (defined $uid) {
$c->stash(uid => $uid);
return $c->$cb();
}
return $c->$cb('Authorization header not present');
},
},
@ -57,7 +65,8 @@ sub startup($self) {
my $r = $self->routes;
# Normal route to controller
$r->get('/')->to('Example#welcome');
$r->get('/login')->to('Login#login');
$r->post('/auth')->to('Login#auth');
}
1;

View File

@ -1,11 +0,0 @@
package IpfsUpload::Controller::Example;
use Mojo::Base 'Mojolicious::Controller', -signatures;
# This action will render a template
sub welcome($self) {
# Render template "example/welcome.html.ep" with message
$self->render(msg => 'Welcome to the Mojolicious real-time web framework!');
}
1;

View File

@ -5,12 +5,33 @@ use experimental q/signatures/;
use Mojo::Base 'Mojolicious::Controller', -signatures;
use Net::LDAPS;
use Net::LDAP::Extension::SetPassword;
sub auth($c) {
$c->openapi->valid_input or return;
my $v = $c->validation;
my $token = $c->req->headers->authorization;
$v->required('username', 'trim')->size(1,32)->like(qr/^([a-z_][a-z0-9_-]*[\$]?)$/);
$v->required('password');
my $username = $c->param('username');
my $password = $c->param('password');
my $config = $c->config;
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(message => "Logged in.");
$c->redirect_to('/my');
});
$c->render(openapi => {
count => 0,
@ -18,4 +39,12 @@ sub auth($c) {
});
}
sub login($c) {
my $uid = $c->session->{uid};
if (defined $uid) {
return $c->redirect_to('my');
}
return $c->render();
}
1;

View File

@ -7,7 +7,7 @@ use Mojo::Base -base, -signatures;
has 'pg';
sub id($self, $token) {
sub id_from_token($self, $token) {
my $res = $self->pg->db->select('access_token', ['uid'], { token => $token })->hash;
if (!defined $res) {
@ -17,5 +17,15 @@ sub id($self, $token) {
return $res->{uid};
}
sub getOrMake($self, $username) {
return $self->pg->db->select_p('users', ['uid'], {username => $username})->then(sub ($res) {
if ($res->rows != 0) {
return $res->hash->{uid};
}
return $self->pg->db->insert_p('users', {username => $username}, {returning => 'uid'})->then(sub ($n) {
return $n->hash->{uid};
});
});
}
1;

View File

@ -0,0 +1,15 @@
% layout "default";
% title "Login";
<h1>Login</h1>
%= form_for auth => (method => 'POST') => begin
<p>
%= label_for username => 'Username'
%= text_field 'username', id=>'username'
</p>
<p>
%= label_for password => 'Password'
%= password_field 'password', id=>'password'
</p>
%= submit_button
% end