Commit 9576cfee authored by Luc Didry's avatar Luc Didry

Add PostgreSQL support. Fix #21

parent 95adc29c
image: debian:jessie image: debian:jessie
test: stages:
script: - sqlite
- apt-get update - postgresql
- apt-get install -y build-essential libssl-dev openssl perl-doc before_script:
- echo yes | cpan Carton - apt-get update
- carton install - apt-get install -y build-essential libssl-dev openssl perl-doc libpq-dev
- cp lstu.conf.template lstu.conf - echo yes | cpan Carton
- sed -i -e "s@#contact@contact@" -e "s@#adminpwd.*@adminpwd => 'toto',@" -e "s@#db_path.*@db_path => 'test.db',@" lstu.conf - carton install
- cp lstu.conf.template lstu.conf
- sed -i -e "s@#contact@contact@" -e "s@#adminpwd.*@adminpwd => 'toto',@" -e "s@#db_path.*@db_path => 'test.db',@" -e "s@#pgdb.*@pgdb => {database => 'lstu', host => 'localhost', user => 'lstu', pwd => 'lstu'},@" lstu.conf
sqlite:
stage: sqlite
script:
- rm -f test.db - rm -f test.db
- make test - make test
- sed -i -e "s@ \(adminpwd.*\)@ \#\1@" -e "s@#hashed_adminpwd.*@hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',@" lstu.conf - sed -i -e "s@ \(adminpwd.*\)@ \#\1@" -e "s@#hashed_adminpwd.*@hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',@" lstu.conf
...@@ -19,3 +24,22 @@ test: ...@@ -19,3 +24,22 @@ test:
tags: tags:
- Debian - Debian
- Jessie - Jessie
postgresql:
stage: postgresql
script:
- apt-get install -y postgresql
- service postgresql start
- sleep 2
- service postgresql status
- su -c "psql -f t/test.sql" postgres
- sed -i -e "s@#dbtype =>.*@dbtype => 'postgresql'@" lstu.conf
- make test
- sed -i -e "s@ \(adminpwd.*\)@ \#\1@" -e "s@#hashed_adminpwd.*@hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',@" lstu.conf
- make test
- sed -i -e "s@#minion.*@minion => { enabled => 1, db_path => 'minion.db' },@" lstu.conf
- rm -f minion.db
- make minion &
- make test
tags:
- Debian
- Jessie
...@@ -10,12 +10,24 @@ Lstu is licensed under the terms of the WTFPL. See the LICENSE file. ...@@ -10,12 +10,24 @@ Lstu is licensed under the terms of the WTFPL. See the LICENSE file.
## Dependencies ## Dependencies
* In order to compile some dependencies, you'll need some packages from your distro:
```shell
sudo apt-get install build-essential libssl-dev
```
* Carton : Perl dependencies manager, it will get what you need, so don't bother about dependencies (but you can read the file `cpanfile` if you want). * Carton : Perl dependencies manager, it will get what you need, so don't bother about dependencies (but you can read the file `cpanfile` if you want).
```shell ```shell
sudo cpan Carton sudo cpan Carton
``` ```
* If you want to use PostgreSQL as a backend, install `libpq-dev` too:
```shell
sudo apt-get install libpq-dev
```
## Installation ## Installation
After installing Carton : After installing Carton :
...@@ -23,8 +35,20 @@ After installing Carton : ...@@ -23,8 +35,20 @@ After installing Carton :
```shell ```shell
git clone https://framagit.org/luc/lstu.git git clone https://framagit.org/luc/lstu.git
cd lstu cd lstu
```
If you **don't** want to use PostgreSQL as a backend, comment the line `requires 'Mojo::Pg';` in the `cpanfile` file:
```shell
sed -e "s@requires 'Mojo::Pg';@#requires 'Mojo::Pg';@" -i cpanfile
```
Let's continue the installation:
```shell
make installdeps make installdeps
cp lstu.conf.template lstu.conf cp lstu.conf.template lstu.conf
# Edit the configuration file
vi lstu.conf vi lstu.conf
``` ```
...@@ -35,6 +59,17 @@ The configuration file is self-documented. ...@@ -35,6 +59,17 @@ The configuration file is self-documented.
```shell ```shell
cd /your/lstu/installation/directory cd /your/lstu/installation/directory
git pull git pull
```
If you **don't** want to use PostgreSQL as a backend, comment the line `requires 'Mojo::Pg';` in the `cpanfile` file:
```shell
sed -e "s@requires 'Mojo::Pg';@#requires 'Mojo::Pg';@" -i cpanfile
```
Then:
```shell
make installdeps make installdeps
vimdiff lstu.conf.template lstu.conf vimdiff lstu.conf.template lstu.conf
``` ```
......
requires 'Mojolicious', '>= 4.63'; requires 'Mojolicious', '>= 4.63';
requires 'ORLite'; requires 'ORLite';
requires 'Mojo::Pg';
requires 'Data::Validate::URI'; requires 'Data::Validate::URI';
requires 'Net::Domain::TLD', '>= 1.74'; requires 'Net::Domain::TLD', '>= 1.74';
requires 'Mojolicious::Plugin::I18N'; requires 'Mojolicious::Plugin::I18N';
......
...@@ -74,6 +74,17 @@ DISTRIBUTIONS ...@@ -74,6 +74,17 @@ DISTRIBUTIONS
Test::More 0.94 Test::More 0.94
strict 0 strict 0
warnings 0 warnings 0
DBD-Pg-3.5.3
pathname: T/TU/TURNSTEP/DBD-Pg-3.5.3.tar.gz
provides:
Bundle::DBD::Pg v3.5.3
DBD::Pg v3.5.3
requirements:
DBI 1.614
ExtUtils::MakeMaker 6.11
Test::More 0.88
Time::HiRes 0
version 0
DBD-SQLite-1.54 DBD-SQLite-1.54
pathname: I/IS/ISHIGAKI/DBD-SQLite-1.54.tar.gz pathname: I/IS/ISHIGAKI/DBD-SQLite-1.54.tar.gz
provides: provides:
...@@ -415,17 +426,17 @@ DISTRIBUTIONS ...@@ -415,17 +426,17 @@ DISTRIBUTIONS
IO::Socket 0 IO::Socket 0
Socket 1.97 Socket 1.97
Test::More 0.88 Test::More 0.88
IO-Socket-SSL-2.043 IO-Socket-SSL-2.044
pathname: S/SU/SULLR/IO-Socket-SSL-2.043.tar.gz pathname: S/SU/SULLR/IO-Socket-SSL-2.044.tar.gz
provides: provides:
IO::Socket::SSL 2.043 IO::Socket::SSL 2.044
IO::Socket::SSL::Intercept 2.014 IO::Socket::SSL::Intercept 2.014
IO::Socket::SSL::OCSP_Cache 2.043 IO::Socket::SSL::OCSP_Cache 2.044
IO::Socket::SSL::OCSP_Resolver 2.043 IO::Socket::SSL::OCSP_Resolver 2.044
IO::Socket::SSL::PublicSuffix undef IO::Socket::SSL::PublicSuffix undef
IO::Socket::SSL::SSL_Context 2.043 IO::Socket::SSL::SSL_Context 2.044
IO::Socket::SSL::SSL_HANDLE 2.043 IO::Socket::SSL::SSL_HANDLE 2.044
IO::Socket::SSL::Session_Cache 2.043 IO::Socket::SSL::Session_Cache 2.044
IO::Socket::SSL::Utils 2.014 IO::Socket::SSL::Utils 2.014
requirements: requirements:
ExtUtils::MakeMaker 0 ExtUtils::MakeMaker 0
...@@ -594,6 +605,19 @@ DISTRIBUTIONS ...@@ -594,6 +605,19 @@ DISTRIBUTIONS
perl 5.006 perl 5.006
strict 0 strict 0
warnings 0 warnings 0
Mojo-Pg-2.35
pathname: S/SR/SRI/Mojo-Pg-2.35.tar.gz
provides:
Mojo::Pg 2.35
Mojo::Pg::Database undef
Mojo::Pg::Migrations undef
Mojo::Pg::PubSub undef
Mojo::Pg::Results undef
Mojo::Pg::Transaction undef
requirements:
DBD::Pg 3.005001
ExtUtils::MakeMaker 0
Mojolicious 7.15
Mojo-SQLite-1.003 Mojo-SQLite-1.003
pathname: D/DB/DBOOK/Mojo-SQLite-1.003.tar.gz pathname: D/DB/DBOOK/Mojo-SQLite-1.003.tar.gz
provides: provides:
...@@ -616,8 +640,8 @@ DISTRIBUTIONS ...@@ -616,8 +640,8 @@ DISTRIBUTIONS
URI::db 0.15 URI::db 0.15
URI::file 4.21 URI::file 4.21
perl 5.010001 perl 5.010001
Mojolicious-7.18 Mojolicious-7.23
pathname: S/SR/SRI/Mojolicious-7.18.tar.gz pathname: S/SR/SRI/Mojolicious-7.23.tar.gz
provides: provides:
Mojo undef Mojo undef
Mojo::Asset undef Mojo::Asset undef
...@@ -649,6 +673,7 @@ DISTRIBUTIONS ...@@ -649,6 +673,7 @@ DISTRIBUTIONS
Mojo::IOLoop::Server undef Mojo::IOLoop::Server undef
Mojo::IOLoop::Stream undef Mojo::IOLoop::Stream undef
Mojo::IOLoop::Subprocess undef Mojo::IOLoop::Subprocess undef
Mojo::IOLoop::TLS undef
Mojo::JSON undef Mojo::JSON undef
Mojo::JSON::Pointer undef Mojo::JSON::Pointer undef
Mojo::Loader undef Mojo::Loader undef
...@@ -682,7 +707,7 @@ DISTRIBUTIONS ...@@ -682,7 +707,7 @@ DISTRIBUTIONS
Mojo::UserAgent::Transactor undef Mojo::UserAgent::Transactor undef
Mojo::Util undef Mojo::Util undef
Mojo::WebSocket undef Mojo::WebSocket undef
Mojolicious 7.18 Mojolicious 7.23
Mojolicious::Command undef Mojolicious::Command undef
Mojolicious::Command::cgi undef Mojolicious::Command::cgi undef
Mojolicious::Command::cpanify undef Mojolicious::Command::cpanify undef
......
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: # vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lstu; package Lstu;
use Mojo::Base 'Mojolicious'; use Mojo::Base 'Mojolicious';
use Data::Validate::URI qw(is_http_uri is_https_uri);
use Mojo::JSON qw(to_json decode_json);
use Mojo::URL;
use Net::Abuse::Utils::Spamhaus qw(check_fqdn);
use Net::LDAP; use Net::LDAP;
use Apache::Htpasswd; use Apache::Htpasswd;
use Lstu::DB::URL; use Lstu::DB::URL;
use Lstu::DB::Ban;
use Lstu::DB::Session;
$ENV{MOJO_REVERSE_PROXY} = 1; $ENV{MOJO_REVERSE_PROXY} = 1;
...@@ -61,6 +55,9 @@ sub startup { ...@@ -61,6 +55,9 @@ sub startup {
# Piwik # Piwik
$self->plugin('Piwik'); $self->plugin('Piwik');
# Lstu Helpers
$self->plugin('Lstu::Plugin::Helpers');
# Authentication (if configured) # Authentication (if configured)
if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) { if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) {
die 'Unable to read '.$self->config('htpasswd') if (defined($self->config('htpasswd')) && !-r $self->config('htpasswd')); die 'Unable to read '.$self->config('htpasswd') if (defined($self->config('htpasswd')) && !-r $self->config('htpasswd'));
...@@ -134,122 +131,6 @@ sub startup { ...@@ -134,122 +131,6 @@ sub startup {
# Secrets # Secrets
$self->secrets($config->{secret}); $self->secrets($config->{secret});
# Helpers
$self->helper(
cache => sub {
my $c = shift;
state $cache = {};
}
);
$self->helper(
clear_cache => sub {
my $c = shift;
my $cache = $c->cache;
my @keys = keys %{$cache};
my $limit = ($c->app->mode eq 'production') ? 500 : 1;
map {delete $cache->{$_};} @keys if (scalar(@keys) > $limit);
}
);
$self->helper(
ip => sub {
my $c = shift;
my $proxy = $c->req->headers->header('X-Forwarded-For');
my $ip = ($proxy) ? $proxy : $c->tx->remote_address;
return $ip;
}
);
$self->helper(
provisioning => sub {
my $c = shift;
# Create some short patterns for provisioning
my $db_url = Lstu::DB::URL->new(dbtype => $c->config('dbtype'));
if ($db_url->count_empty < $c->config('provisioning')) {
for (my $i = 0; $i < $c->config('provis_step'); $i++) {
my $short;
do {
$short= $c->shortener($c->config('length'));
} while ($db_url->exist($short));
$db_url->short($short)->write;
}
}
}
);
$self->helper(
prefix => sub {
my $c = shift;
my $prefix = $c->url_for('index')->to_abs;
# Forced domain
$prefix->host($c->config('fixed_domain')) if (defined($c->config('fixed_domain')) && $c->config('fixed_domain') ne '');
# Hack for prefix (subdir) handling
$prefix .= '/' unless ($prefix =~ m#/$#);
return $prefix;
}
);
$self->helper(
shortener => sub {
my $c = shift;
my $length = shift;
my @chars = ('a'..'h', 'j', 'k', 'm'..'z','A'..'H', 'J'..'N', 'P'..'Z','0'..'9', '-', '_');
my $result = '';
foreach (1..$length) {
$result .= $chars[rand scalar(@chars)];
}
return $result;
}
);
$self->helper(
is_spam => sub {
my $c = shift;
my $url = shift;
my $nb_redir = shift;
if ($nb_redir++ <= 2) {
my $res = check_fqdn($url->host);
if (defined $res) {
return {
is_spam => 1,
msg => $c->l('The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I refuse to shorten it.', $url->host)
}
} else {
my $res = $c->ua->get($url)->res;
if ($res->code >= 300 && $res->code < 400) {
return $c->is_spam(Mojo::URL->new($res->headers->location), $nb_redir);
} else {
return { is_spam => 0 };
}
}
} else {
return {
is_spam => 1,
msg => $c->l('The URL redirects 3 times or most. It\'s most likely a dangerous URL (spam, phishing, etc.). I refuse to shorten it.', $url->host)
}
}
}
);
$self->helper(
cleaning => sub {
my $c = shift;
# Delete old sessions
Lstu::DB::Session->new(dbtype => $c->config('dbtype'))->clear();
# Delete old bans
Lstu::DB::Ban->new(dbtype => $c->config('dbtype'))->clear();
}
);
# Hooks # Hooks
$self->hook( $self->hook(
after_dispatch => sub { after_dispatch => sub {
...@@ -291,7 +172,7 @@ sub startup { ...@@ -291,7 +172,7 @@ sub startup {
my $url = shift; my $url = shift;
my $db_url = Lstu::DB::URL->new( my $db_url = Lstu::DB::URL->new(
dbtype => $job->app->config('dbtype'), app => $job->app,
short => $short short => $short
)->increment_counter; )->increment_counter;
......
...@@ -16,7 +16,7 @@ sub login { ...@@ -16,7 +16,7 @@ sub login {
my $ip = $c->ip; my $ip = $c->ip;
my $banned = Lstu::DB::Ban->new( my $banned = Lstu::DB::Ban->new(
dbtype => $c->config('dbtype'), app => $c,
ip => $ip ip => $ip
)->is_banned($c->config('ban_min_strike')); )->is_banned($c->config('ban_min_strike'));
if (defined $banned) { if (defined $banned) {
...@@ -37,7 +37,7 @@ sub login { ...@@ -37,7 +37,7 @@ sub login {
my $token = $c->shortener(32); my $token = $c->shortener(32);
Lstu::DB::Session->new( Lstu::DB::Session->new(
dbtype => $c->config('dbtype'), app => $c,
token => $token, token => $token,
until => time + 3600 until => time + 3600
)->write; )->write;
...@@ -46,14 +46,14 @@ sub login { ...@@ -46,14 +46,14 @@ sub login {
$c->redirect_to('stats'); $c->redirect_to('stats');
} elsif (defined($act) && $act eq 'logout') { } elsif (defined($act) && $act eq 'logout') {
Lstu::DB::Session->new( Lstu::DB::Session->new(
dbtype => $c->config('dbtype'), app => $c,
token => $c->session('token') token => $c->session('token')
)->delete; )->delete;
delete $c->session->{token}; delete $c->session->{token};
$c->redirect_to('stats'); $c->redirect_to('stats');
} else { } else {
Lstu::DB::Ban->new( Lstu::DB::Ban->new(
dbtype => $c->config('dbtype'), app => $c,
ip => $ip ip => $ip
)->increment_ban_delay(3600); )->increment_ban_delay(3600);
...@@ -68,12 +68,12 @@ sub delete { ...@@ -68,12 +68,12 @@ sub delete {
my $short = $c->param('short'); my $short = $c->param('short');
my $db_session = Lstu::DB::Session->new( my $db_session = Lstu::DB::Session->new(
dbtype => $c->config('dbtype'), app => $c,
token => $c->session('token') token => $c->session('token')
); );
if (defined($c->session('token')) && $db_session->is_valid) { if (defined($c->session('token')) && $db_session->is_valid) {
my $db_url = Lstu::DB::URL->new( my $db_url = Lstu::DB::URL->new(
dbtype => $c->config('dbtype'), app => $c,
short => $short short => $short
); );
if ($db_url->url) { if ($db_url->url) {
......
...@@ -17,7 +17,7 @@ sub add { ...@@ -17,7 +17,7 @@ sub add {
my $ip = $c->ip; my $ip = $c->ip;
my $banned = Lstu::DB::Ban->new( my $banned = Lstu::DB::Ban->new(
dbtype => $c->config('dbtype'), app => $c,
ip => $c->ip ip => $c->ip
)->is_banned($c->config('ban_min_strike')); )->is_banned($c->config('ban_min_strike'));
if (defined $banned) { if (defined $banned) {
...@@ -60,12 +60,12 @@ sub add { ...@@ -60,12 +60,12 @@ sub add {
$msg = $res->{msg}; $msg = $res->{msg};
} else { } else {
my $db_url = Lstu::DB::URL->new( my $db_url = Lstu::DB::URL->new(
dbtype => $c->config('dbtype'), app => $c,
url => $url url => $url
); );
Lstu::DB::Ban->new( Lstu::DB::Ban->new(
dbtype => $c->config('dbtype'), app => $c,
ip => $ip ip => $ip
)->increment_ban_delay(1); )->increment_ban_delay(1);
...@@ -82,7 +82,7 @@ sub add { ...@@ -82,7 +82,7 @@ sub add {
$short = $custom_url; $short = $custom_url;
} else { } else {
$db_url = Lstu::DB::URL->new(dbtype => $c->config('dbtype'))->choose_empty; $db_url = Lstu::DB::URL->new(app => $c)->choose_empty;
if (defined $db_url) { if (defined $db_url) {
$db_url->url($url)->timestamp(time)->write; $db_url->url($url)->timestamp(time)->write;
...@@ -142,11 +142,11 @@ sub stats { ...@@ -142,11 +142,11 @@ sub stats {
my $c = shift; my $c = shift;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) { if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
my $db_session = Lstu::DB::Session->new( my $db_session = Lstu::DB::Session->new(
dbtype => $c->config('dbtype'), app => $c,
token => $c->session('token') token => $c->session('token')
); );
if (defined($c->session('token')) && $db_session->is_valid) { if (defined($c->session('token')) && $db_session->is_valid) {
my $total = Lstu::DB::URL->new(dbtype => $c->config('dbtype'))->total; my $total = Lstu::DB::URL->new(app => $c)->total;
my $page = $c->param('page') || 0; my $page = $c->param('page') || 0;
$page = 0 if ($page < 0); $page = 0 if ($page < 0);
$page = $page - 1 if ($page * $c->config('page_offset') > $total); $page = $page - 1 if ($page * $c->config('page_offset') > $total);
...@@ -154,7 +154,7 @@ sub stats { ...@@ -154,7 +154,7 @@ sub stats {
my ($first, $last) = (!$page, ($page * $c->config('page_offset') <= $total && $total < ($page + 1) * $c->config('page_offset'))); my ($first, $last) = (!$page, ($page * $c->config('page_offset') <= $total && $total < ($page + 1) * $c->config('page_offset')));
my @urls = Lstu::DB::URL->new( my @urls = Lstu::DB::URL->new(
dbtype => $c->config('dbtype'), app => $c,
)->paginate($page, $c->config('page_offset')); )->paginate($page, $c->config('page_offset'));
$c->respond_to( $c->respond_to(
json => sub { json => sub {
...@@ -189,7 +189,7 @@ sub stats { ...@@ -189,7 +189,7 @@ sub stats {
my $u = (defined($c->cookie('url'))) ? decode_json $c->cookie('url') : []; my $u = (defined($c->cookie('url'))) ? decode_json $c->cookie('url') : [];
my @urls = Lstu::DB::URL->new( my @urls = Lstu::DB::URL->new(
dbtype => $c->config('dbtype'), app => $c
)->get_a_lot($u); )->get_a_lot($u);
my $prefix = $c->prefix; my $prefix = $c->prefix;
...@@ -230,7 +230,7 @@ sub get { ...@@ -230,7 +230,7 @@ sub get {
$url = $c->cache->{$short}->{url}; $url = $c->cache->{$short}->{url};
} else { } else {
$db_url = Lstu::DB::URL->new( $db_url = Lstu::DB::URL->new(
dbtype => $c->config('dbtype'), app => $c,
short => $short short => $short
); );
$url = $db_url->url; $url = $db_url->url;
...@@ -255,7 +255,7 @@ sub get { ...@@ -255,7 +255,7 @@ sub get {
$c->app->minion->enqueue(increase_counter => [$short, $c->{url}]); $c->app->minion->enqueue(increase_counter => [$short, $c->{url}]);
} else { } else {
$db_url = Lstu::DB::URL->new( $db_url = Lstu::DB::URL->new(
dbtype => $c->config('dbtype'), app => $c,
short => $short short => $short
) if (defined $c->cache->{$short}); ) if (defined $c->cache->{$short});
......
...@@ -5,7 +5,7 @@ use Mojo::Base -base; ...@@ -5,7 +5,7 @@ use Mojo::Base -base;
has 'ip'; has 'ip';
has 'until'; has 'until';
has 'strike' => 0; has 'strike' => 0;
has 'dbtype'; has 'app';
=head1 NAME =head1 NAME
...@@ -28,7 +28,7 @@ Have a look at Lstu::DB::Ban::SQLite's code: it's simple and may be more underst ...@@ -28,7 +28,7 @@ Have a look at Lstu::DB::Ban::SQLite's code: it's simple and may be more underst
=item B<strike> : integer =item B<strike> : integer
=item B<dbtype> : string =item B<app> : a mojolicious object
=back =back
...@@ -38,7 +38,7 @@ Have a look at Lstu::DB::Ban::SQLite's code: it's simple and may be more underst ...@@ -38,7 +38,7 @@ Have a look at Lstu::DB::Ban::SQLite's code: it's simple and may be more underst
=over 1 =over 1
=item B<Usage> : C<$c = Lstu::DB::Ban-E<gt>new(dbtype =E<gt> 'sqlite');> =item B<Usage> : C<$c = Lstu::DB::Ban-E<gt>new(app =E<gt> $self);>
=item B<Arguments> : any of the attribute above =item B<Arguments> : any of the attribute above
...@@ -46,7 +46,7 @@ Have a look at Lstu::DB::Ban::SQLite's code: it's simple and may be more underst ...@@ -46,7 +46,7 @@ Have a look at Lstu::DB::Ban::SQLite's code: it's simple and may be more underst
=item B<Returns> : the db accessor object =item B<Returns> : the db accessor object
=item B<Info> : the dbtype argument is used by Lstu::DB::Ban to choose which db accessor will be used, you don't need to use it =item B<Info> : the app argument is used by Lstu::DB::Ban to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines
=back =back
...@@ -58,9 +58,13 @@ sub new { ...@@ -58,9 +58,13 @@ sub new {
$c = $c->SUPER::new(@_); $c = $c->SUPER::new(@_);
if (ref($c) eq 'Lstu::DB::Ban') { if (ref($c) eq 'Lstu::DB::Ban') {
if ($c->dbtype eq 'sqlite') { my $dbtype = $c->app->config('dbtype');
if ($dbtype eq 'sqlite') {
use Lstu::DB::Ban::SQLite; use Lstu::DB::Ban::SQLite;
$c = Lstu::DB::Ban::SQLite->new(@_); $c = Lstu::DB::Ban::SQLite->new(@_);
} elsif ($dbtype eq 'postgresql') {
use Lstu::DB::Ban::Pg;
$c = Lstu::DB::Ban::Pg->new(@_);
} }
} }
......
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lstu::DB::Ban::Pg;
use Mojo::Base 'Lstu::DB::Ban';
has 'record' => 0;
sub new {
my $c = shift;
$c = $c->SUPER::new(@_);
$c = $c->_slurp if ($c->ip);
return $c;
}
sub is_banned {
my $c = shift;
my $ban_min_strike = shift;
my $h = $c->app->pg->db->query('SELECT * FROM ban WHERE ip = ? AND until > ? AND strike >= ?', $c->ip, time, $ban_min_strike)->hashes;
if ($h->size) {
$c->until($h->first->{until});
$c->strike($h->first->{strike});
$c->record(1);