Fix #82 - Add optional authentication

This commit is contained in:
Luc Didry
2018-07-29 20:14:46 +02:00
parent 07344aa0c9
commit 182f4ccf4e
14 changed files with 747 additions and 52 deletions
+1
View File
@@ -17,3 +17,4 @@ themes/default/templates/partial/raw.js.ep
tmp/*
.zanata-cache/*
cover_db/*
*.passwd
+1
View File
@@ -21,6 +21,7 @@ Revision history for Lutim
- Add localStorage export and import feature
- Add link to generate random file in collection
- Add modal to modify expiration delay from "myfiles" page
- Add optional authentication (LDAP or htpasswd file)
0.10.4 2018-05-07
- Fix bug in cache system that would allow someone to view an image with an incorrect decryption key
+8
View File
@@ -45,6 +45,14 @@ feature 'memcached', 'Cache system using Memcached' => sub {
requires 'CHI::Driver::Memcached';
requires 'Cache::Memcached';
};
feature 'ldap', 'LDAP authentication support' => sub {
requires 'Net::LDAP';
requires 'Mojolicious::Plugin::Authentication';
};
feature 'htpasswd', 'Htpasswd authentication support' => sub {
requires 'Apache::Htpasswd';
requires 'Mojolicious::Plugin::Authentication';
};
feature 'test' => sub {
requires 'Devel::Cover';
};
+382
View File
@@ -1,5 +1,14 @@
# carton snapshot format: version 1.0
DISTRIBUTIONS
Apache-Htpasswd-1.9
pathname: K/KM/KMELTZ/Apache-Htpasswd-1.9.tar.gz
provides:
Apache::Htpasswd 1.9
requirements:
Crypt::PasswdMD5 0
Digest::SHA 2
ExtUtils::MakeMaker 0
MIME::Base64 0
Archive-Zip-1.60
pathname: P/PH/PHRED/Archive-Zip-1.60.tar.gz
provides:
@@ -29,6 +38,27 @@ DISTRIBUTIONS
IO::Seekable 0
Time::Local 0
perl 5.006
Authen-SASL-2.16
pathname: G/GB/GBARR/Authen-SASL-2.16.tar.gz
provides:
Authen::SASL 2.16
Authen::SASL::CRAM_MD5 2.14
Authen::SASL::EXTERNAL 2.14
Authen::SASL::Perl 2.14
Authen::SASL::Perl::ANONYMOUS 2.14
Authen::SASL::Perl::CRAM_MD5 2.14
Authen::SASL::Perl::DIGEST_MD5 2.14
Authen::SASL::Perl::EXTERNAL 2.14
Authen::SASL::Perl::GSSAPI 0.05
Authen::SASL::Perl::LOGIN 2.14
Authen::SASL::Perl::Layer 2.14
Authen::SASL::Perl::PLAIN 2.14
requirements:
Digest::HMAC_MD5 0
Digest::MD5 0
ExtUtils::MakeMaker 6.42
Test::More 0
perl 5.005
B-Hooks-EndOfScope-0.24
pathname: E/ET/ETHER/B-Hooks-EndOfScope-0.24.tar.gz
provides:
@@ -215,6 +245,14 @@ DISTRIBUTIONS
ExtUtils::MakeMaker 0
Storable 0
perl 5.008001
Convert-ASN1-0.27
pathname: G/GB/GBARR/Convert-ASN1-0.27.tar.gz
provides:
Convert::ASN1 0.27
requirements:
ExtUtils::MakeMaker 6.30
Math::BigInt 1.997
Test::More 0.90
Crypt-Blowfish-2.14
pathname: D/DP/DPARIS/Crypt-Blowfish-2.14.tar.gz
provides:
@@ -228,6 +266,16 @@ DISTRIBUTIONS
requirements:
Digest::MD5 2.00
ExtUtils::MakeMaker 0
Crypt-PasswdMD5-1.40
pathname: R/RS/RSAVAGE/Crypt-PasswdMD5-1.40.tgz
provides:
Crypt::PasswdMD5 1.40
requirements:
Digest::MD5 2.53
Module::Build 0
Test::More 0.94
strict 0
warnings 0
Crypt-Rijndael-1.13
pathname: L/LE/LEONT/Crypt-Rijndael-1.13.tar.gz
provides:
@@ -1042,6 +1090,17 @@ DISTRIBUTIONS
perl 5.006
strict 0
warnings 0
Digest-HMAC-1.03
pathname: G/GA/GAAS/Digest-HMAC-1.03.tar.gz
provides:
Digest::HMAC 1.03
Digest::HMAC_MD5 1.01
Digest::HMAC_SHA1 1.03
requirements:
Digest::MD5 2
Digest::SHA 1
ExtUtils::MakeMaker 0
perl 5.004
Digest-JHash-0.10
pathname: S/SH/SHLOMIF/Digest-JHash-0.10.tar.gz
provides:
@@ -1075,6 +1134,15 @@ DISTRIBUTIONS
Canary::Stability 0
ExtUtils::MakeMaker 6.52
common::sense 0
Encode-Locale-1.05
pathname: G/GA/GAAS/Encode-Locale-1.05.tar.gz
provides:
Encode::Locale 1.05
requirements:
Encode 2
Encode::Alias 0
ExtUtils::MakeMaker 0
perl 5.008
Eval-Closure-0.14
pathname: D/DO/DOY/Eval-Closure-0.14.tar.gz
provides:
@@ -1188,6 +1256,19 @@ DISTRIBUTIONS
File::Spec 0
URI::Escape 0
perl 5.008006
File-Listing-6.04
pathname: G/GA/GAAS/File-Listing-6.04.tar.gz
provides:
File::Listing 6.04
File::Listing::apache 6.04
File::Listing::dosftp 6.04
File::Listing::netware 6.04
File::Listing::unix 6.04
File::Listing::vms 6.04
requirements:
ExtUtils::MakeMaker 0
HTTP::Date 6
perl 5.006002
File-MimeInfo-0.28
pathname: M/MI/MICHIELB/File-MimeInfo-0.28.tar.gz
provides:
@@ -1269,6 +1350,46 @@ DISTRIBUTIONS
HTML::Tagset 3.20
requirements:
ExtUtils::MakeMaker 0
HTTP-Cookies-6.04
pathname: O/OA/OALDERS/HTTP-Cookies-6.04.tar.gz
provides:
HTTP::Cookies 6.04
HTTP::Cookies::Microsoft 6.04
HTTP::Cookies::Netscape 6.04
requirements:
Carp 0
ExtUtils::MakeMaker 0
HTTP::Date 6
HTTP::Headers::Util 6
HTTP::Request 0
Time::Local 0
locale 0
perl 5.008001
strict 0
vars 0
HTTP-Daemon-6.01
pathname: G/GA/GAAS/HTTP-Daemon-6.01.tar.gz
provides:
HTTP::Daemon 6.01
HTTP::Daemon::ClientConn 6.01
requirements:
ExtUtils::MakeMaker 0
HTTP::Date 6
HTTP::Request 6
HTTP::Response 6
HTTP::Status 6
IO::Socket 0
LWP::MediaTypes 6
Sys::Hostname 0
perl 5.008001
HTTP-Date-6.02
pathname: G/GA/GAAS/HTTP-Date-6.02.tar.gz
provides:
HTTP::Date 6.02
requirements:
ExtUtils::MakeMaker 0
Time::Local 0
perl 5.006002
HTTP-Lite-2.44
pathname: N/NE/NEILB/HTTP-Lite-2.44.tar.gz
provides:
@@ -1280,6 +1401,52 @@ DISTRIBUTIONS
perl 5.005
strict 0
warnings 0
HTTP-Message-6.18
pathname: O/OA/OALDERS/HTTP-Message-6.18.tar.gz
provides:
HTTP::Config 6.18
HTTP::Headers 6.18
HTTP::Headers::Auth 6.18
HTTP::Headers::ETag 6.18
HTTP::Headers::Util 6.18
HTTP::Message 6.18
HTTP::Request 6.18
HTTP::Request::Common 6.18
HTTP::Response 6.18
HTTP::Status 6.18
requirements:
Carp 0
Compress::Raw::Zlib 0
Encode 2.21
Encode::Locale 1
Exporter 5.57
ExtUtils::MakeMaker 0
HTTP::Date 6
IO::Compress::Bzip2 2.021
IO::Compress::Deflate 0
IO::Compress::Gzip 0
IO::HTML 0
IO::Uncompress::Bunzip2 2.021
IO::Uncompress::Gunzip 0
IO::Uncompress::Inflate 0
IO::Uncompress::RawInflate 0
LWP::MediaTypes 6
MIME::Base64 2.1
MIME::QuotedPrint 0
Storable 0
URI 1.10
base 0
perl 5.008001
strict 0
warnings 0
HTTP-Negotiate-6.01
pathname: G/GA/GAAS/HTTP-Negotiate-6.01.tar.gz
provides:
HTTP::Negotiate 6.01
requirements:
ExtUtils::MakeMaker 0
HTTP::Headers 6
perl 5.008001
Hash-Merge-0.300
pathname: R/RE/REHSACK/Hash-Merge-0.300.tar.gz
provides:
@@ -1295,6 +1462,15 @@ DISTRIBUTIONS
Hash::MoreUtils 0.05
requirements:
Test::More 0.90
IO-HTML-1.001
pathname: C/CJ/CJM/IO-HTML-1.001.tar.gz
provides:
IO::HTML 1.001
requirements:
Carp 0
Encode 2.10
Exporter 5.57
ExtUtils::MakeMaker 6.30
IO-Socket-SSL-2.056
pathname: S/SU/SULLR/IO-Socket-SSL-2.056.tar.gz
provides:
@@ -1516,6 +1692,14 @@ DISTRIBUTIONS
requirements:
ExtUtils::MakeMaker 0
perl 5.004
JSON-2.97001
pathname: I/IS/ISHIGAKI/JSON-2.97001.tar.gz
provides:
JSON 2.97001
JSON::Backend::PP 2.97001
requirements:
ExtUtils::MakeMaker 0
Test::More 0
JSON-MaybeXS-1.004000
pathname: H/HA/HAARG/JSON-MaybeXS-1.004000.tar.gz
provides:
@@ -1526,6 +1710,13 @@ DISTRIBUTIONS
JSON::PP 2.27300
Scalar::Util 0
perl 5.006
LWP-MediaTypes-6.02
pathname: G/GA/GAAS/LWP-MediaTypes-6.02.tar.gz
provides:
LWP::MediaTypes 6.02
requirements:
ExtUtils::MakeMaker 0
perl 5.006002
List-MoreUtils-0.428
pathname: R/RE/REHSACK/List-MoreUtils-0.428.tar.gz
provides:
@@ -1920,6 +2111,16 @@ DISTRIBUTIONS
Pod::Simple 3.09
Time::Local 1.2
perl 5.010001
Mojolicious-Plugin-Authentication-1.33
pathname: J/JJ/JJATRIA/Mojolicious-Plugin-Authentication-1.33.tar.gz
provides:
Mojolicious::Plugin::Authentication 1.33
requirements:
ExtUtils::MakeMaker 0
Mojo::Base 0
perl 5.010
strict 0
warnings 0
Mojolicious-Plugin-CHI-0.15
pathname: A/AK/AKRON/Mojolicious-Plugin-CHI-0.15.tar.gz
provides:
@@ -2420,6 +2621,25 @@ DISTRIBUTIONS
Carp 0
ExtUtils::MakeMaker 0
Storable 0
Net-HTTP-6.18
pathname: O/OA/OALDERS/Net-HTTP-6.18.tar.gz
provides:
Net::HTTP 6.18
Net::HTTP::Methods 6.18
Net::HTTP::NB 6.18
Net::HTTPS 6.18
requirements:
Carp 0
Compress::Raw::Zlib 0
ExtUtils::MakeMaker 0
IO::Socket::INET 0
IO::Uncompress::Gunzip 0
URI 0
base 0
perl 5.006002
strict 0
vars 0
warnings 0
Net-SSLeay-1.85
pathname: M/MI/MIKEM/Net-SSLeay-1.85.tar.gz
provides:
@@ -2773,6 +2993,13 @@ DISTRIBUTIONS
Test::Builder 0.13
Test::Builder::Tester 1.02
perl 5.006
Text-Soundex-3.05
pathname: R/RJ/RJBS/Text-Soundex-3.05.tar.gz
provides:
Text::Soundex 3.05
requirements:
ExtUtils::MakeMaker 0
if 0
Text-Unidecode-1.30
pathname: S/SB/SBURKE/Text-Unidecode-1.30.tar.gz
provides:
@@ -2955,12 +3182,86 @@ DISTRIBUTIONS
base 0
lib 0
perl 5.008
WWW-RobotRules-6.02
pathname: G/GA/GAAS/WWW-RobotRules-6.02.tar.gz
provides:
WWW::RobotRules 6.02
WWW::RobotRules::AnyDBM_File 6.00
WWW::RobotRules::InCore 6.02
requirements:
AnyDBM_File 0
ExtUtils::MakeMaker 0
Fcntl 0
URI 1.10
perl 5.008001
common-sense-3.74
pathname: M/ML/MLEHMANN/common-sense-3.74.tar.gz
provides:
common::sense 3.74
requirements:
ExtUtils::MakeMaker 0
libwww-perl-6.35
pathname: E/ET/ETHER/libwww-perl-6.35.tar.gz
provides:
LWP 6.35
LWP::Authen::Basic 6.35
LWP::Authen::Digest 6.35
LWP::Authen::Ntlm 6.35
LWP::ConnCache 6.35
LWP::Debug 6.35
LWP::Debug::TraceHTTP 6.35
LWP::DebugFile 6.35
LWP::MemberMixin 6.35
LWP::Protocol 6.35
LWP::Protocol::cpan 6.35
LWP::Protocol::data 6.35
LWP::Protocol::file 6.35
LWP::Protocol::ftp 6.35
LWP::Protocol::gopher 6.35
LWP::Protocol::http 6.35
LWP::Protocol::loopback 6.35
LWP::Protocol::mailto 6.35
LWP::Protocol::nntp 6.35
LWP::Protocol::nogo 6.35
LWP::RobotUA 6.35
LWP::Simple 6.35
LWP::UserAgent 6.35
libwww::perl undef
requirements:
CPAN::Meta::Requirements 2.120620
Digest::MD5 0
Encode 2.12
Encode::Locale 0
ExtUtils::MakeMaker 0
File::Copy 0
File::Listing 6
Getopt::Long 0
HTML::Entities 0
HTML::HeadParser 0
HTTP::Cookies 6
HTTP::Daemon 6
HTTP::Date 6
HTTP::Negotiate 6
HTTP::Request 6
HTTP::Request::Common 6
HTTP::Response 6
HTTP::Status 6.18
IO::Select 0
IO::Socket 0
LWP::MediaTypes 6
MIME::Base64 2.1
Module::Metadata 0
Net::FTP 2.58
Net::HTTP 6.07
Scalar::Util 0
Try::Tiny 0
URI 1.10
URI::Escape 0
WWW::RobotRules 6
base 0
perl 5.008001
strict 0
warnings 0
namespace-autoclean-0.28
pathname: E/ET/ETHER/namespace-autoclean-0.28.tar.gz
provides:
@@ -2983,3 +3284,84 @@ DISTRIBUTIONS
ExtUtils::MakeMaker 0
Package::Stash 0.23
perl 5.008001
perl-ldap-0.65
pathname: M/MA/MARSCHAP/perl-ldap-0.65.tar.gz
provides:
Bundle::Net::LDAP 0.03
LWP::Protocol::ldap 1.25
LWP::Protocol::ldapi undef
LWP::Protocol::ldaps undef
Net::LDAP 0.65
Net::LDAP::ASN 0.12
Net::LDAP::Bind 1.05
Net::LDAP::Constant 0.23
Net::LDAP::Control 0.18
Net::LDAP::Control::Assertion 0.02
Net::LDAP::Control::DontUseCopy 0.01
Net::LDAP::Control::EntryChange 0.02
Net::LDAP::Control::ManageDsaIT 0.04
Net::LDAP::Control::MatchedValues 0.02
Net::LDAP::Control::Paged 0.05
Net::LDAP::Control::PasswordPolicy 0.04
Net::LDAP::Control::PersistentSearch 0.04
Net::LDAP::Control::PostRead 0.03
Net::LDAP::Control::PreRead 0.04
Net::LDAP::Control::ProxyAuth 1.09
Net::LDAP::Control::Relax 0.03
Net::LDAP::Control::Sort 0.04
Net::LDAP::Control::SortResult 0.03
Net::LDAP::Control::SyncDone 0.03
Net::LDAP::Control::SyncRequest 0.03
Net::LDAP::Control::SyncState 0.04
Net::LDAP::Control::VLV 0.06
Net::LDAP::Control::VLVResponse 0.04
Net::LDAP::DSML 0.16
Net::LDAP::DSML::output 0.16
Net::LDAP::DSML::pp 0.16
Net::LDAP::Entry 0.27
Net::LDAP::Extension 1.04
Net::LDAP::Extension::Cancel 0.02
Net::LDAP::Extension::Refresh 0.03
Net::LDAP::Extension::SetPassword 0.06
Net::LDAP::Extension::WhoAmI 0.02
Net::LDAP::Extra 0.02
Net::LDAP::Extra::AD 0.04
Net::LDAP::Extra::eDirectory 0.03
Net::LDAP::Filter 0.20
Net::LDAP::FilterList 0.02
Net::LDAP::FilterMatch 0.27
Net::LDAP::Intermediate 0.04
Net::LDAP::Intermediate::SyncInfo 0.03
Net::LDAP::LDIF 0.26
Net::LDAP::Message 1.12
Net::LDAP::Message::Dummy 1.12
Net::LDAP::Reference 0.14
Net::LDAP::RootDSE 0.02
Net::LDAP::Schema 0.9908
Net::LDAP::Search 0.14
Net::LDAP::Util 0.19
Net::LDAPI 0.04
Net::LDAPS 0.06
requirements:
Authen::SASL 2.00
Convert::ASN1 0.2
Digest::MD5 0
ExtUtils::MakeMaker 6.42
File::Basename 0
File::Compare 0
File::Path 0
HTTP::Negotiate 0
HTTP::Response 0
HTTP::Status 0
IO::File 0
IO::Socket::SSL 1.26
JSON 0
LWP 0
LWP::MediaTypes 0
LWP::Protocol 0
MIME::Base64 0
Test::More 0
Text::Soundex 0
Time::Local 0
URI::ldap 1.1
perl 5.008001
+164 -23
View File
@@ -52,6 +52,7 @@ sub startup {
dbtype => 'sqlite',
db_path => 'minion.db'
},
session_duration => 3600,
cache_max_size => 0,
memcached_servers => [],
quiet_logs => 0,
@@ -176,6 +177,106 @@ sub startup {
delete @{$wait_for_it}{grep { time - $wait_for_it->{$_} > $self->config->{anti_flood_delay} } keys %{$wait_for_it}} if (defined($wait_for_it));
});
# Authentication (if configured)
if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) {
if (defined($self->config('ldap'))) {
require Net::LDAP;
}
if (defined($self->config('htpasswd'))) {
require Apache::Htpasswd;
}
die 'Unable to read '.$self->config('htpasswd') if (defined($self->config('htpasswd')) && !-r $self->config('htpasswd'));
$self->plugin('Authentication' =>
{
autoload_user => 1,
session_key => 'Lutim',
load_user => sub {
my ($c, $username) = @_;
return $username;
},
validate_user => sub {
my ($c, $username, $password, $extradata) = @_;
if (defined($c->config('ldap'))) {
my $ldap = Net::LDAP->new($c->config->{ldap}->{uri});
my $mesg;
if (defined($c->config->{ldap}->{bind_dn}) && defined($c->config->{ldap}->{bind_pwd})) {
# connect to the ldap server using the bind credentials
$mesg = $ldap->bind(
$c->config->{ldap}->{bind_dn},
password => $c->config->{ldap}->{bind_pwd}
);
} else {
# anonymous bind
$mesg = $ldap->bind
}
if ($mesg->code) {
$c->app->log->info('[LDAP INFO] Authenticated bind failed - Login: '.$c->config->{ldap}->{bind_dn}) if defined($c->config->{ldap}->{bind_dn});
$c->app->log->error('[LDAP ERROR] Error on bind: '.$mesg->error);
return undef;
}
my $ldap_user_attr = $c->config->{ldap}->{user_attr};
my $ldap_user_filter = $c->config->{ldap}->{user_filter};
# search the ldap database for the user who is trying to login
$mesg = $ldap->search(
base => $c->config->{ldap}->{user_tree},
filter => "(&($ldap_user_attr=$username)$ldap_user_filter)"
);
if ($mesg->code) {
$c->app->log->error('[LDAP ERROR] Error on search: '.$mesg->error);
return undef;
}
# check to make sure that the ldap search returned at least one entry
my @entries = $mesg->entries;
my $entry = $entries[0];
unless (defined $entry) {
$c->app->log->info("[LDAP INFO] Authentication failed - User $username filtered out, IP: ".$c->ip);
return undef;
}
# retrieve the first user returned by the search
$c->app->log->debug("[LDAP DEBUG] Found user dn: ".$entry->dn);
# Now we know that the user exists
$mesg = $ldap->bind($entry->dn,
password => $password
);
if ($mesg->code) {
$c->app->log->info("[LDAP INFO] Authentication failed - Login: $username, IP: ".$c->ip);
$c->app->log->error('[LDAP ERROR] Authentication failed '.$mesg->error);
return undef;
}
$c->app->log->info("[LDAP INFO] 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);
}
return $username;
}
}
);
$self->app->sessions->default_expiration($self->config('session_duration'));
}
$self->defaults(layout => 'default');
$self->provisioning();
@@ -183,6 +284,14 @@ sub startup {
# Router
my $r = $self->routes;
$r->add_condition(authorized => sub {
my ($r, $c, $captures) = @_;
return 1 unless (defined($self->config('ldap')) || defined($self->config('htpasswd')));
return $c->is_user_authenticated;
});
$r->options(sub {
my $c = shift;
$c->res->headers->allow('POST') if (defined($c->config->{allowed_domains}));
@@ -190,23 +299,43 @@ sub startup {
});
$r->get('/')->
to('Controller#home')->
over('authorized')->
to('Image#home')->
name('index');
$r->get('/')->
to('Authent#index');
if (defined $self->config('ldap') || defined $self->config('htpasswd')) {
# Login page
$r->get('/login')
->to('Authent#index')
->name('login');
# Authentication
$r->post('/login')
->to('Authent#login');
# Logout page
$r->get('/logout')
->to('Authent#log_out')
->name('logout');
}
$r->get('/about')->
to('Controller#about')->
to('Image#about')->
name('about');
$r->get('/infos')->
to('Controller#infos')->
to('Image#infos')->
name('infos');
$r->get('/stats')->
to('Controller#stats')->
to('Image#stats')->
name('stats');
$r->get('/lang/:l')->
to('Controller#change_lang')->
to('Image#change_lang')->
name('lang');
$r->get('/partial/:file' => sub {
@@ -229,60 +358,72 @@ sub startup {
);
})->name('gallery');
$r->get('/myfiles' => sub {
shift->render(
template => 'myfiles'
);
})->name('myfiles');
$r->get('/myfiles')->
over('authorized')->
name('myfiles');
$r->get('/myfiles')->
to('Authent#index');
$r->get('/manifest.webapp')->
to('Controller#webapp')->
to('Image#webapp')->
name('manifest.webapp');
$r->get('/zip')
->to('Controller#zip')
->to('Image#zip')
->name('zip');
$r->get('/random')
->to('Controller#random')
->to('Image#random')
->name('random');
$r->post('/')->
to('Controller#add')->
over('authorized')->
to('Image#add')->
name('add');
$r->post('/')->
to('Authent#index');
$r->get('/d/:short/:token')->
to('Controller#delete')->
over('authorized')->
to('Image#delete')->
name('delete');
$r->get('/d/:short/:token')->
to('Authent#index');
$r->post('/m/:short/:token')->
to('Controller#modify')->
over('authorized')->
to('Image#modify')->
name('modify');
$r->post('/m/:short/:token')->
to('Authent#index');
$r->post('/c')->
to('Controller#get_counter')->
over('authorized')->
to('Image#get_counter')->
name('counter');
$r->post('/c')->
to('Authent#index');
$r->get('/about/<:short>.<:f>')->
to('Controller#about_img')->
to('Image#about_img')->
name('about_img');
$r->get('/about/:short/<:key>.<:f>')->
to('Controller#about_img')->
to('Image#about_img')->
name('about_img');
$r->get('/<:short>.<:f>')->
to('Controller#short')->
to('Image#short')->
name('short');
$r->get('/:short')->
to('Controller#short');
to('Image#short');
$r->get('/:short/<:key>.<:f>')->
to('Controller#short');
to('Image#short');
$r->get('/:short/:key')->
to('Controller#short');
to('Image#short');
}
1;
+76
View File
@@ -0,0 +1,76 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Controller::Authent;
use Mojo::Base 'Mojolicious::Controller';
sub index {
my $c = shift;
if ($c->is_user_authenticated) {
$c->redirect_to('index');
} else {
$c->render(template => 'login');
}
}
sub login {
my $c = shift;
my $login = $c->param('login');
my $pwd = $c->param('password');
my $ref = $c->req->headers->referrer;
if($c->authenticate($login, $pwd)) {
$c->respond_to(
json => sub {
my $c = shift;
$c->render(
json => {
success => Mojo::JSON->true,
msg => $c->l('You have been successfully logged in.')
}
);
},
any => sub {
$c->redirect_to($ref);
}
);
} else {
my $msg = $c->l('Please, check your credentials: unable to authenticate.');
$c->respond_to(
json => sub {
my $c = shift;
$c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
},
any => sub {
$c->stash(msg => $msg);
$c->render(template => 'login')
}
);
}
}
sub log_out {
my $c = shift;
if ($c->is_user_authenticated) {
$c->logout;
}
$c->respond_to(
json => sub {
my $c = shift;
$c->render(
json => {
success => Mojo::JSON->true,
msg => $c->l('You have been successfully logged out.')
}
);
},
any => sub {
$c->render(template => 'logout');
}
);
}
1;
@@ -1,5 +1,5 @@
# vim:set sw=4 ts=4 sts=4 expandtab:
package Lutim::Controller;
package Lutim::Controller::Image;
use Mojo::Base 'Mojolicious::Controller';
use Mojo::Util qw(url_escape url_unescape b64_encode encode);
use Mojo::Asset::Memory;
+23
View File
@@ -159,6 +159,29 @@
# }
#},
# set `ldap` if you want that only authenticated users can shorten URLs
# please note that everybody can still use shortend URLs
# optional, no default
#ldap => {
# uri => 'ldaps://ldap.example.org', # server URI
# user_tree => 'ou=users,dc=example,dc=org', # search base DN
# bind_dn => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN
# bind_pwd => 'secr3t', # search bind password
# user_attr => 'uid', # user attribute (uid, mail, sAMAccountName, etc.)
# user_filter => '(!(uid=ldap_user))', # user filter (to exclude some users, etc.)
#},
# set `htpasswd` if you want to use an htpasswd file instead of ldap
# create the file with `htpasswd -c lutim.passwd user`, update it with `htpasswd lutim.passwd user2`
# make sure that lutim can read the file!
# optional, no default
#htpasswd => 'lutim.passwd',
# if you've set ldap or htpasswd above, the session will last `session_duration` seconds before
# the user needs to reauthenticate
# optional, default is 3600
#session_duration => 3600,
# disable counters of images
# set to 1 to disable counters
# optional, counters are enabled by default
+54 -26
View File
@@ -32,11 +32,11 @@ msgstr ""
msgid "-or-"
msgstr ""
#: lib/Lutim.pm:221 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 themes/default/templates/index.html.ep:5 themes/default/templates/myfiles.html.ep:5 themes/default/templates/partial/raw.js.ep:25 themes/default/templates/partial/raw.js.ep:8 themes/default/templates/raw.html.ep:10
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 themes/default/templates/index.html.ep:5 themes/default/templates/myfiles.html.ep:5 themes/default/templates/partial/raw.js.ep:25 themes/default/templates/partial/raw.js.ep:8 themes/default/templates/raw.html.ep:10
msgid "1 year"
msgstr ""
#: lib/Lutim.pm:220 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 themes/default/templates/index.html.ep:4 themes/default/templates/myfiles.html.ep:33 themes/default/templates/myfiles.html.ep:4 themes/default/templates/partial/for_my_delay.html.ep:13 themes/default/templates/partial/lutim.js.ep:149 themes/default/templates/partial/raw.js.ep:22 themes/default/templates/partial/raw.js.ep:5 themes/default/templates/raw.html.ep:7
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 themes/default/templates/index.html.ep:4 themes/default/templates/myfiles.html.ep:33 themes/default/templates/myfiles.html.ep:4 themes/default/templates/partial/for_my_delay.html.ep:13 themes/default/templates/partial/lutim.js.ep:149 themes/default/templates/partial/raw.js.ep:22 themes/default/templates/partial/raw.js.ep:5 themes/default/templates/raw.html.ep:7
msgid "24 hours"
msgstr ""
@@ -44,7 +44,7 @@ msgstr ""
msgid ": Error while trying to get the counter."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:69
#: themes/default/templates/partial/navbar.html.ep:80
msgid "About"
msgstr ""
@@ -52,7 +52,7 @@ msgstr ""
msgid "Active images"
msgstr ""
#: lib/Lutim/Controller.pm:327
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr ""
@@ -168,7 +168,7 @@ msgstr ""
msgid "For more details, see the <a href=\"https://framagit.org/luc/lutim\">homepage of the project</a>."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:72
#: themes/default/templates/partial/navbar.html.ep:83
msgid "Fork me!"
msgstr ""
@@ -212,7 +212,7 @@ msgstr ""
msgid "Image deleted"
msgstr ""
#: lib/Lutim/Controller.pm:753
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr ""
@@ -220,7 +220,7 @@ msgstr ""
msgid "Import localStorage data"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:61
#: themes/default/templates/partial/navbar.html.ep:72
msgid "Informations"
msgstr ""
@@ -248,7 +248,7 @@ msgstr ""
msgid "Keep EXIF tags"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:32
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr ""
@@ -256,7 +256,7 @@ msgstr ""
msgid "Let's go!"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:66
#: themes/default/templates/partial/navbar.html.ep:77
msgid "License:"
msgstr ""
@@ -264,6 +264,14 @@ msgstr ""
msgid "Link for share on social networks"
msgstr ""
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr ""
#: themes/default/templates/zip.html.ep:7
msgid "Lutim can't zip so many images at once, so it splitted your demand in multiple URLs."
msgstr ""
@@ -308,6 +316,10 @@ msgstr ""
msgid "Only the uploader! (well, only if he's the only owner of the images' rights before the upload)"
msgstr ""
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr ""
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
@@ -317,6 +329,10 @@ msgstr ""
msgid "Please contact the administrator: %1"
msgstr ""
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr ""
@@ -337,28 +353,32 @@ msgstr ""
msgid "Send an image"
msgstr ""
#: themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5 themes/default/templates/partial/navbar.html.ep:37
msgid "Signin"
msgstr ""
#: themes/default/templates/index.html.ep:151 themes/default/templates/partial/gallery.js.ep:211 themes/default/templates/partial/lutim.js.ep:176
msgid "Something bad happened"
msgstr ""
#. ($c->config('contact')
#: lib/Lutim/Controller.pm:760
#: lib/Lutim/Controller/Image.pm:760
msgid "Something went wrong when creating the zip file. Try again later or contact the administrator (%1)."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:44
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:52
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:49
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:55
#: themes/default/templates/partial/navbar.html.ep:66
msgid "Support the author with bitcoins"
msgstr ""
@@ -370,7 +390,7 @@ msgstr ""
msgid "The Lutim software is a <a href=\"http://en.wikipedia.org/wiki/Free_software\">free software</a>, which allows you to download and install it on you own server. Have a look at the <a href=\"https://www.gnu.org/licenses/agpl-3.0.html\">AGPL</a> to see what you can do."
msgstr ""
#: lib/Lutim/Controller.pm:346
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr ""
@@ -382,19 +402,19 @@ msgstr ""
msgid "The data has been successfully imported."
msgstr ""
#: lib/Lutim/Controller.pm:159 lib/Lutim/Controller.pm:227
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr ""
#. ($upload->filename)
#: lib/Lutim/Controller.pm:487
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr ""
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller.pm:310 lib/Lutim/Controller.pm:379 themes/default/templates/partial/lutim.js.ep:249
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr ""
@@ -403,16 +423,16 @@ msgid "The graph's datas are not updated in real-time."
msgstr ""
#. ($image->filename)
#: lib/Lutim/Controller.pm:229
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr ""
#. ($image->filename)
#: lib/Lutim/Controller.pm:238 lib/Lutim/Controller.pm:243
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr ""
#: lib/Lutim/Controller.pm:167
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr ""
@@ -429,7 +449,7 @@ msgid "There is XXXX image(s) in the gallery"
msgstr ""
#. ($c->config->{contact})
#: lib/Lutim/Controller.pm:484
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
@@ -454,15 +474,15 @@ msgid "Unable to copy to clipboard"
msgstr ""
#. ($short)
#: lib/Lutim/Controller.pm:107 lib/Lutim/Controller.pm:201 lib/Lutim/Controller.pm:272
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr ""
#: lib/Lutim/Controller.pm:573 lib/Lutim/Controller.pm:618 lib/Lutim/Controller.pm:657 lib/Lutim/Controller.pm:700 lib/Lutim/Controller.pm:712 lib/Lutim/Controller.pm:723 lib/Lutim/Controller.pm:750 lib/Lutim/Plugin/Helpers.pm:88
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr ""
#: lib/Lutim/Controller.pm:144
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr ""
@@ -519,6 +539,14 @@ msgstr ""
msgid "You can, optionally, request that the image(s) posted on Lutim to be deleted at first view (or download) or after the delay selected from those proposed."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr ""
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr ""
@@ -535,7 +563,7 @@ msgstr ""
msgid "core developer"
msgstr ""
#: lib/Lutim.pm:219 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 themes/default/templates/index.html.ep:3 themes/default/templates/myfiles.html.ep:3 themes/default/templates/partial/raw.js.ep:21 themes/default/templates/partial/raw.js.ep:4 themes/default/templates/raw.html.ep:6
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 themes/default/templates/index.html.ep:3 themes/default/templates/myfiles.html.ep:3 themes/default/templates/partial/raw.js.ep:21 themes/default/templates/partial/raw.js.ep:4 themes/default/templates/raw.html.ep:6
msgid "no time limit"
msgstr ""
@@ -51,7 +51,7 @@
.pswp__button,
.pswp__button--arrow--left:before,
.pswp__button--arrow--right:before {
background: url(default-skin.png) 0 0 no-repeat;
background: url(default-skin/default-skin.png) 0 0 no-repeat;
background-size: 264px 88px;
width: 44px;
height: 44px; }
File diff suppressed because one or more lines are too long
+18
View File
@@ -0,0 +1,18 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
% title 'Lutim login';
% if (defined stash('msg')) {
<%= stash('msg') %>
% }
<form method="post" action="<%= url_for('login') %>" class="form-inline">
<div class="form-group">
<label for="login"><%= l('Login') %></label>
<input id="login" type="text" class="form-control" name="login">
</div>
<div class="form-group">
<label for="password"><%= l('Password') %></label>
<input id="password" type="password" class="form-control" name="password">
</div>
<button class="btn btn-default" type="submit" name="action">
<%= l('Signin') %>
</button>
</form>
+6
View File
@@ -0,0 +1,6 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
% title 'Lutim logout';
<h1 class="h4"><%= l('You have been successfully logged out.') %></h1>
<p>
<a href="<%= url_for('login') %>" class="btn btn-default"><%= l('Signin') %></a>
</p
@@ -27,6 +27,17 @@
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
% if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) {
% if ($c->is_user_authenticated) {
<li>
<a href="<%= url_for('logout') %>"><%= l('Logout') %></a>
</li>
% } else {
<li>
<a href="<%= url_for('login') %>"><%= l('Signin') %></a>
</li>
% }
% }
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
<span class="icon-language" aria-hidden="true" title="<%= l('Language') %>"></span><span class="caret"></span>