mourningdove/bin/ljsysban.pl

229 lines
7.8 KiB
Perl
Raw Permalink Normal View History

2026-05-24 01:03:05 +00:00
#!/usr/bin/perl
#
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
# the terms of the license supplied by Live Journal, Inc, which can
# currently be found at:
#
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
#
# In accordance with the original license, this code and all its
# modifications are provided under the GNU General Public License.
# A copy of that license can be found in the LICENSE file included as
# part of this distribution.
use strict;
use Getopt::Long;
# parse input options
my ( $list, $add, $modify, $banid, $status, $bandate, $banuntil, $banlength, $what, $value, $note );
exit 1
unless GetOptions(
'list' => \$list,
'add' => \$add,
'modify' => \$modify,
'banid=s' => \$banid,
'status=s' => \$status,
'bandate=s' => \$bandate,
'banuntil=s' => \$banuntil,
'banlength=s' => \$banlength,
'what=s' => \$what,
'value=s' => \$value,
'note=s' => \$note,
);
# did they give valid input?
my $an_opt = ( $what || $value || $status || $bandate || $banuntil || $banlength || $note );
unless (
(
$list && ( ( $banid && !$an_opt ) || ( !$banid && $an_opt ) )
|| ( $add && $what && $value )
|| ( $modify && $banid && $an_opt )
)
)
{
die "Usage: ljsysban.pl [opts]\n\n"
. " --list { <--banid=?> | or one of:\n"
. " [--what=? --status=? --bandate=datetime --banuntil=datetime\n"
. " --value=? --note=?]\n"
. " }\n\n"
. " --add <--what=? --value=?\n"
. " [--status=? --bandate=datetime { --banuntil=datetime | --banlength=duration } --note=?]>\n\n"
. " --modify <--banid=?>\n"
. " [--status=? --bandate=datetime { --banuntil=datetime |\n"
. " --banlength=duration } --value=? --note=?]\n\n"
. "datetime in format 'YYYY-MM-DD HH:MM:SS', duration in format 'N[dhms]' e.g. '5d' or '3h'.\n\n"
. "examples:\n"
. " ljsysban.pl --list --what=ip --value=127.0.0.1\n"
. " ljsysban.pl --add --what=email --value=test\@test.com --banuntil='2006-06-01 00:00:00' --note='test'\n"
. " ljsysban.pl --add --what=uniq --value=jd87fdnef8jf8jef --banlength=3d --note='3 day ban'\n\n";
}
# now load in the beast
BEGIN {
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
}
use LJ::Sysban;
my $dbh = LJ::get_db_writer();
# list bans
if ($list) {
my $where;
if ($banid) {
$where = "banid=" . $dbh->quote($banid);
}
else {
my @where = ();
push @where, ( "what=" . $dbh->quote($what) ) if $what;
push @where, ( "value=" . $dbh->quote($value) ) if $value;
push @where, ( "status=" . $dbh->quote($status) ) if $status;
push @where, ( "bandate=" . $dbh->quote($bandate) ) if $bandate;
push @where, ( "banuntil=" . $dbh->quote($banuntil) ) if $banuntil;
push @where, ( "note=" . $dbh->quote($note) ) if $note;
$where = join( " AND ", @where );
}
my $sth = $dbh->prepare("SELECT * FROM sysban WHERE $where ORDER BY bandate ASC");
$sth->execute;
my $ct;
while ( my $ban = $sth->fetchrow_hashref ) {
print "> banid: $ban->{'banid'}, status: $ban->{'status'}, ";
print "bandate: " . ( $ban->{'bandate'} ? $ban->{'bandate'} : "BOT" ) . ", ";
print "banuntil: " . ( $ban->{'banuntil'} ? $ban->{'banuntil'} : "EOT" ) . "\n";
print "> what: $ban->{'what'}, value: $ban->{'value'}\n";
print "> note: $ban->{'note'}\n" if $ban->{'note'};
print "\n";
$ct++;
}
print "\n\tNO MATCHES\n\n" unless $ct;
exit;
}
# verify ban length and convert to banuntil as necessary
if ($banlength) {
die "--banlength must be of format N[dmhs] such as 3d, 5h, 60m, 35s.\n"
unless $banlength =~ /^(\d+)([dhms])$/i;
my ( $num, $type ) = ( $1, lc $2 );
$banlength = "DATE_ADD(NOW(), INTERVAL $num "
. { 'd' => "DAY", 'h' => "HOUR", 'm' => "MINUTE", 's' => "SECOND" }->{$type} . ")";
$banuntil = $dbh->selectrow_array("SELECT $banlength");
die $dbh->errstr if $dbh->err;
}
# add new ban
if ($add) {
$status = ( $status eq 'expired' ? 'expired' : 'active' );
$dbh->do(
"INSERT INTO sysban (status, what, value, note, bandate, banuntil)"
. "VALUES (?, ?, ?, ?, "
. ( $bandate ? $dbh->quote($bandate) : 'NOW()' ) . ", "
. ( $banuntil ? $dbh->quote($banuntil) : 'NULL' ) . ")",
undef, $status, $what, $value, $note
);
die $dbh->errstr if $dbh->err;
my $insertid = $dbh->{'mysql_insertid'};
LJ::Sysban::ban_do( $what, $value, LJ::mysqldate_to_time($banuntil) );
# log in statushistory
LJ::statushistory_add( 0, 0, 'sysban_add',
"banid=$insertid; status=$status; "
. "bandate="
. ( $bandate || LJ::mysql_time() ) . "; "
. "banuntil="
. ( $banuntil || 'NULL' ) . "; "
. "what=$what; value=$value; "
. "note=$note;" );
print "CREATED: banid=$insertid\n";
exit;
}
# modify existing ban
if ($modify) {
# load selected ban
my $ban = $dbh->selectrow_hashref( "SELECT * FROM sysban WHERE banid=?", undef, $banid );
die $dbh->errstr if $dbh->err;
my @set = ();
# ip/uniq ban and we're going to change the value
if ( ( $value && $value ne $ban->{'value'} )
|| $banuntil && $banuntil ne $ban->{'banuntil'}
|| ( $status && $status ne $ban->{'status'} && $status eq 'expired' ) )
{
LJ::Sysban::ban_undo( $ban->{what}, $value || $ban->{value} );
}
# what - must have a value
if ( $what && $what ne $ban->{'what'} ) {
$ban->{'what'} = $what;
push @set, "what=" . $dbh->quote( $ban->{'what'} );
}
# ip/uniq ban and we are going to change the value
if ( ( $value && $value ne $ban->{'value'} )
|| $banuntil && $banuntil ne $ban->{'banuntil'}
|| ( $status && $status ne $ban->{'status'} && $status eq 'active' ) )
{
my $new_value = $value || $ban->{value};
my $new_banuntil = LJ::mysqldate_to_time( $banuntil || $ban->{banuntil} );
LJ::Sysban::ban_do( $ban->{what}, $new_value, $new_banuntil );
}
# value - must have a value
if ( $value && $value ne $ban->{'value'} ) {
$ban->{'value'} = $value;
push @set, "value=" . $dbh->quote( $ban->{'value'} );
}
# status - must have a value
if ( $status && $status ne $ban->{'status'} ) {
$ban->{'status'} = ( $status eq 'expired' ? 'expired' : 'active' );
push @set, "status=" . $dbh->quote( $ban->{'status'} );
}
# banuntil
if ( $banuntil && $banuntil ne $ban->{'banuntil'} ) {
$ban->{'banuntil'} = ( $banuntil && $banuntil ne 'NULL' ) ? $banuntil : 0;
push @set,
"banuntil=" . ( $ban->{'banuntil'} ? $dbh->quote( $ban->{'banuntil'} ) : 'NULL' );
}
# bandate - must have a value
if ( $bandate && $bandate ne $ban->{'bandate'} ) {
$ban->{'bandate'} = $bandate;
push @set, "bandate=" . $dbh->quote( $ban->{'bandate'} );
}
# note - can be changed to blank
if ( defined $note && $note ne $ban->{'note'} ) {
$ban->{'note'} = $note;
push @set, "note=" . $dbh->quote( $ban->{'note'} );
}
# do update
$dbh->do( "UPDATE sysban SET " . join( ", ", @set ) . " WHERE banid=?", undef,
$ban->{'banid'} );
# log in statushistory
my $msg;
map {
$msg .= " " if $msg;
$msg .= "$_=$ban->{$_};"
} qw(banid status bandate banuntil what value note);
LJ::statushistory_add( 0, 0, 'sysban_mod', $msg );
print "MODIFIED: banid=$banid\n";
exit;
}