Annotation of ChivanetModcon/modcon, revision 1.2

1.1       snw         1: #!/usr/bin/env perl
                      2: 
                      3: #
                      4: # ChivaNet Moderator Console
                      5: #  Copyright (C) 2025 Coherent Logic Development LLC
                      6: #
1.2     ! snw         7: # $Id: modcon,v 1.1.1.1 2025/01/30 19:16:06 snw Exp $
1.1       snw         8: #
                      9: # Author: Serena Willis <snw@coherent-logic.com>
                     10: #
                     11: # Licensed AGPL-3.0
                     12: #
1.2     ! snw        13: # $Log: modcon,v $
        !            14: # Revision 1.1.1.1  2025/01/30 19:16:06  snw
        !            15: # Initial commit
        !            16: #
1.1       snw        17: #
                     18: 
                     19: use REST::Client;
                     20: use JSON;
                     21: use Getopt::Long;
                     22: use Data::Dumper;
                     23: use Term::ReadKey;
                     24: 
                     25: my $rasurl = '';
                     26: my $apikey = '';
                     27: my $online = 0;
                     28: my $modcon_version = '0.0.1';
                     29: my $cnclient = '';
                     30: my $rasclient = '';
                     31: 
                     32: my $wchar = '';
                     33: my $hchar = '';
                     34: my $wpixels = '';
                     35: my $hpixels = '';
                     36: 
1.2     ! snw        37: my $account = '';
        !            38: 
1.1       snw        39: sub list_sso_users {
                     40:     $cnclient->GET("/chivanet/users");
                     41:     my $ct = 0;
                     42:     
                     43:     my $json = $cnclient->responseContent();
                     44:     my $hashref = decode_json($json);
                     45: 
                     46:     if($hashref->{ok} == 1) {
                     47:         my $arrayref = $hashref->{users};
                     48:         my @users = sort(@{$arrayref});
                     49:         
                     50:         foreach my $user (@users) {
                     51:             print "$user\n";
                     52:             $ct = $ct + 1;
                     53: 
                     54:             if($ct > $hchar - 2) {
                     55:                 print "ENTER to continue, Q to quit...";
                     56:                 my $resp = <STDIN>;
                     57:                 chomp($resp);
                     58:                 if($resp eq "Q") {
                     59:                     return;
                     60:                 }
                     61:                 elsif($resp eq "q") {
                     62:                     return;
                     63:                 }
                     64:                 $ct = 0;
                     65:             }
                     66:         }
                     67:     }
                     68:     else {
                     69:         print "RPC error\n";
                     70:     }
                     71: }
                     72: 
                     73: sub list_ras_users {
                     74: 
                     75: }
                     76: 
