- add ?grant and ?revoke to add/delete users
authorAndreas Scherbaum <andreas@scherbaum.biz>
Sun, 11 Nov 2012 19:04:28 +0000 (20:04 +0100)
committerAndreas Scherbaum <andreas@scherbaum.biz>
Sun, 11 Nov 2012 19:04:28 +0000 (20:04 +0100)
docbot.pl
docbot.translations
todo.txt

index beadd8461cc694230935b7af3913de4de686f33b..23d2acbb92c77a9c88c0a48b3abc94e8b123a266 100755 (executable)
--- a/docbot.pl
+++ b/docbot.pl
@@ -349,6 +349,8 @@ sub init_statistics {
     $main::statistics{'command_counter_lost'}     = 0;
     $main::statistics{'command_counter_url'}      = 0;
     $main::statistics{'command_counter_key'}      = 0;
+    $main::statistics{'command_counter_grant'}    = 0;
+    $main::statistics{'command_counter_revoke'}   = 0;
 
     $main::statistics{'command_access_denied'}    = 0;
 
@@ -1363,6 +1365,10 @@ sub is_valid_admin_command {
         return 1;
     } elsif ($command eq 'quit') {
         return 1;
+    } elsif ($command eq 'grant') {
+        return 1;
+    } elsif ($command eq 'revoke') {
+        return 1;
     }
 
     return 0;
@@ -1939,12 +1945,218 @@ sub handle_command {
         when('quit') {
             return handle_command_quit($command, $string, $mode, $kernel, $heap, $who, $nick, $where, $msg, $sender, $irc, $channel);
         }
+        when('grant') {
+            return handle_command_grant($command, $string, $mode, $kernel, $heap, $who, $nick, $where, $msg, $sender, $irc, $channel);
+        }
+        when('revoke') {
+            return handle_command_revoke($command, $string, $mode, $kernel, $heap, $who, $nick, $where, $msg, $sender, $irc, $channel);
+        }
     }
 
     return '';
 }
 
 
