Add optionnal LDAP authentication for uploading files

This commit is contained in:
Luc Didry 2016-05-20 23:12:44 +02:00 committed by Luc Didry
parent 261d9b4361
commit ac8d764b06
11 changed files with 926 additions and 195 deletions

View File

@ -3,6 +3,7 @@ requires "ORLite";
requires "Mojolicious::Plugin::DebugDumperHelper";
requires 'Mojolicious::Plugin::I18N';
requires 'Mojolicious::Plugin::Mail';
requires 'Mojolicious::Plugin::Authentication';
requires 'EV';
requires 'Filesys::DiskUsage';
requires 'Switch';
@ -13,3 +14,4 @@ requires 'Number::Bytes::Human';
requires 'Filesys::DfPortable';
requires 'Switch';
requires 'Data::Entropy';
requires 'Net::LDAP';

View File

@ -1,5 +1,26 @@
# carton snapshot format: version 1.0
DISTRIBUTIONS
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
CPAN-Meta-2.150005
pathname: D/DA/DAGOLDEN/CPAN-Meta-2.150005.tar.gz
provides:
@ -29,6 +50,14 @@ DISTRIBUTIONS
Canary::Stability 2006
requirements:
ExtUtils::MakeMaker 0
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-Rijndael-1.13
pathname: L/LE/LEONT/Crypt-Rijndael-1.13.tar.gz
provides:
@ -193,10 +222,21 @@ DISTRIBUTIONS
perl 5.006
strict 0
warnings 0
EV-4.21
pathname: M/ML/MLEHMANN/EV-4.21.tar.gz
Digest-HMAC-1.03
pathname: G/GA/GAAS/Digest-HMAC-1.03.tar.gz
provides:
EV 4.21
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
EV-4.22
pathname: M/ML/MLEHMANN/EV-4.22.tar.gz
provides:
EV 4.22
EV::MakeMaker undef
requirements:
Canary::Stability 0
@ -212,16 +252,38 @@ DISTRIBUTIONS
Time::Local 0
strict 0
warnings 0
Email-Valid-1.196
pathname: R/RJ/RJBS/Email-Valid-1.196.tar.gz
Email-Valid-1.200
pathname: R/RJ/RJBS/Email-Valid-1.200.tar.gz
provides:
Email::Valid 1.196
Email::Valid 1.200
requirements:
ExtUtils::MakeMaker 0
Mail::Address 0
Scalar::Util 0
Test::More 0
perl 5.006
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
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-Remove-1.52
pathname: A/AD/ADAMK/File-Remove-1.52.tar.gz
provides:
@ -249,6 +311,62 @@ DISTRIBUTIONS
File::Temp 0
Test::More 0
Test::Warn 0
HTML-Parser-3.72
pathname: G/GA/GAAS/HTML-Parser-3.72.tar.gz
provides:
HTML::Entities 3.69
HTML::Filter 3.72
HTML::HeadParser 3.71
HTML::LinkExtor 3.69
HTML::Parser 3.72
HTML::PullParser 3.57
HTML::TokeParser 3.69
requirements:
ExtUtils::MakeMaker 0
HTML::Tagset 3
XSLoader 0
perl 5.008
HTML-Tagset-3.20
pathname: P/PE/PETDANCE/HTML-Tagset-3.20.tar.gz
provides:
HTML::Tagset 3.20
requirements:
ExtUtils::MakeMaker 0
HTTP-Cookies-6.01
pathname: G/GA/GAAS/HTTP-Cookies-6.01.tar.gz
provides:
HTTP::Cookies 6.01
HTTP::Cookies::Microsoft 6.00
HTTP::Cookies::Netscape 6.00
requirements:
ExtUtils::MakeMaker 0
HTTP::Date 6
HTTP::Headers::Util 6
Time::Local 0
perl 5.008001
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:
@ -260,6 +378,80 @@ DISTRIBUTIONS
perl 5.005
strict 0
warnings 0
HTTP-Message-6.11
pathname: E/ET/ETHER/HTTP-Message-6.11.tar.gz
provides:
HTTP::Config 6.11
HTTP::Headers 6.11
HTTP::Headers::Auth 6.11
HTTP::Headers::ETag 6.11
HTTP::Headers::Util 6.11
HTTP::Message 6.11
HTTP::Request 6.11
HTTP::Request::Common 6.11
HTTP::Response 6.11
HTTP::Status 6.11
requirements:
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
URI 1.10
perl 5.008001
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
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-IP-0.37
pathname: P/PE/PEVANS/IO-Socket-IP-0.37.tar.gz
provides:
IO::Socket::IP 0.37
requirements:
IO::Socket 0
Socket 1.97
Test::More 0.88
IO-Socket-SSL-2.027
pathname: S/SU/SULLR/IO-Socket-SSL-2.027.tar.gz
provides:
IO::Socket::SSL 2.027
IO::Socket::SSL::Intercept 2.014
IO::Socket::SSL::OCSP_Cache 2.027
IO::Socket::SSL::OCSP_Resolver 2.027
IO::Socket::SSL::PublicSuffix undef
IO::Socket::SSL::SSL_Context 2.027
IO::Socket::SSL::SSL_HANDLE 2.027
IO::Socket::SSL::Session_Cache 2.027
IO::Socket::SSL::Utils 2.014
requirements:
ExtUtils::MakeMaker 0
Net::SSLeay 1.46
Scalar::Util 0
IPC-Run3-0.048
pathname: R/RJ/RJBS/IPC-Run3-0.048.tar.gz
provides:
@ -268,6 +460,22 @@ DISTRIBUTIONS
ExtUtils::MakeMaker 0
Test::More 0.31
Time::HiRes 0
JSON-2.90
pathname: M/MA/MAKAMAKA/JSON-2.90.tar.gz
provides:
JSON 2.90
JSON::Backend::PP 2.90
JSON::Boolean 2.90
requirements:
ExtUtils::MakeMaker 0
Test::More 0
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
Locale-Maketext-Lexicon-1.00
pathname: D/DR/DRTECH/Locale-Maketext-Lexicon-1.00.tar.gz
provides:
@ -427,8 +635,8 @@ DISTRIBUTIONS
Text::ParseWords 0
perl 5.008000
version 0.87
Mojolicious-6.22
pathname: S/SR/SRI/Mojolicious-6.22.tar.gz
Mojolicious-6.62
pathname: S/SR/SRI/Mojolicious-6.62.tar.gz
provides:
Mojo undef
Mojo::Asset undef
@ -490,7 +698,8 @@ DISTRIBUTIONS
Mojo::UserAgent::Server undef
Mojo::UserAgent::Transactor undef
Mojo::Util undef
Mojolicious 6.22
Mojo::WebSocket undef
Mojolicious 6.62
Mojolicious::Command undef
Mojolicious::Command::cgi undef
Mojolicious::Command::cpanify undef
@ -538,10 +747,19 @@ DISTRIBUTIONS
ojo undef
requirements:
ExtUtils::MakeMaker 0
IO::Socket::IP 0.26
IO::Socket::IP 0.37
JSON::PP 2.27103
Pod::Simple 3.09
Time::Local 1.2
Mojolicious-Plugin-Authentication-1.29
pathname: M/MA/MADCAT/Mojolicious-Plugin-Authentication-1.29.tar.gz
provides:
Mojolicious::Plugin::Authentication 1.29
requirements:
ExtUtils::MakeMaker 0
Mojo::Base 0
strict 0
warnings 0
Mojolicious-Plugin-DebugDumperHelper-0.02
pathname: L/LD/LDIDRY/Mojolicious-Plugin-DebugDumperHelper-0.02.tar.gz
provides:
@ -570,10 +788,35 @@ DISTRIBUTIONS
Mojolicious 5
Test::More 0
perl 5.001001
Number-Bytes-Human-0.09
pathname: D/DA/DAGOBERT/Number-Bytes-Human-0.09.tar.gz
Net-HTTP-6.09
pathname: E/ET/ETHER/Net-HTTP-6.09.tar.gz
provides:
Number::Bytes::Human 0.09
Net::HTTP 6.09
Net::HTTP::Methods 6.09
Net::HTTP::NB 6.09
Net::HTTPS 6.09
requirements:
Compress::Raw::Zlib 0
ExtUtils::MakeMaker 0
IO::Select 0
IO::Socket::INET 0
IO::Uncompress::Gunzip 0
URI 0
perl 5.006002
Net-SSLeay-1.74
pathname: M/MI/MIKEM/Net-SSLeay-1.74.tar.gz
provides:
Net::SSLeay 1.74
Net::SSLeay::Handle 0.61
requirements:
ExtUtils::MakeMaker 6.36
MIME::Base64 0
Test::More 0.60_01
perl 5.005
Number-Bytes-Human-0.10
pathname: D/DA/DAGOBERT/Number-Bytes-Human-0.10.tar.gz
provides:
Number::Bytes::Human 0.10
requirements:
Carp 0
ExtUtils::MakeMaker 0
@ -676,6 +919,13 @@ DISTRIBUTIONS
Test::Builder::Tester 1.02
Test::More 0
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
TimeDate-2.30
pathname: G/GB/GBARR/TimeDate-2.30.tar.gz
provides:
@ -719,9 +969,233 @@ DISTRIBUTIONS
Time::Zone 2.24
requirements:
ExtUtils::MakeMaker 0
URI-1.71
pathname: E/ET/ETHER/URI-1.71.tar.gz
provides:
URI 1.71
URI::Escape 3.31
URI::Heuristic 4.20
URI::IRI 1.71
URI::QueryParam 1.71
URI::Split 1.71
URI::URL 5.04
URI::WithBase 2.20
URI::_foreign 1.71
URI::_generic 1.71
URI::_idna 1.71
URI::_ldap 1.71
URI::_login 1.71
URI::_punycode 1.71
URI::_query 1.71
URI::_segment 1.71
URI::_server 1.71
URI::_userpass 1.71
URI::data 1.71
URI::file 4.21
URI::file::Base 1.71
URI::file::FAT 1.71
URI::file::Mac 1.71
URI::file::OS2 1.71
URI::file::QNX 1.71
URI::file::Unix 1.71
URI::file::Win32 1.71
URI::ftp 1.71
URI::gopher 1.71
URI::http 1.71
URI::https 1.71
URI::ldap 1.71
URI::ldapi 1.71
URI::ldaps 1.71
URI::mailto 1.71
URI::mms 1.71
URI::news 1.71
URI::nntp 1.71
URI::pop 1.71
URI::rlogin 1.71
URI::rsync 1.71
URI::rtsp 1.71
URI::rtspu 1.71
URI::sftp 1.71
URI::sip 1.71
URI::sips 1.71
URI::snews 1.71
URI::ssh 1.71
URI::telnet 1.71
URI::tn3270 1.71
URI::urn 1.71
URI::urn::isbn undef
URI::urn::oid 1.71
requirements:
Exporter 5.57
ExtUtils::MakeMaker 0
MIME::Base64 2
Scalar::Util 0
parent 0
perl 5.008001
utf8 0
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
XML-SAX-Base-1.08
pathname: G/GR/GRANTM/XML-SAX-Base-1.08.tar.gz
provides:
XML::SAX::Base 1.08
XML::SAX::Base::NoHandler 1.08
XML::SAX::Exception 1.08
requirements:
ExtUtils::MakeMaker 6.31
Test::More 0.88
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.15
pathname: E/ET/ETHER/libwww-perl-6.15.tar.gz
provides:
LWP 6.15
LWP::Authen::Basic undef
LWP::Authen::Digest undef
LWP::Authen::Ntlm 6.15
LWP::ConnCache 6.15
LWP::Debug undef
LWP::DebugFile undef
LWP::MemberMixin undef
LWP::Protocol 6.15
LWP::Protocol::GHTTP undef
LWP::Protocol::MyFTP undef
LWP::Protocol::cpan undef
LWP::Protocol::data undef
LWP::Protocol::file undef
LWP::Protocol::ftp undef
LWP::Protocol::gopher undef
LWP::Protocol::http undef
LWP::Protocol::http::Socket undef
LWP::Protocol::http::SocketMethods undef
LWP::Protocol::loopback undef
LWP::Protocol::mailto undef
LWP::Protocol::nntp undef
LWP::Protocol::nogo undef
LWP::RobotUA 6.15
LWP::Simple 6.15
LWP::UserAgent 6.15
requirements:
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
IO::Select 0
IO::Socket 0
LWP::MediaTypes 6
MIME::Base64 2.1
Net::FTP 2.58
Net::HTTP 6.07
URI 1.10
URI::Escape 0
WWW::RobotRules 6
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
XML::SAX::Base 0
perl 5.008001