1.2     ! snw        77: sub select_sso_user {
        !            78:     my($id) = @_;
        !            79: 
        !            80:     $cnclient->GET("/chivanet/validate_user?id=$id");
        !            81:     my $json = $cnclient->responseContent();
        !            82:     my $hashref = decode_json($json);
        !            83: 
        !            84:     #print Dumper($hashref);
        !            85:     
        !            86:     if($hashref->{exists} == 1) {
        !            87: 
        !            88:         $cnclient->GET("/chivanet/user?id=$id");
        !            89:         my $json = $cnclient->responseContent();
        !            90:         $account = decode_json($json);
        !            91:         
        !            92:         return $id;
        !            93:     }
        !            94:     else {
        !            95:         print ">>> invalid SSO user $id [$hashref->{error}]\n";
        !            96:         return "---";
        !            97:     }
        !            98:             
        !            99: }
        !           100: 
        !           101: sub select_ras_user {
        !           102:     my($id) = @_;
        !           103: 
        !           104:     $cnclient->GET("/chivanet/validate_sn?id=$id");
        !           105:     my $json = $cnclient->responseContent();
        !           106:     my $hashref = decode_json($json);
        !           107: 
        !           108:     if($hashref->{exists} == 1) {
        !           109:         return $id;
        !           110:     }
        !           111:     else {
        !           112:         print ">>> invalid RAS screen name $id\n";
        !           113:         return "---";
        !           114:     }
        !           115: }
        !           116: 
        !           117: sub trace_ras_sn {
        !           118:     my($user) = @_;
        !           119:     
        !           120:     $cnclient->GET("/chivanet/trace_sn?id=$user");
        !           121:     my $json = $cnclient->responseContent();
        !           122:     my $hashref = decode_json($json);
        !           123:     my $record = $hashref->{account};
        !           124:     my $result = $record->{id};
        !           125:     
        !           126:     print "RAS screen name $user belongs to SSO account $result; switching to SSO mode\n";
        !           127:     return $result;
        !           128:     
        !           129: }
        !           130: 
        !           131: sub list_ras_sessions {
        !           132:     $cnclient->GET("/chivanet/ras_sessions");
        !           133:     my $json = $cnclient->responseContent();
        !           134:     my $hashref = decode_json($json);
        !           135:     my $sessions = $hashref->{sessions};
        !           136:     my $arrayref = $sessions->{sessions};
        !           137:     my $ct = 0;
        !           138:     
        !           139:     foreach my $session (@{$arrayref}) {
        !           140:         print "$session->{screen_name}\n";
        !           141: 
        !           142:         $ct = $ct + 1;
        !           143: 
        !           144:         if($ct > $hchar - 2) {
        !           145:             print "ENTER to continue, Q to quit...";
        !           146:             my $resp = <STDIN>;
        !           147:             chomp($resp);
        !           148:             if($resp eq "Q") {
        !           149:                 return;
        !           150:             }
        !           151:             elsif($resp eq "q") {
        !           152:                 return;
        !           153:             }
        !           154:             $ct = 0;
        !           155:         }
        !           156:     }
        !           157:     
        !           158:     print "$sessions->{count} current sessions\n";
        !           159:     
        !           160: }
        !           161: 
        !           162: sub list_ras_screennames {
        !           163:     my($id) = @_;
        !           164:     
        !           165:     $cnclient->GET("/chivanet/ras_screen_names?id=$id");
        !           166: 
        !           167:     my $json = $cnclient->responseContent();
        !           168:     my $hashref = decode_json($json);
        !           169:     my $arrayref = $hashref->{screen_names};
        !           170:     my $ct = 0;
        !           171:     
        !           172:     foreach my $sn (@{$arrayref}) {
        !           173:         my $name = "$sn->{screen_name}\n";
        !           174:         chomp($name);
        !           175: 
        !           176:         my $bot = '';
        !           177:         my $public = '';
        !           178:         
        !           179:         if($sn->{bot_sn} eq 1) {
        !           180:             $bot = "bot";
        !           181:         }
        !           182:         else {
        !           183:             $bot = "human";
        !           184:         }
        !           185: 
        !           186:         if($sn->{public_sn} eq 1) {
        !           187:             $public = "public";
        !           188:         }
        !           189:         else {
        !           190:             $public = "unlisted";
        !           191:         }
        !           192: 
        !           193:         print "$name:  $public $bot; created $sn->{create_ts}\n";
        !           194:         
        !           195:         $ct = $ct + 1;
        !           196: 
        !           197:         if($ct > $hchar - 2) {
        !           198:             print "ENTER to continue, Q to quit...";
        !           199:             my $resp = <STDIN>;
        !           200:             chomp($resp);
        !           201:             if($resp eq "Q") {
        !           202:                 return;
        !           203:             }
        !           204:             elsif($resp eq "q") {
        !           205:                 return;
        !           206:             }
        !           207:             $ct = 0;
        !           208:         }
        !           209:     }
        !           210: 
        !           211: }
        !           212: 
        !           213: sub print_sso_user {
        !           214:     my $act = $account->{account};
        !           215: 
        !           216:     print "\n";
        !           217:     print "Username          :  $act->{id}\n";
        !           218:     print "Real Name         :  $act->{last_name}, $act->{first_name}\n";
        !           219:     print "Display Name      :  $act->{display_name}\n";
        !           220:     print "Pronouns          :  $act->{pronouns}\n";
        !           221:     print "Profile Image     :  https://chivanet.org$act->{profile_photo}\n";        
        !           222:     print "E-Mail Address    :  $act->{email}\n";
        !           223:     print "Permission Level  :  $act->{perm_level}\n";
        !           224:     print "Created           :  $act->{create_ts}\n";
        !           225:     print "Banned            :  $act->{mod_banned}\n\n";
        !           226: }
        !           227: 
        !           228: sub print_ras_user {
        !           229:     my($id) = @_;
        !           230: 
        !           231:     $cnclient->GET("/chivanet/sn_status?id=$id");
        !           232:     my $json = $cnclient->responseContent();
        !           233:     my $hashref = decode_json($json);
        !           234:     my $status = $hashref->{status};
        !           235:     my $online = "offline";
        !           236:     
        !           237:     if($status->{online} == 1) {        
        !           238:         $online = "online";        
        !           239:     }
        !           240:     
        !           241:     print "\n";
        !           242: 
        !           243: 
        !           244:     if($online eq "online") {
        !           245:         my $sess = $status->{session};
        !           246:         my $service = 'AIM';
        !           247:         
        !           248:         if($sess->{is_icq} == 1) {
        !           249:             $service = 'ICQ';
        !           250:         }
        !           251: 
        !           252:         if($sess->{idle_seconds} > 0) {
        !           253:             $online = "idle";
        !           254:         }
        !           255:         
        !           256:         print "Screen Name       :  $id [$online]\n";
        !           257:         print "Service           :  $service\n";
        !           258:         if($online eq "online") {
        !           259:             print "Time Online (secs):  $sess->{online_seconds}\n";
        !           260:         }
        !           261:         else {
        !           262:             print "Time Idle (secs)  :  $sess->{idle_seconds}\n";
        !           263:         }
        !           264:         print "Away Message      :  $sess->{away_message}\n\n";
        !           265:     }
        !           266:     else {
        !           267:         print "Screen Name       :  $id [$online]\n\n";
        !           268:     }
        !           269:     
        !           270: #    print Dumper($status);
        !           271:     
        !           272: }
        !           273: 
        !           274: sub send_im {
        !           275:     my($user, $msgbody) = @_;
        !           276: 
        !           277:     print "sending message \"$msgbody\" to $user...";   
        !           278:     
        !           279:     my $msg = "<font color=red><strong>[ChivaNet Support]:</strong></font> $msgbody";
        !           280:     
        !           281:     $cnclient->GET("/chivanet/send_im?from=ChivaNet&to=$user&message=$msg");
        !           282:     my $json = $cnclient->responseContent();
        !           283:     my $hashref = decode_json($json);
        !           284:     
        !           285:     if($hashref->{status} == 1) {
        !           286:         print "[OK]\n";
        !           287:     }
        !           288:     else {
        !           289:         print "[FAIL]\n";
        !           290:     }
        !           291: }
        !           292: 
