| App-ZofCMS-Plugin-FloodControl documentation | Contained in the App-ZofCMS-Plugin-FloodControl distribution. |
App::ZofCMS::Plugin::FloodControl - plugin for protecting forms and anything else from floods (abuse)
In your Main Config File or ZofCMS Template file:
plug_flood_control => {
dsn => "DBI:mysql:database=test;host=localhost",
user => 'test',
pass => 'test',
# everything below is optional
opt => { RaiseError => 1, AutoCommit => 1 },
create_table => 0,
limit => 2,
timeout => 600,
table => 'flood_control',
run => 0,
trigger => 'plug_flood',
cell => 'q',
t_key => 'plug_flood',
flood_id => 'flood',
flood_code => sub {
my ( $template, $query, $config ) = @_;
kill_damn_flooders();
},
no_flood_code => sub {
my ( $template, $query, $config ) = @_;
hug_the_user();
},
}
In your HTML::Template Template:
<tmpl_if name='plug_flood'>
STOP FLOODING, ASSHOLE!
<tmpl_else>
<form ....
.../form>
</tmpl_if>
Plugin needs an SQL table to operate. You can either create it by hand or set the
create_table option to a true value once so plugin could create the table automatically.
The needed table needs to have these three columns:
CREATE TABLE flood_table (host VARCHAR(250), time VARCHAR(10), id VARCHAR(5));
The value type of the id column can be different depending on what flood_id arguments
you'd use (see docs below for more).
The module is a plugin for App::ZofCMS. It provides means to detect flood (abuse) and react accordingly depending on whether or not flood was detected.
This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template
pluginsplugins => [ qw/FloodControl/ ],
You obviously need to the add the plugin in the list of plugins to execute. Along with this plugin you would probably want to use something like App::ZofCMS::Plugin::FormChecker and App::ZofCMS::Plugin::DBI
plug_flood_control plug_flood_control => {
dsn => "DBI:mysql:database=test;host=localhost",
user => 'test',
pass => 'test',
# everything below is optional
opt => { RaiseError => 1, AutoCommit => 1 },
create_table => 0,
limit => 2,
timeout => 600,
table => 'flood_control',
run => 0,
trigger => 'plug_flood',
cell => 'q',
t_key => 'plug_flood',
flood_id => 'flood',
flood_code => sub {
my ( $template, $query, $config ) = @_;
kill_damn_flooders();
},
no_flood_code => sub {
my ( $template, $query, $config ) = @_;
hug_the_user();
},
}
plug_flood_control => sub {
my ( $t, $q, $config ) = @_;
return {
dsn => "DBI:mysql:database=test;host=localhost",
user => 'test',
pass => 'test',
};
}
Plugin uses plug_flood_control first-level key that can be specified in either (or both)
Main Config File or ZofCMS Template file. The key takes a hashref or a subref as a value. If subref is specified,
its return value will be assigned to plug_flood_control as if it was already there. If sub returns
an undef, then plugin will stop further processing. The @_ of the subref will
contain (in that order): ZofCMS Tempalate hashref, query parameters hashref and
App::ZofCMS::Config object. If the keys of
that hashref are specified in both files will take their values from ZofCMS Template.
Most of these keys are optional with sensible defaults. Possible keys/values are as follows:
dsndsn => "DBI:mysql:database=test;host=localhost",
Mandatory. Specifies the "DSN" for DBI module. See DBI's docs for connect_cached()
method for more info on this one.
useruser => 'test',
Mandatory. Specifies your username for the SQL database.
passpass => 'test',
Mandatory. Specifies your password for the SQL database.
opt opt => { RaiseError => 1, AutoCommit => 1 },
Optional. Takes a hashref as a value. Specifies the additional options for DBI's
connect_cached() method. See DBI's docs for connect_cached()
method for more info on this one. Defaults to: { RaiseError => 1, AutoCommit => 1 }
tabletable => 'flood_control',
Optional. Takes a string as a value that represents the name of the table in which to
store flood data. Defaults to: flood_control
create_tablecreate_table => 0,
Optional. Takes either true or false values. When set to a true value will automatically
create the table that is needed for the plugin. You can create the table manually, its
format is described in the SYNOPSIS section above. Defaults to: 0
limitlimit => 2,
Optional. Specifies the "flood limit". Takes a positive integer value that
is the number of times the plugin will be
triggered in timeout (see below) seconds before it will think we are being abused.
Defaults to: 2
timeouttimeout => 600,
Optional. Takes a positive integer value. Specifies timeout in seconds after which
the plugin will forget that a certain user triggered it. In other words, if the plugin is
triggered when someone submits the form and timeout is set to 600 and limit is set
to 2 then the user would be able to submit the form only twice every 10 minutes.
Defaults to: 600
triggertrigger => 'plug_flood',
Optional. Takes a string as a value that names the key in a cell (see below).
Except for when the cell is set to q, the value referenced by the key must contain
a true value in order for the plugin to trigger (to run). Defaults to: plug_flood
cellcell => 'q',
Optional. The plugin can be triggered either from query, {t} special key, {d}
ZofCMS Template special key, or any first-level ZofCMS Template key (also, see run
option below). The value of the cell key specifies where the plugin will look for the
trigger (see above). Possible values for cell key are: q (query), d ({d} key),
t ({t} key) or empty string (first-level ZofCMS Template key). For every cell value
but the q, the trigger (i.e. the key referenced by the trigger argument) must be set
to a true value in order for the plugin to trigger. When cell is set to value q, then
the query parameter referenced by trigger must have length() in order for the plugin
to trigger. Defaults to: q
runrun => 0,
Optional. An alternative to using cell and trigger arguments you can set
(e.g. dynamically with some other plugin) the run argument to a true value. Takes
either true or false values. When set to a true value plugin will "trigger" (check for floods)
without any consideration to cell and trigger values. Defaults to: 0
t_keyt_key => 'plug_flood',
Optional. If plugin sees that the user is flooding, it will set t_key in ZofCMS Template
{t} special key. Thus you can display appropriate messages using <tmpl_if name="">.
Defaults to: plug_flood
flood_idflood_id => 'flood',
Optional. You can use the same table to control various pages or forms from flood
independently by setting flood_id to different values for each of them. Defaults to:
flood
flood_code flood_code => sub {
my ( $template, $query, $config ) = @_;
kill_damn_flooders();
},
Optional. Takes a subref as a value. This sub will be run if plugin thinks that the user
is flooding. The @_ will contain (in that order) ZofCMS Template hashref, query parameters
hashref where keys are params' names and values are their values and App::ZofCMS::Config
object. By default is not specified.
no_flood_code no_flood_code => sub {
my ( $template, $query, $config ) = @_;
hug_the_user();
},
Optional. Takes a subref as a value. This is the opposite of flood_code.
This sub will be run if plugin thinks that the user
is NOT flooding.
The @_ will contain (in that order) ZofCMS Template hashref, query parameters
hashref where keys are params' names and values are their values and App::ZofCMS::Config
object. By default is not specified.
'Zoffix, <'zoffix at cpan.org'>
(http://zoffix.com/, http://haslayout.net/, http://zofdesign.com/)
Please report any bugs or feature requests to bug-app-zofcms-plugin-floodcontrol at rt.cpan.org, or through
the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=App-ZofCMS-Plugin-FloodControl. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
perldoc App::ZofCMS::Plugin::FloodControl
You can also look for information at:
http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-ZofCMS-Plugin-FloodControl
http://cpanratings.perl.org/d/App-ZofCMS-Plugin-FloodControl
Copyright 2008 'Zoffix, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| App-ZofCMS-Plugin-FloodControl documentation | Contained in the App-ZofCMS-Plugin-FloodControl distribution. |
package App::ZofCMS::Plugin::FloodControl; use warnings; use strict; our $VERSION = '0.0103'; use DBI; use base 'App::ZofCMS::Plugin::Base'; sub _key { 'plug_flood_control' } sub _defaults { return ( # dsn => "DBI:mysql:database=test;host=localhost", # user => 'test', # pass => 'test', create_table => 0, opt => { RaiseError => 1, AutoCommit => 1 }, limit => 2, run => 1, timeout => 600, table => 'flood_control', trigger => 'plug_flood', t_key => 'plug_flood', cell => 'q', flood_id => 'flood', ); } sub _do { my ( $self, $conf, $template, $query, $config ) = @_; unless ( $conf->{run} ) { my ( $cell, $trigger ) = @$conf{ qw/cell trigger/ }; if ( $cell eq 'q' ) { return unless defined $query->{ $trigger } and length $query->{ $trigger }; } elsif ( $cell eq 't' or $cell eq 'd' ) { return unless $template->{ $cell }{ $trigger }; } elsif ( $cell eq '' ) { return unless $template->{ $trigger }; } } my $host = $config->cgi->remote_host; $host = substr $host, 0, 250; my $dbh = DBI->connect_cached( @$conf{ qw/dsn user pass opt/ } ); if ( $conf->{create_table} ) { $dbh->do( "CREATE TABLE $conf->{table} (host TEXT, time VARCHAR(10), id VARCHAR(5));", ); } $dbh->do( "DELETE FROM $conf->{table} WHERE time < ? AND id = ?;", undef, time() - $conf->{timeout}, $conf->{flood_id}, ); my $entries = $dbh->selectall_arrayref( "SELECT * FROM $conf->{table} WHERE host = ? AND id = ?;", { Slice => {} }, $host, $conf->{flood_id}, ); if ( @{ $entries || [] } >= $conf->{limit} ) { $template->{t}{ $conf->{t_key} } = 1; if ( $conf->{flood_code} ) { $conf->{flood_code}( $template, $query, $config ); } } else { $dbh->do( "INSERT INTO $conf->{table} VALUES(?, ?, ?);", undef, $host, time(), $conf->{flood_id}, ); if ( $conf->{no_flood_code} ) { $conf->{no_flood_code}( $template, $query, $config ); } } } 1; __END__