Commit d4afe13f authored by Yann's avatar Yann

Add htpasswd file support for user authentication

Fixes based on merge request discussion by Luc Didry: https://framagit.org/luc/lufi/merge_requests/7

Coding style
parent 9d5bb760
......@@ -15,3 +15,4 @@ requires 'Filesys::DfPortable';
requires 'Switch';
requires 'Data::Entropy';
requires 'Net::LDAP';
requires 'Apache::Htpasswd';
......@@ -4,6 +4,7 @@ use Mojo::Base 'Mojolicious';
use LufiDB;
use Data::Entropy qw(entropy_source);
use Net::LDAP;
use Apache::Htpasswd;
$ENV{MOJO_MAX_WEBSOCKET_SIZE} = 100485760; # 10 * 1024 * 1024 = 10MiB
......@@ -61,6 +62,9 @@ sub startup {
# Debug
$self->plugin('DebugDumperHelper');
# Check htpasswd file existence
die 'Unable to read '.$self->config('htpasswd') if (defined($self->config('htpasswd')) && !-r $self->config('htpasswd'));
# Authentication (if configured)
$self->plugin('authentication' =>
{
......@@ -74,41 +78,51 @@ sub startup {
validate_user => sub {
my ($c, $username, $password, $extradata) = @_;
my $ldap = Net::LDAP->new($c->config->{ldap}->{uri});
my $mesg = $ldap->bind($c->config->{ldap}->{bind_user}.$c->config->{ldap}->{bind_dn},
password => $c->config->{ldap}->{bind_pwd}
);
$mesg->code && die $mesg->error;
$mesg = $ldap->search(
base => $c->config->{ldap}->{user_tree},
filter => "(&(uid=$username)".$c->config->{ldap}->{user_filter}.")"
);
if ($mesg->code) {
$c->app->log->error($mesg->error);
return undef;
}
# Now we know that the user exists
$mesg = $ldap->bind('uid='.$username.$c->config->{ldap}->{bind_dn},
password => $password
);
if ($mesg->code) {
$c->app->log->info("[LDAP authentication failed] login: $username, IP: ".$c->ip);
$c->app->log->error("[LDAP authentication failed] ".$mesg->error);
return undef;
if (defined($c->config('ldap'))) {
my $ldap = Net::LDAP->new($c->config->{ldap}->{uri});
my $mesg = $ldap->bind($c->config->{ldap}->{bind_user}.$c->config->{ldap}->{bind_dn},
password => $c->config->{ldap}->{bind_pwd}
);
$mesg->code && die $mesg->error;
$mesg = $ldap->search(
base => $c->config->{ldap}->{user_tree},
filter => "(&(uid=$username)".$c->config->{ldap}->{user_filter}.")"
);
if ($mesg->code) {
$c->app->log->error($mesg->error);
return undef;
}
# Now we know that the user exists
$mesg = $ldap->bind('uid='.$username.$c->config->{ldap}->{bind_dn},
password => $password
);
if ($mesg->code) {
$c->app->log->info("[LDAP authentication failed] login: $username, IP: ".$c->ip);
$c->app->log->error("[LDAP authentication failed] ".$mesg->error);
return undef;
}
$c->app->log->info("[LDAP authentication successful] login: $username, IP: ".$c->ip);
} elsif (defined($c->config('htpasswd'))) {
my $htpasswd = new Apache::Htpasswd({passwdFile => $c->config->{htpasswd},
ReadOnly => 1}
);
if (!$htpasswd->htCheckPassword($username, $password)) {
return undef;
}
$c->app->log->info("[Simple authentication successful] login: $username, IP: ".$c->ip);
}
$c->app->log->info("[LDAP authentication successful] login: $username, IP: ".$c->ip);
return $username;
}
}
);
if (defined($self->config('ldap'))) {
if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) {
$self->app->sessions->default_expiration($self->config('session_duration'));
}
......@@ -238,14 +252,14 @@ sub startup {
# Page for files uploading
$r->get('/' => sub {
my $c = shift;
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->render(template => 'index');
} else {
$c->redirect_to('login');
}
})->name('index');
if (defined $self->config('ldap')) {
if (defined $self->config('ldap') || defined $self->config('htpasswd')) {
# Login page
$r->get('/login' => sub {
my $c = shift;
......@@ -291,7 +305,7 @@ sub startup {
# List of files (use localstorage, so the server know nothing about files)
$r->get('/files' => sub {
my $c = shift;
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->render(template => 'files');
} else {
$c->redirect_to('login');
......
......@@ -13,7 +13,7 @@ use Filesys::DfPortable;
sub upload {
my $c = shift;
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->inactivity_timeout(30000000);
$c->app->log->debug('Client connected');
......@@ -97,7 +97,7 @@ sub upload {
}
my $creator = $c->ip;
if (defined($c->config('ldap'))) {
if (defined($c->config('ldap')) || defined($c->config('htpasswd'))) {
$creator = 'User: '.$c->current_user.', IP: '.$creator;
}
$f = Lufi::File->new(
......@@ -303,7 +303,7 @@ sub get_counter {
my $short = $c->param('short');
my $token = $c->param('token');
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
my @records = LufiDB::Files->select('WHERE short = ?', $short);
if (scalar(@records)) {
if ($records[0]->mod_token eq $token) {
......@@ -352,7 +352,7 @@ sub delete {
my $short = $c->param('short');
my $token = $c->param('token');
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
my @records = LufiDB::Files->select('WHERE short = ? AND mod_token = ?', ($short, $token));
if (scalar(@records)) {
my $f = Lufi::File->new(record => $records[0]);
......
......@@ -132,6 +132,10 @@
# user_filter => '!(uid=ldap_user)'
#},
# set `htpasswd` if you want to use an htpasswd file instead of ldap
# see 'man htpasswd' to know how to create such file
#htpasswd => 'lufi.passwd',
# if you've set ldap above, the session will last `session_duration` seconds before
# the user needs to reauthenticate
# optional, default is 3600
......
......@@ -31,26 +31,26 @@
<a href="<%= url_for('/') %>" class="brand-logo">&nbsp;<img src="<%= url_for('/img/lufi-min.png') %>" alt="logo"> Lufi</a>
<a href="#" data-activates="mobile-demo" class="button-collapse"><i class="mdi-navigation-menu"></i></a>
<ul id="nav-mobile" class="right hide-on-med-and-down">
% if (!defined(config('ldap')) || is_user_authenticated()) {
% if ((!defined(config('ldap')) && !defined(config('htpasswd'))) || is_user_authenticated()) {
<li<%== ' class="active"' if (current_route eq 'index') %>><a href="<%= url_for('/') %>"><%= l('Upload files') %></a></li>
<li<%== ' class="active"' if (current_route eq 'files') %>><a href="<%= url_for('/files') %>"><%= l('My files') %></a></li>
% } else {
<li><a href="<%= url_for('/login') %>"><%= l('Signin') %></a></li>
% }
<li<%== ' class="active"' if (current_route eq 'about') %>><a href="<%= url_for('/about') %>"><%= l('About') %></a></li>
% if (defined(config('ldap')) && is_user_authenticated()) {
% if ((defined(config('ldap')) || defined(config('htpasswd'))) && is_user_authenticated()) {
<li><a href="<%= url_for('/logout') %>"><%= l('Logout') %></a></li>
% }
</ul>
<ul id="mobile-demo" class="side-nav">
% if (!defined(config('ldap')) || is_user_authenticated()) {
% if ((!defined(config('ldap')) && !defined(config('htpasswd'))) || is_user_authenticated()) {
<li<%== ' class="active"' if (current_route eq 'index') %>><a href="<%= url_for('/') %>"><%= l('Upload files') %></a></li>
<li<%== ' class="active"' if (current_route eq 'files') %>><a href="<%= url_for('/files') %>"><%= l('My files') %></a></li>
% } else {
<li><a href="<%= url_for('/login') %>"><%= l('Signin') %></a></li>
% }
<li<%== ' class="active"' if (current_route eq 'about') %>><a href="<%= url_for('/about') %>"><%= l('About') %></a></li>
% if (defined(config('ldap')) && is_user_authenticated()) {
% if ((defined(config('ldap')) || defined(config('htpasswd'))) && is_user_authenticated()) {
<li><a href="<%= url_for('/logout') %>"><%= l('Logout') %></a></li>
% }
</ul>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment