From 44b737a8c31f411ce3d7da302641466ee2b77446 Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Tue, 25 Jan 2011 22:40:22 +0000 Subject: [PATCH] factoids: allow factset/factunset by regular users; factset/factunset now has list of metadata levels, and does ownership checking; added action_with_args metadata field to be substituted for action if factoid triggered with arguments --- PBot/FactoidCommands.pm | 85 +++++++++++++++++++++++++++++++++++++++-- PBot/Factoids.pm | 19 ++++----- PBot/VERSION.pm | 4 +- 3 files changed, 94 insertions(+), 14 deletions(-) diff --git a/PBot/FactoidCommands.pm b/PBot/FactoidCommands.pm index a0f5de3b..b9b2ae55 100644 --- a/PBot/FactoidCommands.pm +++ b/PBot/FactoidCommands.pm @@ -27,6 +27,21 @@ sub new { return $self; } +# TODO - move this someplace better so it can be more accessible to user-customisation +my %factoid_metadata_levels = ( + created_on => 999, + enabled => 10, + last_referenced_in => 60, + last_referenced_on => 60, + modulelauncher_subpattern => 60, + owner => 60, + rate_limit => 10, + ref_count => 60, + ref_user => 60, + type => 60, + # all others are allowed to be factset by anybody/default to level 0 +); + sub initialize { my ($self, %conf) = @_; @@ -43,8 +58,8 @@ sub initialize { $pbot->commands->register(sub { return $self->factrem(@_) }, "factrem", 0); $pbot->commands->register(sub { return $self->factshow(@_) }, "factshow", 0); $pbot->commands->register(sub { return $self->factinfo(@_) }, "factinfo", 0); - $pbot->commands->register(sub { return $self->factset(@_) }, "factset", 10); - $pbot->commands->register(sub { return $self->factunset(@_) }, "factunset", 10); + $pbot->commands->register(sub { return $self->factset(@_) }, "factset", 0); + $pbot->commands->register(sub { return $self->factunset(@_) }, "factunset", 0); $pbot->commands->register(sub { return $self->factchange(@_) }, "factchange", 0); $pbot->commands->register(sub { return $self->factalias(@_) }, "factalias", 0); $pbot->commands->register(sub { return $self->call_factoid(@_) }, "fact", 0); @@ -90,6 +105,39 @@ sub factset { return "Usage: factset [key ]" } + my $admininfo = $self->{pbot}->admins->loggedin($from, "$nick!$user\@$host"); + + my $level = 0; + my $meta_level = 0; + + if(defined $admininfo) { + $level = $admininfo->{level}; + } + + if(defined $key) { + if(defined $factoid_metadata_levels{$key}) { + $meta_level = $factoid_metadata_levels{$key}; + } + + if($meta_level > 0) { + if($level == 0) { + return "You must login to set '$key'"; + } elsif($level < $meta_level) { + return "You must be at least level $meta_level to set '$key'"; + } + } + } + + my ($owner_channel, $owner_trigger) = $self->{pbot}->factoids->find_factoid($channel, $trigger, undef, 1); + + if(defined $owner_channel) { + my $factoid = $self->{pbot}->factoids->factoids->hash->{$owner_channel}->{$owner_trigger}; + + if(lc $nick ne lc $factoid->{'owner'} and $level == 0) { + return "You are not the owner of $trigger."; + } + } + return $self->{pbot}->factoids->factoids->set($channel, $trigger, $key, $value); } @@ -98,10 +146,41 @@ sub factunset { my ($from, $nick, $user, $host, $arguments) = @_; my ($channel, $trigger, $key) = split / /, $arguments, 3 if defined $arguments; - if(not defined $channel or not defined $trigger) { + if(not defined $channel or not defined $trigger or not defined $key) { return "Usage: factunset " } + my $admininfo = $self->{pbot}->admins->loggedin($from, "$nick!$user\@$host"); + + my $level = 0; + my $meta_level = 0; + + if(defined $admininfo) { + $level = $admininfo->{level}; + } + + if(defined $factoid_metadata_levels{$key}) { + $meta_level = $factoid_metadata_levels{$key}; + } + + if($meta_level > 0) { + if($level == 0) { + return "You must login to unset '$key'"; + } elsif($level < $meta_level) { + return "You must be at least level $meta_level to unset '$key'"; + } + } + + my ($owner_channel, $owner_trigger) = $self->{pbot}->factoids->find_factoid($channel, $trigger, undef, 1); + + if(defined $owner_channel) { + my $factoid = $self->{pbot}->factoids->factoids->hash->{$owner_channel}->{$owner_trigger}; + + if(lc $nick ne lc $factoid->{'owner'} and $level == 0) { + return "You are not the owner of $trigger."; + } + } + return $self->{pbot}->factoids->factoids->unset($channel, $trigger, $key); } diff --git a/PBot/Factoids.pm b/PBot/Factoids.pm index 82d87ace..a9688edc 100644 --- a/PBot/Factoids.pm +++ b/PBot/Factoids.pm @@ -205,9 +205,6 @@ sub interpreter { $from = lc $from; - # (COMMENTED OUT) remove trailing comma or colon from keyword if keyword has other characters beforehand - # $keyword =~ s/^(.+)[:,]$/$1/; - return undef if not length $keyword; my $original_keyword = $keyword; @@ -232,7 +229,7 @@ sub interpreter { $command = $1; } - $pbot->logger->log("[" . (defined $from ? $from : "(undef)") . "] ($nick!$user\@$host) [$keyword] aliased to: [$command]\n"); + $pbot->logger->log("[" . (defined $from ? $from : "stdin") . "] ($nick!$user\@$host) [$keyword] aliased to: [$command]\n"); $self->factoids->hash->{$channel}->{$keyword}->{ref_count}++; $self->factoids->hash->{$channel}->{$keyword}->{ref_user} = $nick; @@ -274,7 +271,7 @@ sub interpreter { # Don't allow user-custom /msg factoids, unless factoid triggered by admin if(($self->factoids->hash->{$channel}->{$keyword}->{action} =~ m/^\/msg/i) and (not $self->{pbot}->admins->loggedin($from, "$nick!$user\@$host"))) { - $self->{pbot}->logger->log("[HACK] Bad factoid (contains /msg): " . $self->factoids->hash->{$channel}->{$keyword}->{action} . "\n"); + $self->{pbot}->logger->log("[ABUSE] Bad factoid (contains /msg): " . $self->factoids->hash->{$channel}->{$keyword}->{action} . "\n"); return "You must login to use this command." } @@ -299,21 +296,25 @@ sub interpreter { $result = "/msg $tonick $fromnick$keyword is $result"; } - $self->{pbot}->logger->log("text set to [$result]\n"); + $self->{pbot}->logger->log("result set to [$result]\n"); } else { $result = $self->factoids->hash->{$channel}->{$keyword}->{action}; } if(defined $arguments) { - # TODO - extract and remove $tonick from end of $arguments + if(exists $self->factoids->hash->{$channel}->{$keyword}->{action_with_args}) { + $result = $self->factoids->hash->{$channel}->{$keyword}->{action_with_args}; + } + if(not $result =~ s/\$args/$arguments/gi) { - # factoid doesn't take an argument + # factoid doesn't take an argument, so assume argument is a nick if it is a single-word 20 characters or less + # TODO - maintain list of channel nicks and compare against this list to ensure nick exists if($arguments =~ /^[^ ]{1,20}$/) { # might be a nick if($result =~ /^\/.+? /) { $result =~ s/^(\/.+?) /$1 $arguments: /; } else { - $result =~ s/^/\/say $arguments: $keyword is / unless (defined $tonick); + $result =~ s/^/\/say $arguments: $keyword is / unless defined $tonick; } } else { # return undef; diff --git a/PBot/VERSION.pm b/PBot/VERSION.pm index 0cadb303..903d4e97 100644 --- a/PBot/VERSION.pm +++ b/PBot/VERSION.pm @@ -13,8 +13,8 @@ use warnings; # These are set automatically by the build/commit script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 252, - BUILD_DATE => "2011-01-24", + BUILD_REVISION => 253, + BUILD_DATE => "2011-01-25", }; 1;