3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-26 22:09:26 +01:00

Escape undesired SQL wildcards in certain statements; add aka command to list also-known-as entries

This commit is contained in:
Pragmatic Software 2014-07-11 12:57:18 +00:00
parent 65073e311d
commit 46b5b95d54
3 changed files with 149 additions and 14 deletions

View File

@ -46,7 +46,8 @@ sub initialize {
$self->{pbot}->{registry}->add_default('text', 'messagehistory', 'max_messages', $conf{max_messages} // 32); $self->{pbot}->{registry}->add_default('text', 'messagehistory', 'max_messages', $conf{max_messages} // 32);
$self->{pbot}->{commands}->register(sub { $self->recall_message(@_) }, "recall", 0); $self->{pbot}->{commands}->register(sub { $self->recall_message(@_) }, "recall", 0);
$self->{pbot}->{commands}->register(sub { $self->list_also_known_as(@_) }, "aka", 0);
$self->{pbot}->{atexit}->register(sub { $self->{database}->end(); return; }); $self->{pbot}->{atexit}->register(sub { $self->{database}->end(); return; });
} }
@ -61,6 +62,35 @@ sub add_message {
$self->{database}->add_message($account, $mask, $channel, { timestamp => scalar gettimeofday, msg => $text, mode => $mode }); $self->{database}->add_message($account, $mask, $channel, { timestamp => scalar gettimeofday, msg => $text, mode => $mode });
} }
sub list_also_known_as {
my ($self, $from, $nick, $user, $host, $arguments) = @_;
if(not length $arguments) {
return "Usage: aka <nick>";
}
my @akas = $self->{database}->get_also_known_as($arguments);
if(@akas) {
my $result = "$arguments also known as: ";
my %uniq;
foreach my $aka (@akas) {
my ($nick) = $aka =~ /^([^!]+)!/;
$uniq{$nick} = $nick;
}
my $sep = "";
foreach my $aka (sort keys %uniq) {
next if $aka =~ /^Guest\d+$/;
$result .= "$sep$aka";
$sep = ", ";
}
return $result;
} else {
return "I don't know anybody named $arguments.";
}
}
sub recall_message { sub recall_message {
my ($self, $from, $nick, $user, $host, $arguments) = @_; my ($self, $from, $nick, $user, $host, $arguments) = @_;

View File

@ -240,8 +240,9 @@ sub find_message_account_by_nick {
my ($self, $nick) = @_; my ($self, $nick) = @_;
my ($id, $hostmask) = eval { my ($id, $hostmask) = eval {
my $sth = $self->{dbh}->prepare('SELECT id,hostmask FROM Hostmasks WHERE hostmask LIKE ? LIMIT 1'); my $sth = $self->{dbh}->prepare('SELECT id,hostmask FROM Hostmasks WHERE hostmask LIKE ? ESCAPE "\" LIMIT 1');
$sth->bind_param(1, "$nick!%"); my $qnick = quotemeta $nick;
$sth->bind_param(1, "$qnick!%");
$sth->execute(); $sth->execute();
my $row = $sth->fetchrow_hashref(); my $row = $sth->fetchrow_hashref();
return ($row->{id}, $row->{hostmask}); return ($row->{id}, $row->{hostmask});
@ -268,13 +269,14 @@ sub find_message_accounts_by_nickserv {
sub find_message_accounts_by_mask { sub find_message_accounts_by_mask {
my ($self, $mask) = @_; my ($self, $mask) = @_;
$mask =~ s/\*/%/g; my $qmask = quotemeta $mask;
$mask =~ s/\?/_/g; $qmask =~ s/\\\*/%/g;
$mask =~ s/\$.*$//; $qmask =~ s/\\\?/_/g;
$qmask =~ s/\\\$.*$//;
my $accounts = eval { my $accounts = eval {
my $sth = $self->{dbh}->prepare('SELECT id FROM Hostmasks WHERE hostmask LIKE ?'); my $sth = $self->{dbh}->prepare('SELECT id FROM Hostmasks WHERE hostmask LIKE ? ESCAPE "\"');
$sth->bind_param(1, $mask); $sth->bind_param(1, $qmask);
$sth->execute(); $sth->execute();
return $sth->fetchall_arrayref(); return $sth->fetchall_arrayref();
}; };
@ -290,8 +292,9 @@ sub get_message_account {
return $id if defined $id; return $id if defined $id;
my $rows = eval { my $rows = eval {
my $sth = $self->{dbh}->prepare('SELECT id,hostmask FROM Hostmasks WHERE hostmask LIKE ? ORDER BY last_seen DESC'); my $sth = $self->{dbh}->prepare('SELECT id,hostmask FROM Hostmasks WHERE hostmask LIKE ? ESCAPE "\" ORDER BY last_seen DESC');
$sth->bind_param(1, "$nick!%"); my $qnick = quotemeta $nick;
$sth->bind_param(1, "$qnick!%");
$sth->execute(); $sth->execute();
my $rows = $sth->fetchall_arrayref({}); my $rows = $sth->fetchall_arrayref({});
@ -353,7 +356,7 @@ sub update_hostmask_data {
$comma = ', '; $comma = ', ';
} }
$sql .= ' WHERE hostmask LIKE ?'; $sql .= ' WHERE hostmask LIKE ? ESCAPE "\"';
my $sth = $self->{dbh}->prepare($sql); my $sth = $self->{dbh}->prepare($sql);
@ -362,7 +365,8 @@ sub update_hostmask_data {
$sth->bind_param($param++, $data->{$key}); $sth->bind_param($param++, $data->{$key});
} }
$sth->bind_param($param, $mask); my $qmask = quotemeta $mask;
$sth->bind_param($param, $qmask);
$sth->execute(); $sth->execute();
$self->{new_entries}++; $self->{new_entries}++;
}; };
@ -632,7 +636,7 @@ sub get_channel_datas_with_enter_abuses {
my ($self) = @_; my ($self) = @_;
my $channel_datas = eval { my $channel_datas = eval {
my $sth = $self->{dbh}->prepare('SELECT id, channel, enter_abuses FROM Channels WHERE enter_abuses > 0'); my $sth = $self->{dbh}->prepare('SELECT id, channel, enter_abuses, last_offense FROM Channels WHERE enter_abuses > 0');
$sth->execute(); $sth->execute();
return $sth->fetchall_arrayref({}); return $sth->fetchall_arrayref({});
}; };
@ -655,6 +659,107 @@ sub devalidate_all_channels {
$self->{pbot}->{logger}->log($@) if $@; $self->{pbot}->{logger}->log($@) if $@;
} }
sub get_also_known_as {
my ($self, $nick) = @_;
$self->{pbot}->{logger}->log("Looking for AKAs for nick [$nick]\n");
my @list = eval {
my %aka_hostmasks;
my $sth = $self->{dbh}->prepare('SELECT hostmask FROM Hostmasks WHERE hostmask LIKE ? ESCAPE "\" ORDER BY last_seen DESC');
my $qnick = quotemeta $nick;
$sth->bind_param(1, "$qnick!%");
$sth->execute();
my $rows = $sth->fetchall_arrayref({});
my %hostmasks;
foreach my $row (@$rows) {
$hostmasks{$row->{hostmask}} = $row->{hostmask};
$self->{pbot}->{logger}->log("Found matching nick for hostmask $row->{hostmask}\n");
}
my %ids;
foreach my $hostmask (keys %hostmasks) {
my $id = $self->get_message_account_id($hostmask);
next if exists $ids{$id};
$ids{$id} = $id;
$sth = $self->{dbh}->prepare('SELECT hostmask FROM Hostmasks WHERE id == ?');
$sth->bind_param(1, $id);
$sth->execute();
$rows = $sth->fetchall_arrayref({});
foreach my $row (@$rows) {
$aka_hostmasks{$row->{hostmask}} = $row->{hostmask};
$self->{pbot}->{logger}->log("Adding matching id AKA hostmask $row->{hostmask}\n");
$hostmasks{$row->{hostmask}} = $row->{hostmask};
}
}
foreach my $hostmask (keys %hostmasks) {
my ($host) = $hostmask =~ /(\@.*)$/;
$sth = $self->{dbh}->prepare('SELECT id FROM Hostmasks WHERE hostmask LIKE ?');
$sth->bind_param(1, "\%$host");
$sth->execute();
$rows = $sth->fetchall_arrayref({});
foreach my $row (@$rows) {
next if exists $ids{$row->{id}};
$ids{$row->{id}} = $row->{id};
$sth = $self->{dbh}->prepare('SELECT hostmask FROM Hostmasks WHERE id == ?');
$sth->bind_param(1, $row->{id});
$sth->execute();
my $rows = $sth->fetchall_arrayref({});
foreach my $row (@$rows) {
$aka_hostmasks{$row->{hostmask}} = $row->{hostmask};
$self->{pbot}->{logger}->log("Adding matching host AKA hostmask $row->{hostmask}\n");
}
}
}
my %nickservs;
foreach my $id (keys %ids) {
$sth = $self->{dbh}->prepare('SELECT nickserv FROM Nickserv WHERE id == ?');
$sth->bind_param(1, $id);
$sth->execute();
$rows = $sth->fetchall_arrayref({});
foreach my $row (@$rows) {
$nickservs{$row->{nickserv}} = $row->{nickserv};
}
}
foreach my $nickserv (keys %nickservs) {
$sth = $self->{dbh}->prepare('SELECT id FROM Nickserv WHERE nickserv == ?');
$sth->bind_param(1, $nickserv);
$sth->execute();
$rows = $sth->fetchall_arrayref({});
foreach my $row (@$rows) {
next if exists $ids{$row->{id}};
$ids{$row->{id}} = $row->{id};
$sth = $self->{dbh}->prepare('SELECT hostmask FROM Hostmasks WHERE id == ?');
$sth->bind_param(1, $row->{id});
$sth->execute();
my $rows = $sth->fetchall_arrayref({});
foreach my $row (@$rows) {
$aka_hostmasks{$row->{hostmask}} = $row->{hostmask};
$self->{pbot}->{logger}->log("Adding matching nickserv AKA hostmask $row->{hostmask}\n");
}
}
}
return sort keys %aka_hostmasks;
};
$self->{pbot}->{logger}->log($@) if $@;
return @list;
}
# End of public API, the remaining are internal support routines for this module # End of public API, the remaining are internal support routines for this module
sub get_new_account_id { sub get_new_account_id {

View File

@ -13,7 +13,7 @@ use warnings;
# These are set automatically by the build/commit script # These are set automatically by the build/commit script
use constant { use constant {
BUILD_NAME => "PBot", BUILD_NAME => "PBot",
BUILD_REVISION => 730, BUILD_REVISION => 731,
BUILD_DATE => "2014-07-11", BUILD_DATE => "2014-07-11",
}; };