Annotation of ChivanetModcon/modcon, revision 1.3

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

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