+# handle_command_grant()
+#
+# command handler for the 'grant' command
+#
+# parameter:
+#  - the command (lower case)
+#  - the parameter string (may be empty)
+#  - the command mode (admin/operator/user)
+#  - POE kernel
+#  - POE heap
+#  - the full who of the message sender, including the nick name
+#  - the nick name of the message sender
+#  - the full origin of the message
+#  - the message itself
+#  - POE sender
+#  - session irc handle
+#  - the channel name
+# return:
+#  - text to send back to the sender
+sub handle_command_grant {
+    my $command = shift;
+    my $string  = shift;
+    my $mode    = shift;
+    my $kernel  = shift;
+    my $heap    = shift;
+    my $who     = shift;
+    my $nick    = shift;
+    my $where   = shift;
+    my $msg     = shift;
+    my $sender  = shift;
+    my $irc     = shift;
+    my $channel = shift;
+
+
+    # 'grant' goes to the command channel only
+    if (lc($channel) eq lc($irc->nick_name())) {
+        return 'The "grant" command is only allowed in the command channel';
+    }
+    if (lc($channel) ne lc(config_get_key2('bot', 'commandchannel'))) {
+        return 'The "grant" command is only allowed in the command channel';
+    }
+
+    if (length($string) < 1) {
+        my $answer = 'The "grant" command requires two parameters';
+           $answer = translate_text_for_channel($channel, 'error_grant_command_parameter', $answer);
+        return $answer;
+    }
+
+    # remove spaces at beginning and end
+    $string =~ s/^[\s\t]+//gs;
+    $string =~ s/[\s\t]+$//gs;
+
+    my ($msg_nick, $msg_level);
+    if ($string =~ /^([^\s]+)\s+(.+)$/) {
+        $msg_nick  = $1;
+        $msg_level = $2;
+    } else {
+        my $answer = 'The "grant" command requires two parameters';
+           $answer = translate_text_for_channel($channel, 'error_grant_command_parameter', $answer);
+        return $answer;
+    }
+
+
+    if ($msg_level ne 'op' and $msg_level ne 'admin') {
+        my $answer = 'The second parameter must be "op" or "admin"';
+           $answer = translate_text_for_channel($channel, 'error_grant_second_parameter', $answer);
+        return $answer;
+    }
+
+
+    print_msg("grant: '$msg_nick/$msg_level', by $nick", DEBUG);
+    send_to_commandchannel("grant: '$msg_nick/$msg_level', by $nick");
+
+    $main::statistics{'command_counter_grant'}++;
+
+
+    my $query = "SELECT u_nick, u_role FROM docbot_user WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+    my $st    = $main::db->query($query, $msg_nick);
+    if (!defined($st)) {
+        my $answer = "Database error";
+           $answer = translate_text_for_channel($channel, 'database_error', $answer);
+        return $answer;
+    }
+    my $rows = $st->rows;
+    if ($rows == 0) {
+        # user not yet in database
+        $query = "INSERT INTO docbot_user (u_nick, u_role, u_reason) VALUES (LOWER(?::TEXT), ?::TEXT, ?::TEXT)";
+        $st    = $main::db->query($query, $msg_nick, $msg_level, 'Granted by ' . $nick);
+        if (!defined($st)) {
+            my $answer = "Database error";
+               $answer = translate_text_for_channel($channel, 'database_error', $answer);
+            return $answer;
+        }
+        my $answer = "User added";
+           $answer = translate_text_for_channel($channel, 'error_grant_user_added', $answer);
+        return $answer;
+    } else {
+        # user already in database, compare level
+        my $row = $st->fetchrow_hashref;
+        if ($row->{'u_role'} eq $msg_level) {
+            my $answer = "User already in database with requested level";
+               $answer = translate_text_for_channel($channel, 'error_grant_user_has_level', $answer);
+            return $answer;
+        } else {
+            $query = "UPDATE docbot_user SET u_role = ?::TEXT, u_reaeson = ?::TEXT WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+            $st    = $main::db->query($query, $msg_level, 'Granted/changed by ' . $nick, $msg_nick);
+            if (!defined($st)) {
+                my $answer = "Database error";
+                   $answer = translate_text_for_channel($channel, 'database_error', $answer);
+                return $answer;
+            }
+            my $answer = "User changed";
+               $answer = translate_text_for_channel($channel, 'error_grant_user_canged', $answer);
+            return $answer;
+        }
+    }
+}
+
+
+# handle_command_revoke()
+#
+# command handler for the 'revoke' command
+#
+# parameter:
+#  - the command (lower case)
+#  - the parameter string (may be empty)
+#  - the command mode (admin/operator/user)
+#  - POE kernel
+#  - POE heap
+#  - the full who of the message sender, including the nick name
+#  - the nick name of the message sender
+#  - the full origin of the message
+#  - the message itself
+#  - POE sender
+#  - session irc handle
+#  - the channel name
+# return:
+#  - text to send back to the sender
+sub handle_command_revoke {
+    my $command = shift;
+    my $string  = shift;
+    my $mode    = shift;
+    my $kernel  = shift;
+    my $heap    = shift;
+    my $who     = shift;
+    my $nick    = shift;
+    my $where   = shift;
+    my $msg     = shift;
+    my $sender  = shift;
+    my $irc     = shift;
+    my $channel = shift;
+
+
+    # 'grant' goes to the command channel only
+    if (lc($channel) eq lc($irc->nick_name())) {
+        return 'The "revoke" command is only allowed in the command channel';
+    }
+    if (lc($channel) ne lc(config_get_key2('bot', 'commandchannel'))) {
+        return 'The "revoke" command is only allowed in the command channel';
+    }
+
+    if (length($string) < 1) {
+        my $answer = 'The "revoke" command requires one parameter';
+           $answer = translate_text_for_channel($channel, 'error_revoke_command_parameter', $answer);
+        return $answer;
+    }
+
+    # remove spaces at beginning and end
+    $string =~ s/^[\s\t]+//gs;
+    $string =~ s/[\s\t]+$//gs;
+
+
+    print_msg("revoke: '$string', by $nick", DEBUG);
+    send_to_commandchannel("revoke: '$string', by $nick");
+
+    $main::statistics{'command_counter_revoke'}++;
+
+
+    my $query = "DELETE FROM docbot_user WHERE LOWER(u_nick) = LOWER(?::TEXT)";
+    my $st    = $main::db->query($query, $string);
+    if (!defined($st)) {
+        my $answer = "Database error";
+           $answer = translate_text_for_channel($channel, 'database_error', $answer);
+        return $answer;
+    }
+    my $rows = $st->rows;
+    if ($rows == 0) {
+        # user not in database
+        my $answer = "User not in database";
+           $answer = translate_text_for_channel($channel, 'error_revoke_user_not_in_db', $answer);
+        return $answer;
+    } else {
+        # user now removed
+        my $answer = "User removed from database";
+           $answer = translate_text_for_channel($channel, 'error_revoke_user_removed_from_db', $answer);
+        return $answer;
+    }
+}
+
+
 # handle_command_quit()
 #
 # command handler for the 'quit' command
