3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-29 23:39:24 +01:00
pbot/PBot/Admins.pm

212 lines
6.2 KiB
Perl
Raw Normal View History

2020-01-21 00:25:26 +01:00
# File: Admins.pm
# Author: pragma_
#
# Purpose: Manages list of bot admins and whether they are logged in.
License project under MPL2 This patch adds the file LICENSE which is the verbatim copy of the Mozilla Public License Version 2.0 as retreived from https://www.mozilla.org/media/MPL/2.0/index.815ca599c9df.txt on 2017-03-05. This patch also places license headers for the MPL2 type A variant of the license header in the following files: PBot/AntiFlood.pm PBot/BanTracker.pm PBot/BlackList.pm PBot/BotAdminCommands.pm PBot/BotAdmins.pm PBot/ChanOpCommands.pm PBot/ChanOps.pm PBot/Channels.pm PBot/Commands.pm PBot/DualIndexHashObject.pm PBot/EventDispatcher.pm PBot/FactoidCommands.pm PBot/FactoidModuleLauncher.pm PBot/Factoids.pm PBot/HashObject.pm PBot/IRCHandlers.pm PBot/IgnoreList.pm PBot/IgnoreListCommands.pm PBot/Interpreter.pm PBot/LagChecker.pm PBot/Logger.pm PBot/MessageHistory.pm PBot/MessageHistory_SQLite.pm PBot/NickList.pm PBot/PBot.pm PBot/Plugins.pm PBot/Plugins/AntiAway.pm PBot/Plugins/AntiKickAutoRejoin.pm PBot/Plugins/AntiRepeat.pm PBot/Plugins/AntiTwitter.pm PBot/Plugins/AutoRejoin.pm PBot/Plugins/Counter.pm PBot/Plugins/Quotegrabs.pm PBot/Plugins/Quotegrabs/Quotegrabs_Hashtable.pm PBot/Plugins/Quotegrabs/Quotegrabs_SQLite.pm PBot/Plugins/UrlTitles.pm PBot/Plugins/_Example.pm PBot/Refresher.pm PBot/Registerable.pm PBot/Registry.pm PBot/RegistryCommands.pm PBot/SQLiteLogger.pm PBot/SQLiteLoggerLayer.pm PBot/SelectHandler.pm PBot/StdinReader.pm PBot/Timer.pm PBot/Utils/ParseDate.pm PBot/VERSION.pm build/update-version.pl modules/acronym.pl modules/ago.pl modules/c11std.pl modules/c2english.pl modules/c2english/CGrammar.pm modules/c2english/c2eng.pl modules/c99std.pl modules/cdecl.pl modules/cfaq.pl modules/cjeopardy/IRCColors.pm modules/cjeopardy/QStatskeeper.pm modules/cjeopardy/Scorekeeper.pm modules/cjeopardy/cjeopardy.pl modules/cjeopardy/cjeopardy_answer.pl modules/cjeopardy/cjeopardy_filter.pl modules/cjeopardy/cjeopardy_hint.pl modules/cjeopardy/cjeopardy_qstats.pl modules/cjeopardy/cjeopardy_scores.pl modules/cjeopardy/cjeopardy_show.pl modules/codepad.pl modules/compiler_block.pl modules/compiler_client.pl modules/compiler_vm/Diff.pm modules/compiler_vm/cc modules/compiler_vm/compiler_client.pl modules/compiler_vm/compiler_server.pl modules/compiler_vm/compiler_server_vbox_win32.pl modules/compiler_vm/compiler_server_watchdog.pl modules/compiler_vm/compiler_vm_client.pl modules/compiler_vm/compiler_vm_server.pl modules/compiler_vm/compiler_watchdog.pl modules/compiler_vm/languages/_c_base.pm modules/compiler_vm/languages/_default.pm modules/compiler_vm/languages/bash.pm modules/compiler_vm/languages/bc.pm modules/compiler_vm/languages/bf.pm modules/compiler_vm/languages/c11.pm modules/compiler_vm/languages/c89.pm modules/compiler_vm/languages/c99.pm modules/compiler_vm/languages/clang.pm modules/compiler_vm/languages/clang11.pm modules/compiler_vm/languages/clang89.pm modules/compiler_vm/languages/clang99.pm modules/compiler_vm/languages/clangpp.pm modules/compiler_vm/languages/clisp.pm modules/compiler_vm/languages/cpp.pm modules/compiler_vm/languages/freebasic.pm modules/compiler_vm/languages/go.pm modules/compiler_vm/languages/haskell.pm modules/compiler_vm/languages/java.pm modules/compiler_vm/languages/javascript.pm modules/compiler_vm/languages/ksh.pm modules/compiler_vm/languages/lua.pm modules/compiler_vm/languages/perl.pm modules/compiler_vm/languages/python.pm modules/compiler_vm/languages/python3.pm modules/compiler_vm/languages/qbasic.pm modules/compiler_vm/languages/scheme.pm modules/compiler_vm/languages/server/_c_base.pm modules/compiler_vm/languages/server/_default.pm modules/compiler_vm/languages/server/c11.pm modules/compiler_vm/languages/server/c89.pm modules/compiler_vm/languages/server/c99.pm modules/compiler_vm/languages/server/clang.pm modules/compiler_vm/languages/server/clang11.pm modules/compiler_vm/languages/server/clang89.pm modules/compiler_vm/languages/server/clang99.pm modules/compiler_vm/languages/server/cpp.pm modules/compiler_vm/languages/server/freebasic.pm modules/compiler_vm/languages/server/haskell.pm modules/compiler_vm/languages/server/java.pm modules/compiler_vm/languages/server/qbasic.pm modules/compiler_vm/languages/server/tendra.pm modules/compiler_vm/languages/sh.pm modules/compiler_vm/languages/tendra.pm modules/compliment modules/cstd.pl modules/define.pl modules/dice_roll.pl modules/excuse.sh modules/expand_macros.pl modules/fnord.pl modules/funnyish_quote.pl modules/g.pl modules/gdefine.pl modules/gen_cfacts.pl modules/gencstd.pl modules/get_title.pl modules/getcfact.pl modules/google.pl modules/gspy.pl modules/gtop10.pl modules/gtop15.pl modules/headlines.pl modules/horoscope modules/horrorscope modules/ideone.pl modules/insult.pl modules/love_quote.pl modules/man.pl modules/map.pl modules/math.pl modules/prototype.pl modules/qalc.pl modules/random_quote.pl modules/seen.pl modules/urban modules/weather.pl modules/wikipedia.pl pbot.pl pbot.sh It is highly recommended that this list of files is reviewed to ensure that all files are the copyright of the sole maintainer of the repository. If any files with license headers contain the intellectual property of anyone else, it is recommended that a request is made to revise this patch or that the explicit permission of the co-author is gained to allow for the license of the work to be changed. I (Tomasz Kramkowski), the contributor, take no responsibility for any legal action taken against the maintainer of this repository for incorrectly claiming copyright to any work not owned by the maintainer of this repository.
2017-03-05 22:33:31 +01:00
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
2020-01-21 00:25:26 +01:00
package PBot::Admins;
use warnings;
use strict;
2019-07-11 03:40:53 +02:00
use feature 'unicode_strings';
use PBot::DualIndexHashObject;
2020-01-21 00:25:26 +01:00
use PBot::AdminCommands;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
$self->{admins} = PBot::DualIndexHashObject->new(name => 'Admins', filename => $conf{filename}, pbot => $conf{pbot});
$self->load_admins;
$self->{pbot}->{event_dispatcher}->register_handler('irc.join', sub { $self->on_join(@_) });
$self->{commands} = PBot::AdminCommands->new(pbot => $conf{pbot});
}
sub on_join {
my ($self, $event_type, $event) = @_;
my ($nick, $user, $host, $channel) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->to);
($nick, $user, $host) = $self->{pbot}->{irchandlers}->normalize_hostmask($nick, $user, $host);
my $admin = $self->find_admin($channel, "$nick!$user\@$host");
if (defined $admin) {
if ($self->{pbot}->{chanops}->can_gain_ops($channel)) {
my $modes = '+';
my $targets = '';
if ($admin->{autoop}) {
$self->{pbot}->{logger}->log("[admin] $nick!$user\@$host autoop in $channel\n");
$modes .= 'o';
$targets .= "$nick ";
}
if ($admin->{autovoice}) {
$self->{pbot}->{logger}->log("[admin] $nick!$user\@$host autovoice in $channel\n");
$modes .= 'v';
$targets .= "$nick ";
}
if (length $modes > 1) {
$self->{pbot}->{chanops}->add_op_command($channel, "mode $channel $modes $targets");
$self->{pbot}->{chanops}->gain_ops($channel);
}
}
if ($admin->{autologin}) {
$self->{pbot}->{logger}->log("[admin] $nick!$user\@$host autologin to $admin->{name} ($admin->{level}) for $channel\n");
$admin->{loggedin} = 1;
}
}
return 0;
}
sub add_admin {
my $self = shift;
my ($name, $channel, $hostmask, $level, $password, $dont_save) = @_;
$channel = '.*' if $channel !~ m/^#/;
my $data = {
name => $name,
level => $level,
password => $password
};
$self->{pbot}->{logger}->log("Adding new level $level admin: [$name] [$hostmask] for channel [$channel]\n");
$self->{admins}->add($channel, $hostmask, $data, $dont_save);
}
sub remove_admin {
my $self = shift;
my ($channel, $hostmask) = @_;
return $self->{admins}->remove($channel, $hostmask);
}
sub load_admins {
my $self = shift;
my $filename;
if (@_) { $filename = shift; } else { $filename = $self->{admins}->{filename}; }
if (not defined $filename) {
Carp::carp "No admins path specified -- skipping loading of admins";
return;
}
$self->{admins}->load;
2019-06-26 18:34:19 +02:00
my $i = 0;
foreach my $channel (sort keys %{ $self->{admins}->{hash} } ) {
foreach my $hostmask (sort keys %{ $self->{admins}->{hash}->{$channel} }) {
next if $hostmask eq '_name';
$i++;
my $name = $self->{admins}->{hash}->{$channel}->{$hostmask}->{name};
my $level = $self->{admins}->{hash}->{$channel}->{$hostmask}->{level};
my $password = $self->{admins}->{hash}->{$channel}->{$hostmask}->{password};
if (not defined $name or not defined $level or not defined $password) {
Carp::croak "An admin in $filename is missing critical data\n";
}
my $chan = $channel eq '.*' ? 'global' : $channel;
$self->{pbot}->{logger}->log("Adding new level $level $chan admin: $name $hostmask\n");
}
}
$self->{pbot}->{logger}->log(" $i admins loaded.\n");
}
sub save_admins {
my $self = shift;
$self->{admins}->save;
}
sub find_admin {
my ($self, $from, $hostmask) = @_;
$from = $self->{pbot}->{registry}->get_value('irc', 'botnick') if not defined $from;
$hostmask = '.*' if not defined $hostmask;
$hostmask = lc $hostmask;
my $result = eval {
foreach my $channel_regex (keys %{ $self->{admins}->{hash} }) {
if ($from !~ m/^#/ or $from =~ m/^$channel_regex$/i) {
foreach my $hostmask_regex (keys %{ $self->{admins}->{hash}->{$channel_regex} }) {
next if $hostmask_regex eq '_name';
if ($hostmask_regex =~ m/[*?]/) {
# contains * or ? so it's converted to a regex
my $hostmask_quoted = quotemeta $hostmask_regex;
$hostmask_quoted =~ s/\\\*/.*?/g;
$hostmask_quoted =~ s/\\\?/./g;
return $self->{admins}->{hash}->{$channel_regex}->{$hostmask_regex} if $hostmask =~ m/^$hostmask_quoted$/i;
} else {
# direct comparison
return $self->{admins}->{hash}->{$channel_regex}->{$hostmask_regex} if $hostmask eq lc $hostmask_regex;
}
}
}
}
return undef;
};
if ($@) {
$self->{pbot}->{logger}->log("Error in find_admin parameters: $@\n");
}
return $result;
}
sub loggedin {
my ($self, $channel, $hostmask) = @_;
my $admin = $self->find_admin($channel, $hostmask);
if (defined $admin && $admin->{loggedin}) {
return $admin;
} else {
return undef;
}
}
sub login {
my ($self, $channel, $hostmask, $password) = @_;
my $admin = $self->find_admin($channel, $hostmask);
if (not defined $admin) {
$self->{pbot}->{logger}->log("Attempt to login non-existent [$channel][$hostmask] failed\n");
return "You do not have an account in $channel.";
}
if ($admin->{password} ne $password) {
$self->{pbot}->{logger}->log("Bad login password for [$channel][$hostmask]\n");
return "I don't think so.";
}
$admin->{loggedin} = 1;
$self->{pbot}->{logger}->log("$hostmask logged into $channel\n");
return "Logged into $channel.";
}
sub logout {
my ($self, $channel, $hostmask) = @_;
my $admin = $self->find_admin($channel, $hostmask);
delete $admin->{loggedin} if defined $admin;
}
1;