1.1       snw       293: sub prompt {
                    294:     
                    295:     my $rawcmd = '';
1.2     ! snw       296:     my $mode = '---';
1.1       snw       297:     my $user = '---';
                    298: 
                    299:     while (1) {
                    300:         print "MODCON [$mode/$user]> ";
                    301:         my $line = <STDIN>;
                    302:         chomp($line);
                    303:         $rawcmd = $line;
                    304:         
                    305:         my @cmd = split(' ', $rawcmd);
                    306:         
                    307:         if ($cmd[0] eq "quit") {
                    308:             return;
                    309:         }
                    310:         elsif ($cmd[0] eq "mode") {
1.2     ! snw       311:             if($cmd[1] eq "sso") {
1.1       snw       312:                 $mode = "SSO";
                    313:                 $user = "---";
1.2     ! snw       314:                 $account = '';
1.1       snw       315:             }
1.2     ! snw       316:             elsif ($cmd[1] eq "ras") {
1.1       snw       317:                 $mode = "RAS";
                    318:                 $user = "---";
1.2     ! snw       319:                 $account = '';
        !           320:             }
        !           321:             else {
        !           322:                 print "?\n";
        !           323:             }
        !           324:         }
        !           325:         elsif ($cmd[0] eq "select") {
        !           326:             if($cmd[1] eq "user") {
        !           327:                 if($mode eq "SSO") {
        !           328:                     $user = select_sso_user($cmd[2]);                    
        !           329:                     chomp($user);
        !           330:                     print_sso_user;
        !           331:                 }
        !           332:                 elsif($mode eq "RAS") {
        !           333:                     $user = select_ras_user($cmd[2]);
        !           334:                     chomp($user);
        !           335:                     print_ras_user $user;
        !           336:                 }
        !           337:                 else {
        !           338:                     print "?\n";
        !           339:                 }
        !           340:             }            
        !           341:             else {
        !           342:                 print "?\n";
        !           343:             }
        !           344:         }
        !           345:         elsif ($cmd[0] eq "im") {
        !           346:             if($mode eq "RAS") {
        !           347:                 if($user ne "---") {
        !           348:                     my @msga = @cmd[1..$#cmd];
        !           349:                     my $msgbody = join(' ', @msga);                    
        !           350:                     send_im($user, $msgbody);
        !           351:                 }
        !           352:                 else {
        !           353:                     print "?\n";
        !           354:                 }
        !           355:             }
        !           356:             else {
        !           357:                 print "?\n";
        !           358:             }
        !           359:         }    
        !           360:         elsif ($cmd[0] eq "trace") {
        !           361:             if($mode eq "RAS") {
        !           362:                 if($user ne "---") {                    
        !           363:                     my $id = trace_ras_sn($user);
        !           364:                     $mode = "SSO";
        !           365:                     $user = select_sso_user($id);
        !           366:                     print_sso_user;
        !           367:                 }
        !           368:                 else {
        !           369:                     print "?\n";
        !           370:                 }
        !           371:             }
        !           372:             else {
        !           373:                 print "?\n";
        !           374:             }
        !           375:         }
        !           376:         elsif ($cmd[0] eq "field") {
        !           377:             if($user ne "---") {
        !           378:                 my $act = $account->{account};
        !           379:                 print "$user\-\>$cmd[1]:  $act->{$cmd[1]}\n";
        !           380:             }
        !           381:             else {
        !           382:                 print "?\n";
        !           383:             }
        !           384:         }
        !           385:         elsif ($cmd[0] eq "describe") {
        !           386:             if($user ne "---") {
        !           387:                 if($mode eq "SSO") {
        !           388:                     print_sso_user;
        !           389:                 }
        !           390:                 elsif($mode eq "RAS") {
        !           391:                     print_ras_user($user);
        !           392:                 }                                
1.1       snw       393:             }
                    394:             else {
                    395:                 print "?\n";
                    396:             }
                    397:         }
                    398:         elsif ($cmd[0] eq "list") {
                    399:             if($cmd[1] eq "users") {
                    400:                 if($mode eq "SSO") {
                    401:                     list_sso_users();
                    402:                 }
                    403:                 elsif($mode eq "RAS") {
                    404:                     list_ras_users();
                    405:                 }
                    406:             }
1.2     ! snw       407:             elsif($cmd[1] eq "sessions") {
        !           408:                 if($mode eq "RAS") {
        !           409:                     list_ras_sessions();
        !           410:                 }
        !           411:                 else {
        !           412:                     print "?\n";
        !           413:                 }
        !           414:             }
        !           415:             elsif($cmd[1] eq "sn") {
        !           416:                 if($mode eq "SSO") {
        !           417:                     if($user ne "---") {
        !           418:                         list_ras_screennames $user;
        !           419:                     }
        !           420:                     else {
        !           421:                         print "?\n";
        !           422:                     }
        !           423:                 }
        !           424:                 else {
        !           425:                     print "?\n";
        !           426:                 }
        !           427:             }
1.1       snw       428:             else {
                    429:                 print "?\n";
                    430:             }
                    431:         }
                    432:         else {
                    433:             print "?\n"
                    434:         }
                    435:     }
                    436: 
                    437: }
                    438: 
                    439: sub main {  
                    440:     GetOptions("rasurl=s" => \$rasurl,               
                    441:                "apikey=s" => \$apikey)
                    442:         or die("error in command line arguments");
                    443: 
                    444:     ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
                    445:     
                    446:     $cnclient = REST::Client->new({
                    447:         host => 'https://chivanet.org/rest/api',
                    448:         timeout => 10});
                    449: 
                    450:     $cnclient->addHeader('Authorization', "Apikey $apikey");
                    451: 
                    452:     $rasclient = REST::Client->new({
                    453:         host => $rasurl,
                    454:         timeout => 10});    
                    455:     
                    456:     print "ChivaNet MODCON $modcon_version\n";
                    457:     print " Copyright (C) 2025 Coherent Logic Development LLC\n\n";
                    458:     
                    459:     prompt();
                    460:     print "Goodbye.\n"
                    461: }
                    462: 
                    463: main();

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>