@@ -2078,6 +2290,8 @@ sub handle_command_status {
     push(@commands, 'lost: ' .     $main::statistics{'command_counter_lost'});
     push(@commands, 'url: ' .      $main::statistics{'command_counter_url'});
     push(@commands, 'key: ' .      $main::statistics{'command_counter_key'});
+    push(@commands, 'grant: ' .    $main::statistics{'command_counter_grant'});
+    push(@commands, 'revoke: ' .   $main::statistics{'command_counter_revoke'});
     # don't bother to add 'quit' statistic here
     $irc->yield( privmsg => $channel, 'Number of executed IRC commands: ' . join(", ", @commands) );
     $irc->yield( privmsg => $channel, 'Number of denied IRC requests: ' . $main::statistics{'command_access_denied'} );
@@ -3083,6 +3297,18 @@ sub handle_command_help {
         $irc->yield( privmsg => $replyto, $answer );
     }
 
+    if ($string eq 'grant') {
+        my $answer = "Use ?grant <nick> <op/admin>";
+           $answer = translate_text_for_channel($replyto, 'help_general_line_grant', $answer);
+        $irc->yield( privmsg => $replyto, $answer );
+    }
+
+    if ($string eq 'revoke') {
+        my $answer = "Use ?revoke <nick>";
+           $answer = translate_text_for_channel($replyto, 'help_general_line_revoke', $answer);
+        $irc->yield( privmsg => $replyto, $answer );
+    }
+
     return '';
 }
 
index fc81e7af619035885b05109dcd63e706ab330aeb..e4790797e109160d7f5466be42bdca359f321840 100644 (file)
@@ -35,6 +35,14 @@ translations:
     error_key_command_parameter: 'Der "key" Befehl erfordert einen Parameter'
     wallchan_command_message: 'Nachricht vom Operator'
     error_say_command_parameter: 'Der "say" Befehl erfordert zwei Parameter'
+    error_grant_command_parameter: 'Der "grant" Befehl erfordert zwei Parameter'
+    error_grant_second_parameter: 'Der zweite Parameter muss "op" oder "admin" sein'
+    error_grant_user_has_level: 'Dieser Benutzer ist bereits mit diesem Level in der Datenbank eingetragen'
+    error_grant_user_added: 'Benutzer addiert'
+    error_grant_user_canged: 'Benutzer geƤndert'
+    error_revoke_command_parameter: 'Der "revoke" Befehl erfordert einen Parameter'
+    error_revoke_user_not_in_db: 'Benutzer nicht in Datenbank'
+    error_revoke_user_removed_from_db: 'Benutzer aus Datenbank entfernt'
     error_say_not_joined: 'Der Bot ist nicht in diesem Channel'
     error_join_command_parameter: 'Der "join" Befehl erfordert zwei Parameter'
     error_join_already_joined: 'Der Bot ist bereits in diesem Channel'
@@ -50,6 +58,8 @@ translations:
     help_general_line_quit: 'Nutze: ?quit'
     help_general_line_join: 'Nutze: ?join <Channel name> <Session Nummer> lang:<Sprache> pass:<Channel Passwort>'
     help_general_line_leave: 'Nutze: ?leave'
+    help_general_line_grant: 'Nutze: ?grant <Nick> <op/admin>'
+    help_general_line_revoke: 'Nutze: ?revoke <Nick>'
     lost_only_in_commandchannel: 'Der "lost" Befehl ist nur im Adminchannel erlaubt'
     url_only_in_commandchannel: 'Der "url" Befehl ist nur im Adminchannel erlaubt'
     key_only_in_commandchannel: 'Der "key" Befehl ist nur im Adminchannel erlaubt'
index a70dddc140802cb960ebd8aeb2dc1575d33ca886..ededa7c6a6775dbf3ded6f45d8dc3fc58cf3513b 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -11,7 +11,6 @@
 - add "?restart" command
 - user management through irc commands (add/remove/list/search users)
 - save last user/nick interaction time
-- add ?grant and ?revoke to add/delete users
 - ?status should know the status of each connection
   - including the last time the connection has seen traffic
 - history per channel
@@ -46,3 +45,4 @@
 - nickserv handling (passwords) OK
 - post important commands into commandchannel OK
 - add Nagios check for the PostgreSQL infrastructure check
+- add ?grant and ?revoke to add/delete users