View File

@ -3,6 +3,7 @@ package Lufi;
use Mojo::Base 'Mojolicious';
use LufiDB;
use Data::Entropy qw(entropy_source);
use Net::LDAP;
$ENV{MOJO_MAX_WEBSOCKET_SIZE} = 100485760; # 10 * 1024 * 1024 = 10MiB
@ -12,19 +13,20 @@ sub startup {
my $config = $self->plugin('Config' => {
default => {
provisioning => 100,
provis_step => 5,
length => 10,
token_length => 32,
secrets => ['hfudsifdsih'],
default_delay => 0,
max_delay => 0,
mail => {
provisioning => 100,
provis_step => 5,
length => 10,
token_length => 32,
secrets => ['hfudsifdsih'],
default_delay => 0,
max_delay => 0,
mail => {
how => 'sendmail'
},
mail_sender => 'no-reply@lufi.io',
theme => 'default',
upload_dir => 'files',
mail_sender => 'no-reply@lufi.io',
theme => 'default',
upload_dir => 'files',
session_duration => 3600,
}
});
@ -59,6 +61,55 @@ sub startup {
# Debug
$self->plugin('DebugDumperHelper');
# Authentication (if configured)
$self->plugin('authentication' =>
{
autoload_user => 1,
session_key => 'Dolomon',
load_user => sub {
my ($c, $username) = @_;
return $username;
},
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->error($mesg->error);
return undef;
}
return $username;
}
}
);
if (defined($self->config('ldap'))) {
$self->app->sessions->default_expiration($self->config('session_duration'));
}
# Secrets
$self->secrets($self->config('secrets'));
# Helpers
@ -183,9 +234,47 @@ sub startup {
# Page for files uploading
$r->get('/' => sub {
shift->render(template => 'index');
my $c = shift;
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
$c->render(template => 'index');
} else {
$c->redirect_to('login');
}
})->name('index');
if (defined $self->config('ldap')) {
# Login page
$r->get('/login' => sub {
my $c = shift;
if ($c->is_user_authenticated) {
$c->redirect_to('index');
} else {
$c->render(template => 'login');
}
});
# Authentication
$r->post('/login' => sub {
my $c = shift;
my $login = $c->param('login');
my $pwd = $c->param('password');
if($c->authenticate($login, $pwd)) {
$c->redirect_to('index');
} else {
$c->stash(msg => $c->l('Please, check your credentials: unable to authenticate.'));
$c->render(template => 'login');
}
});
# Logout page
$r->get('/logout' => sub {
my $c = shift;
if ($c->is_user_authenticated) {
$c->logout;
}
$c->render(template => 'logout');
})->name('logout');
}
# About page
$r->get('/about' => sub {
shift->render(template => 'about');
@ -196,9 +285,14 @@ sub startup {
to('Files#r')->
name('render');
# List of files (use localstorage, so the server know nothing about files
# List of files (use localstorage, so the server know nothing about files)
$r->get('/files' => sub {
shift->render(template => 'files');
my $c = shift;
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
$c->render(template => 'files');
} else {
$c->redirect_to('login');
}
})->name('files');
# Get counter informations about a file

View File

@ -13,122 +13,124 @@ use Filesys::DfPortable;
sub upload {
my $c = shift;
$c->inactivity_timeout(30000000);
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
$c->inactivity_timeout(30000000);
$c->app->log->debug('Client connected');
$c->app->log->debug('Client connected');
$c->on(
message => sub {
my ($ws, $text) = @_;
$c->on(
message => sub {
my ($ws, $text) = @_;
my $begin = time;
my $begin = time;
my ($json) = split('XXMOJOXX', $text, 2);
$json = encode 'UTF-8', $json;
$json = decode_json $json;
my ($json) = split('XXMOJOXX', $text, 2);
$json = encode 'UTF-8', $json;
$json = decode_json $json;
$c->app->log->debug('Got message');
$c->app->log->debug('Got message');
my $stop = 0;
my $stop = 0;
# Check if stop_upload file is present
if ($c->stop_upload) {
$stop = 1;
$c->send(sprintf('{"success": false, "msg":"'.$c->l('Sorry, uploading is disabled.').'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
}
# Check against max_size
elsif (defined $c->config('max_file_size')) {
if ($json->{size} > $c->config('max_file_size')) {
# Check if stop_upload file is present
if ($c->stop_upload) {
$stop = 1;
$c->send(sprintf('{"success": false, "msg":"'.$c->l('Your file is too big: %1 (maximum size allowed: %2)', format_bytes($json->{size}), format_bytes($c->config('max_file_size'))).'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
$c->send(sprintf('{"success": false, "msg":"'.$c->l('Sorry, uploading is disabled.').'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
}
# Check against max_size
elsif (defined $c->config('max_file_size')) {
if ($json->{size} > $c->config('max_file_size')) {
$stop = 1;
$c->send(sprintf('{"success": false, "msg":"'.$c->l('Your file is too big: %1 (maximum size allowed: %2)', format_bytes($json->{size}), format_bytes($c->config('max_file_size'))).'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
}
}
# Check that we have enough space (multiplying by 2 since it's encrypted, it takes more place that the original file)
elsif ($json->{part} == 0 && ($json->{size} * 2) >= dfportable($c->config('upload_dir'))->{bavail}) {
$stop = 1;
$c->send(sprintf('{"success": false, "msg":"'.$c->l('No enough space available on the server for this file (size: %1).', format_bytes($json->{size})).'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
}
}
# Check that we have enough space (multiplying by 2 since it's encrypted, it takes more place that the original file)
elsif ($json->{part} == 0 && ($json->{size} * 2) >= dfportable($c->config('upload_dir'))->{bavail}) {
$stop = 1;
$c->send(sprintf('{"success": false, "msg":"'.$c->l('No enough space available on the server for this file (size: %1).', format_bytes($json->{size})).'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
}
unless ($stop) {
my $f;
if (defined($json->{id})) {
my @records = LufiDB::Files->select('WHERE short = ?', $json->{id});
$f = Lufi::File->new(record => $records[0]) if scalar @records;
} else {
my $delay;
unless ($stop) {
my $f;
if (defined($json->{id})) {
my @records = LufiDB::Files->select('WHERE short = ?', $json->{id});
$f = Lufi::File->new(record => $records[0]) if scalar @records;
} else {
my $delay;
if (defined $c->config('delay_for_size')) {
# Choose delay according to config
my $delays = $c->config('delay_for_size');
my @keys = sort {$b <=> $a} keys %{$delays};
for my $key (@keys) {
if ($json->{size} >= $key) {
$delay = ($json->{delay} < $delays->{$key}) ? $json->{delay} : $delays->{$key};
last;
if (defined $c->config('delay_for_size')) {
# Choose delay according to config
my $delays = $c->config('delay_for_size');
my @keys = sort {$b <=> $a} keys %{$delays};
for my $key (@keys) {
if ($json->{size} >= $key) {
$delay = ($json->{delay} < $delays->{$key}) ? $json->{delay} : $delays->{$key};
last;
}
}
}
}
# If the file size is lower than the lowest configured size or if there is no delay_for_size setting, we choose the configured max delay
unless (defined $delay) {
$delay = ($json->{delay} <= $c->max_delay || $c->max_delay == 0) ? $json->{delay} : $c->max_delay;
}
$f = Lufi::File->new(
record => $c->get_empty,
created_by => $c->ip,
delete_at_first_view => ($json->{del_at_first_view}) ? 1 : 0,
delete_at_day => $delay,
mediatype => $json->{type},
filename => $json->{name},
filesize => $json->{size},
nbslices => $json->{total},
mod_token => $c->shortener($c->config('token_length'))
);
$f->write;
}
# This check is just in case we didn't succeed to find a corresponding record
# It normally can't happen
if (defined $f) {
# If we already have a part, it's a resend because the websocket has been broken
# In this case, we don't need to rewrite the file
unless ($f->slices->grep(sub { $_->j == $json->{part} })->size) {
# Create directory
my $dir = catdir($c->config('upload_dir'), $f->short);
mkdir($dir, 0700) unless (-d $dir);
# Create slice file
my $file = catfile($dir, $json->{part}.'.part');
my $s = Lufi::Slice->new(
short => $f->short,
j => $json->{part},
path => $file
);
spurt $text, $file;
push @{$f->slices}, $s;
$s->write;
if (($json->{part} + 1) == $json->{total}) {
$f->complete(1);
$f->created_at(time);
$f->write;
# If the file size is lower than the lowest configured size or if there is no delay_for_size setting, we choose the configured max delay
unless (defined $delay) {
$delay = ($json->{delay} <= $c->max_delay || $c->max_delay == 0) ? $json->{delay} : $c->max_delay;
}
$f = Lufi::File->new(
record => $c->get_empty,
created_by => $c->ip,
delete_at_first_view => ($json->{del_at_first_view}) ? 1 : 0,
delete_at_day => $delay,
mediatype => $json->{type},
filename => $json->{name},
filesize => $json->{size},
nbslices => $json->{total},
mod_token => $c->shortener($c->config('token_length'))
);
$f->write;
}
$c->provisioning;
# This check is just in case we didn't succeed to find a corresponding record
# It normally can't happen
if (defined $f) {
# If we already have a part, it's a resend because the websocket has been broken
# In this case, we don't need to rewrite the file
unless ($f->slices->grep(sub { $_->j == $json->{part} })->size) {
# Create directory
my $dir = catdir($c->config('upload_dir'), $f->short);
mkdir($dir, 0700) unless (-d $dir);
$ws->send(sprintf('{"success": true, "i": %d, "j": %d, "parts": %d, "short": "%s", "name": "%s", "size": %d, "del_at_first_view": %s, "created_at": %d, "delay": %d, "token": "%s", "sent_delay": %d, "duration": %d}', $json->{i}, $json->{part}, $json->{total}, $f->short, $f->filename, $f->filesize, (($f->delete_at_first_view) ? 'true' : 'false'), $f->created_at, $f->delete_at_day, $f->mod_token, $json->{delay}, time - $begin));
} else {
$ws->send(sprintf('{"success": false, "msg":"'.$c->l('The server was unable to find the file record to add your file part to. Please, contact the administrator.').'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
# Create slice file
my $file = catfile($dir, $json->{part}.'.part');
my $s = Lufi::Slice->new(
short => $f->short,
j => $json->{part},
path => $file
);
spurt $text, $file;
push @{$f->slices}, $s;
$s->write;
if (($json->{part} + 1) == $json->{total}) {
$f->complete(1);
$f->created_at(time);
$f->write;
}
}
$c->provisioning;
$ws->send(sprintf('{"success": true, "i": %d, "j": %d, "parts": %d, "short": "%s", "name": "%s", "size": %d, "del_at_first_view": %s, "created_at": %d, "delay": %d, "token": "%s", "sent_delay": %d, "duration": %d}', $json->{i}, $json->{part}, $json->{total}, $f->short, $f->filename, $f->filesize, (($f->delete_at_first_view) ? 'true' : 'false'), $f->created_at, $f->delete_at_day, $f->mod_token, $json->{delay}, time - $begin));
} else {
$ws->send(sprintf('{"success": false, "msg":"'.$c->l('The server was unable to find the file record to add your file part to. Please, contact the administrator.').'", "sent_delay": %d, "i": %d}', $json->{delay}, $json->{i}));
}
}
}
}
);
$c->on(
finish => sub {
$c->app->log->debug('Client disconnected');
}
);
);
$c->on(
finish => sub {
$c->app->log->debug('Client disconnected');
}
);
}
}
sub download {
@ -233,24 +235,35 @@ sub get_counter {
my $short = $c->param('short');
my $token = $c->param('token');
my @records = LufiDB::Files->select('WHERE short = ?', $short);
if (scalar(@records)) {
if ($records[0]->mod_token eq $token) {
return $c->render(
json => {
success => true,
short => $short,
counter => $records[0]->counter,
deleted => ($records[0]->deleted) ? true : false
}
);
if (!defined($c->config('ldap')) || $c->is_user_authenticated) {
my @records = LufiDB::Files->select('WHERE short = ?', $short);
if (scalar(@records)) {
if ($records[0]->mod_token eq $token) {
return $c->render(
json => {
success => true,
short => $short,
counter => $records[0]->counter,
deleted => ($records[0]->deleted) ? true : false
}
);
} else {
return $c->render(
json => {
success => false,
missing => false,
short => $short,
msg => $c->l('Unable to get counter for %1. The token is invalid.', $short)
}
);
}
} else {
return $c->render(
json => {
success => false,
missing => false,
missing => true,
short => $short,
msg => $c->l('Unable to get counter for %1. The token is invalid.', $short)
msg => $c->l('Unable to get counter for %1. The file does not exists. It will be removed from your localStorage.', $short)
}
);
}
@ -258,9 +271,9 @@ sub get_counter {
return $c->render(
json => {
success => false,
missing => true,
missing => false,
short => $short,
msg => $c->l('Unable to get counter for %1. The file does not exists. It will be removed from your localStorage.', $short)
msg => $c->l('Unable to get counter for %1. You are not authenticated.', $short)
}
);
}
@ -271,31 +284,48 @@ sub delete {
my $short = $c->param('short');
my $token = $c->param('token');
my @records = LufiDB::Files->select('WHERE short = ? AND mod_token = ?', ($short, $token));
if (scalar(@records)) {
my $f = Lufi::File->new(record => $records[0]);
my $msg;
if ($f->deleted) {
$msg = $c->l('The file has already been deleted');
} else {
$f->delete;
$msg = $c->l('File deleted');
}
return $c->respond_to(
json => {
success => true,
msg => $msg
},
any => sub {
$c->render(
template => 'msg',
f => $f,
msg => $msg
);
if (!defined($c->config('ldap')) || $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]);
my $msg;
if ($f->deleted) {
$msg = $c->l('The file has already been deleted');
} else {
$f->delete;
$msg = $c->l('File deleted');
}
);
return $c->respond_to(
json => {
success => true,
msg => $msg
},
any => sub {
$c->render(
template => 'msg',
f => $f,
msg => $msg
);
}
);
} else {
my $msg = $c->l('Could not find the file. Are you sure of the URL and the token?');
return $c->respond_to(
json => {
success => false,
msg => $msg
},
any => sub {
$c->render(
template => 'msg',
f => undef,
msg => $msg
);
}
);
}
} else {
my $msg = $c->l('Could not find the file. Are you sure of the URL and the token?');
my $msg = $c->l('Could not delete the file. You are not authenticated.');
return $c->respond_to(
json => {
success => false,

View File

@ -115,6 +115,23 @@
# optional, default is 'files'
#upload_dir => 'files',
# set `ldap` if you want that only authenticated users can upload files
# please note that everybody can still download files
# optional, no default
#ldap => {
# uri => 'ldaps://ldap.example.org',
# user_tree => 'ou=users,dc=example,dc=org',
# bind_dn => ',ou=users,dc=example,dc=org',
# bind_user => 'uid=ldap_user',
# bind_pwd => 'secr3t',
# user_filter => '!(uid=ldap_user)'
#},
# if you setted ldap above, the session will last `session_duration` seconds before
# the user needs to reauthenticate
# optional, default is 3600
#session_duration => 3600,
#########################
# Lufi cron jobs settings
#########################
@ -138,5 +155,5 @@
# images which are not viewed since delete_no_longer_viewed_files days will be deleted by the cron cleanfiles task
# if delete_no_longer_viewed_files is not set, the no longer viewed files will NOT be deleted
# optional, no default
#delete_no_longer_viewed_files => 90
#delete_no_longer_viewed_files => 90,
};

View File

@ -37,7 +37,7 @@ msgstr ""
msgid "A thank you with a photo of kitten on <a href=\"https://framasphere.org/people/b13eb6b0beac0131e7e32a0000053625\" class=\"classic\">Diaspora*</a> or <a href=\"https://twitter.com/framasky\" class=\"classic\">Twitter</a> is cool too ;-)"
msgstr ""
#: themes/default/templates/layouts/default.html.ep:36 themes/default/templates/layouts/default.html.ep:41
#: themes/default/templates/layouts/default.html.ep:40 themes/default/templates/layouts/default.html.ep:52
msgid "About"
msgstr ""
@ -74,11 +74,15 @@ msgstr ""
msgid "Copy to clipboard"
msgstr ""
#: lib/Lufi/Controller/Files.pm:298
#: lib/Lufi/Controller/Files.pm:328
msgid "Could not delete the file. You are not authenticated."
msgstr ""
#: lib/Lufi/Controller/Files.pm:312
msgid "Could not find the file. Are you sure of the URL and the token?"
msgstr ""
#: lib/Lufi/Controller/Files.pm:226
#: lib/Lufi/Controller/Files.pm:228
msgid "Could not find the file. Are you sure of the URL?"
msgstr ""
@ -130,15 +134,15 @@ msgstr ""
msgid "Encrypting part XX1 of XX2"
msgstr ""
#: lib/Lufi/Controller/Files.pm:162
#: lib/Lufi/Controller/Files.pm:164
msgid "Error: the file existed but was deleted."
msgstr ""
#: lib/Lufi/Controller/Files.pm:203
#: lib/Lufi/Controller/Files.pm:205
msgid "Error: the file has not been sent entirely."
msgstr ""
#: lib/Lufi/Controller/Files.pm:208
#: lib/Lufi/Controller/Files.pm:210
msgid "Error: unable to find the file. Are you sure of your URL?"
msgstr ""
@ -154,7 +158,7 @@ msgstr ""
msgid "Export localStorage data"
msgstr ""
#: lib/Lufi/Controller/Files.pm:282
#: lib/Lufi/Controller/Files.pm:296
msgid "File deleted"
msgstr ""
@ -222,16 +226,24 @@ msgstr ""
msgid "Javascript is disabled. You won't be able to use Lufi."
msgstr ""
#: themes/default/templates/login.html.ep:15
msgid "Login"
msgstr ""
#: themes/default/templates/layouts/default.html.ep:42 themes/default/templates/layouts/default.html.ep:54
msgid "Logout"
msgstr ""
#: themes/default/templates/about.html.ep:4
msgid "Lufi is a free (as in free speech) file hosting software."
msgstr ""
#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:35 themes/default/templates/layouts/default.html.ep:40
#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:36 themes/default/templates/layouts/default.html.ep:48
msgid "My files"
msgstr ""
#. (format_bytes($json->{size})
#: lib/Lufi/Controller/Files.pm:49
#: lib/Lufi/Controller/Files.pm:50
msgid "No enough space available on the server for this file (size: %1)."
msgstr ""
@ -243,6 +255,10 @@ msgstr ""
msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list."
msgstr ""
#: themes/default/templates/login.html.ep:21
msgid "Password"
msgstr ""
#. (config('contact')
#: themes/default/templates/about.html.ep:13
msgid "Please contact the administrator: %1"
@ -285,11 +301,15 @@ msgstr ""
msgid "Share your files in total privacy on %1"
msgstr ""
#: themes/default/templates/layouts/default.html.ep:38 themes/default/templates/layouts/default.html.ep:50 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8
msgid "Signin"
msgstr ""
#: themes/default/templates/index.html.ep:30
msgid "Sorry, the uploading is currently disabled. Please try again later."
msgstr ""
#: lib/Lufi/Controller/Files.pm:37
#: lib/Lufi/Controller/Files.pm:38
msgid "Sorry, uploading is disabled."
msgstr ""
@ -309,7 +329,7 @@ msgstr ""
msgid "The email subject can't be empty."
msgstr ""
#: lib/Lufi/Controller/Files.pm:279
#: lib/Lufi/Controller/Files.pm:293
msgid "The file has already been deleted"
msgstr ""
@ -335,7 +355,7 @@ msgstr ""
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://flattr.com/submit/auto?user_id=_SKy_&amp;url=%1&amp;title=Lufi&amp;category=software\" class=\"classic\">Flattr</a> or with <a href=\"bitcoin:1CJYU2uGmPKhvithCGntyniTTe2hofpPX3?label=Lufi\" class=\"classic\">Bitcoin</a>."
msgstr ""
#: lib/Lufi/Controller/Files.pm:122
#: lib/Lufi/Controller/Files.pm:123
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
msgstr ""
@ -348,16 +368,21 @@ msgid "Unable to copy the link(s) to your clipboard"
msgstr ""
#. ($short)
#: lib/Lufi/Controller/Files.pm:263
#: lib/Lufi/Controller/Files.pm:266
msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage."
msgstr ""
#. ($short)
#: lib/Lufi/Controller/Files.pm:253
#: lib/Lufi/Controller/Files.pm:256
msgid "Unable to get counter for %1. The token is invalid."
msgstr ""
#: themes/default/templates/layouts/default.html.ep:34 themes/default/templates/layouts/default.html.ep:39
#. ($short)
#: lib/Lufi/Controller/Files.pm:276
msgid "Unable to get counter for %1. You are not authenticated."
msgstr ""
#: themes/default/templates/layouts/default.html.ep:35 themes/default/templates/layouts/default.html.ep:47
msgid "Upload files"
msgstr ""
@ -401,12 +426,16 @@ msgstr ""
msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?"
msgstr ""
#: themes/default/templates/logout.html.ep:5
msgid "You have been successfully logged out."
msgstr ""
#: lib/Lufi/Controller/Mail.pm:30
msgid "You must give email addresses."
msgstr ""
#. (format_bytes($json->{size})
#: lib/Lufi/Controller/Files.pm:43
#: lib/Lufi/Controller/Files.pm:44
msgid "Your file is too big: %1 (maximum size allowed: %2)"
msgstr ""

View File

@ -39,7 +39,7 @@ msgstr " :"
msgid "A thank you with a photo of kitten on <a href=\"https://framasphere.org/people/b13eb6b0beac0131e7e32a0000053625\" class=\"classic\">Diaspora*</a> or <a href=\"https://twitter.com/framasky\" class=\"classic\">Twitter</a> is cool too ;-)"
msgstr "Un merci avec une photo de chaton sur <a href=\"https://framasphere.org/people/b13eb6b0beac0131e7e32a0000053625\" class=\"classic\">Diaspora*</a> ou <a href=\"https://twitter.com/framasky\" class=\"classic\">Twitter</a> fait aussi laffaire ;-)"
#: themes/default/templates/layouts/default.html.ep:36 themes/default/templates/layouts/default.html.ep:41
#: themes/default/templates/layouts/default.html.ep:40 themes/default/templates/layouts/default.html.ep:52
msgid "About"
msgstr "À propos"
@ -76,11 +76,15 @@ msgstr "Copier tous les liens dans le presse-papier"
msgid "Copy to clipboard"
msgstr "Copier dans le presse-papier"
#: lib/Lufi/Controller/Files.pm:298
#: lib/Lufi/Controller/Files.pm:328
msgid "Could not delete the file. You are not authenticated."
msgstr "Impossible de supprimer le fichier. Vous n'êtes pas connecté·e."
#: lib/Lufi/Controller/Files.pm:312
msgid "Could not find the file. Are you sure of the URL and the token?"
msgstr "Impossible de retrouver le fichier. Êtes-vous sûr(e) que lURL et le jeton sont les bons ?"
#: lib/Lufi/Controller/Files.pm:226
#: lib/Lufi/Controller/Files.pm:228
msgid "Could not find the file. Are you sure of the URL?"
msgstr "Impossible de retrouver le fichier. Êtes-vous sûr(e) que lURL est la bonne ?"
@ -132,15 +136,15 @@ msgstr "Mails"
msgid "Encrypting part XX1 of XX2"
msgstr "Chiffrement du fragment XX1 sur XX2"
#: lib/Lufi/Controller/Files.pm:162
#: lib/Lufi/Controller/Files.pm:164
msgid "Error: the file existed but was deleted."
msgstr "Erreur : le fichier existait mais a été supprimé"
#: lib/Lufi/Controller/Files.pm:203
#: lib/Lufi/Controller/Files.pm:205
msgid "Error: the file has not been sent entirely."
msgstr "Erreur : le fichier na pas été envoyé dans son intégralité"
#: lib/Lufi/Controller/Files.pm:208
#: lib/Lufi/Controller/Files.pm:210
msgid "Error: unable to find the file. Are you sure of your URL?"
msgstr "Erreur : impossible de retrouver le fichier. Êtes-vous sûr(e) de lURL ?"
@ -156,7 +160,7 @@ msgstr "Expire le"
msgid "Export localStorage data"
msgstr "Exporter les données localStorage"
#: lib/Lufi/Controller/Files.pm:282
#: lib/Lufi/Controller/Files.pm:296
msgid "File deleted"
msgstr "Fichier supprimé"
@ -224,16 +228,24 @@ msgstr "Il semble que la clé dans votre URL soit incorrecte. Veuillez vérifier
msgid "Javascript is disabled. You won't be able to use Lufi."
msgstr "Javascript est désactivé. Lufi ne fonctionnera pas."
#: themes/default/templates/login.html.ep:15
msgid "Login"
msgstr "Identifiant"
#: themes/default/templates/layouts/default.html.ep:42 themes/default/templates/layouts/default.html.ep:54
msgid "Logout"
msgstr "Déconnexion"
#: themes/default/templates/about.html.ep:4
msgid "Lufi is a free (as in free speech) file hosting software."
msgstr "Lufi est un logiciel libre dhébergement de fichiers."
#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:35 themes/default/templates/layouts/default.html.ep:40
#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:36 themes/default/templates/layouts/default.html.ep:48
msgid "My files"
msgstr "Mes fichiers"
#. (format_bytes($json->{size})
#: lib/Lufi/Controller/Files.pm:49
#: lib/Lufi/Controller/Files.pm:50
msgid "No enough space available on the server for this file (size: %1)."
msgstr "Espace disque insuffisant sur le serveur pour ce fichier (taille du fichier: %1)."
@ -245,6 +257,10 @@ msgstr "Pas de délai dexpiration"
msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list."
msgstr "Seuls les fichiers envoyés avec ce navigateur web sont listés ici. Les informations sont stockées en localStorage : si vous supprimez vos données localStorage, vous perdrez ces informations."
#: themes/default/templates/login.html.ep:21
msgid "Password"
msgstr "Mot de passe"
#. (config('contact')
#: themes/default/templates/about.html.ep:13
msgid "Please contact the administrator: %1"
@ -287,11 +303,15 @@ msgstr "Envoi du fragment XX1 sur XX2"
msgid "Share your files in total privacy on %1"
msgstr "Partagez vos fichiers en toute confidentialité sur %1"
#: themes/default/templates/layouts/default.html.ep:38 themes/default/templates/layouts/default.html.ep:50 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8
msgid "Signin"
msgstr "Connexion"
#: themes/default/templates/index.html.ep:30
msgid "Sorry, the uploading is currently disabled. Please try again later."
msgstr "Désolé, lenvoi de fichier est actuellement désactivé. Veuillez réessayer plus tard."
#: lib/Lufi/Controller/Files.pm:37
#: lib/Lufi/Controller/Files.pm:38
msgid "Sorry, uploading is disabled."
msgstr "Désolé, lenvoi de fichier est désactivé."
@ -311,7 +331,7 @@ msgstr "Le corps du mail ne peut être vide."
msgid "The email subject can't be empty."
msgstr "Le sujet du mail ne peut être vide."
#: lib/Lufi/Controller/Files.pm:279
#: lib/Lufi/Controller/Files.pm:293
msgid "The file has already been deleted"
msgstr "Le fichier a déjà été supprimé"
@ -337,7 +357,7 @@ msgstr "Le mail a été envoyé."
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://flattr.com/submit/auto?user_id=_SKy_&amp;url=%1&amp;title=Lufi&amp;category=software\" class=\"classic\">Flattr</a> or with <a href=\"bitcoin:1CJYU2uGmPKhvithCGntyniTTe2hofpPX3?label=Lufi\" class=\"classic\">Bitcoin</a>."
msgstr "Lauteur originel (et pour linstant, le seul) est <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. Si vous avez envie de le supporter, vous pouvez le faire via <a href=\"https://flattr.com/submit/auto?user_id=_SKy_&amp;url=%1&amp;title=Lufi&amp;category=software\" class=\"classic\">Flattr</a> ou en <a href=\"bitcoin:1CJYU2uGmPKhvithCGntyniTTe2hofpPX3?label=Lufi\" class=\"classic\">Bitcoin</a>."
#: lib/Lufi/Controller/Files.pm:122
#: lib/Lufi/Controller/Files.pm:123
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
msgstr "Le serveur a été incapable de retrouver lenregistrement du fichier auquel ajouter votre fragment de fichier. Veuillez contacter l'administrateur."
@ -350,16 +370,21 @@ msgid "Unable to copy the link(s) to your clipboard"
msgstr "Impossible de copier le(s) lien(s) dans votre presse-papier"
#. ($short)
#: lib/Lufi/Controller/Files.pm:263
#: lib/Lufi/Controller/Files.pm:266
msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage."
msgstr "Impossible de récupérer le compteur pour %1. Le fichier nexiste pas. Il va être supprimé de votre localStorage."
#. ($short)
#: lib/Lufi/Controller/Files.pm:253
#: lib/Lufi/Controller/Files.pm:256
msgid "Unable to get counter for %1. The token is invalid."
msgstr "Impossible de récupérer le compteur pour %1. Le jeton est invalide."
#: themes/default/templates/layouts/default.html.ep:34 themes/default/templates/layouts/default.html.ep:39
#. ($short)
#: lib/Lufi/Controller/Files.pm:276
msgid "Unable to get counter for %1. You are not authenticated."
msgstr "Impossible de récupérer le compteur pour %1. Vous n'êtes pas connecté·e."
#: themes/default/templates/layouts/default.html.ep:35 themes/default/templates/layouts/default.html.ep:47
msgid "Upload files"
msgstr "Envoyer des fichiers"
@ -403,12 +428,16 @@ msgstr "Vous essayez de quitter la page. Le téléchargement sera annulé. Êtes
msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?"
msgstr "Vous essayez de quitter la page. Lenvoi sera annulé. Êtes-vous sûr(e) ?"
#: themes/default/templates/logout.html.ep:5
msgid "You have been successfully logged out."
msgstr "Vous avez été déconnecté·e avec succès."
#: lib/Lufi/Controller/Mail.pm:30
msgid "You must give email addresses."
msgstr "Vous devez envoyer des adresses mail."
#. (format_bytes($json->{size})
#: lib/Lufi/Controller/Files.pm:43
#: lib/Lufi/Controller/Files.pm:44
msgid "Your file is too big: %1 (maximum size allowed: %2)"
msgstr "Votre fichier est trop volumineux : %1 (la taille maximum autorisée est %2)"

View File

@ -31,14 +31,28 @@
<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()) {
<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()) {
<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()) {
<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()) {
<li><a href="<%= url_for('/logout') %>"><%= l('Logout') %></a></li>
% }
</ul>
</div>
</nav>

View File

@ -0,0 +1,29 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
% if (defined stash('msg')) {
<div class="col s12">
<div class="card pink">
<div class="card-content white-text">
<strong><%= stash('msg') %></strong>
</div>
</div>
</div>
% }
<form class="row" method="post" action="<%= url_for('login') %>">
<div class="col s8 m8 offset-s2 offset-m2">
<div class="input-field">
<input id="login" type="text" class="validate" name="login">
<label for="login"><%= l('Login') %></label>
</div>
</div>
<div class="col s8 m8 offset-s2 offset-m2">
<div class="input-field">
<input id="password" type="password" class="validate" name="password">
<label for="password"><%= l('Password') %></label>
</div>
</div>
<div class="col s8 m8 offset-s2 offset-m2">
<button class="btn waves-effect waves-light" type="submit" name="action">
<%= l('Signin') %>
</button>
</div>
</form>

View File

@ -0,0 +1,11 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
<div class="col s12">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<strong><%= l('You have been successfully logged out.') %></strong>
</div>
<div class="card-action">
<a href="<%= url_for('login') %>"><%= l('Signin') %></a>
</div>
</div>
</div>

View File

@ -6,5 +6,7 @@ themes/default/templates/mail.html.ep
themes/default/templates/msg.html.ep
themes/default/templates/render.html.ep
themes/default/templates/about.html.ep
themes/default/templates/login.html.ep
themes/default/templates/logout.html.ep
lib/Lufi/Controller/Files.pm
lib/Lufi/Controller/Mail.pm