Diff for /ChivanetModcon/modcon between versions 1.1 and 1.8

version 1.1, 2025/01/30 19:16:06 version 1.8, 2025/03/10 15:34:45
Line 11 Line 11
 # Licensed AGPL-3.0  # Licensed AGPL-3.0
 #  #
 # $Log$  # $Log$
 # Revision 1.1  2025/01/30 19:16:06  snw  # Revision 1.8  2025/03/10 15:34:45  snw
 # Initial revision  # Undo the change
   #
   # Revision 1.7  2025/03/10 15:31:54  snw
   # Test
   #
   # Revision 1.6  2025/02/04 18:55:12  snw
   # Updates
   #
   # Revision 1.5  2025/02/01 03:17:46  snw
   # Fix session list
   #
   # Revision 1.4  2025/01/31 19:41:00  snw
   # Move to a UNIX UI paradigm
   #
   # Revision 1.3  2025/01/31 15:39:06  snw
   # Minor fixes
   #
   # Revision 1.2  2025/01/31 13:38:51  snw
   # Initial basic functions working
   #
   # Revision 1.1.1.1  2025/01/30 19:16:06  snw
   # Initial commit
 #  #
 #  #
   
 use REST::Client;  use REST::Client;
 use JSON;  use JSON;
 use Getopt::Long;  
 use Data::Dumper;  use Data::Dumper;
 use Term::ReadKey;  use Term::ReadKey;
   use Getopt::Long;
   use Text::Glob qw(match_glob);
   
 my $rasurl = '';  my $sso_account = '';
 my $apikey = '';  my $apikey = '';
 my $online = 0;  my $online = 0;
 my $modcon_version = '0.0.1';  my $modcon_version = '0.0.1';
 my $cnclient = '';  my $cnclient = '';
 my $rasclient = '';  
   
 my $wchar = '';  my $wchar = '';
 my $hchar = '';  my $hchar = '';
 my $wpixels = '';  my $wpixels = '';
 my $hpixels = '';  my $hpixels = '';
   my $account = '';
   my $mode = '---';
   my $user = '---';
   $site = '';
   
   sub list_directories {
       return ('sso', 'ras');
   }
   
 sub list_sso_users {  sub list_sso_users {
     $cnclient->GET("/chivanet/users");      $cnclient->GET("/chivanet/users");       
     my $ct = 0;  
       
     my $json = $cnclient->responseContent();      my $json = $cnclient->responseContent();
     my $hashref = decode_json($json);      my $hashref = decode_json($json);
   
     if($hashref->{ok} == 1) {      if($hashref->{ok} == 1) {
         my $arrayref = $hashref->{users};          my $arrayref = $hashref->{users};
         my @users = sort(@{$arrayref});          my @users = @{$arrayref};
           
         foreach my $user (@users) {          return @users;
             print "$user\n";  
             $ct = $ct + 1;  
   
             if($ct > $hchar - 2) {  
                 print "ENTER to continue, Q to quit...";  
                 my $resp = <STDIN>;  
                 chomp($resp);  
                 if($resp eq "Q") {  
                     return;  
                 }  
                 elsif($resp eq "q") {  
                     return;  
                 }  
                 $ct = 0;  
             }  
         }  
     }      }
     else {      else {
         print "RPC error\n";          print "RPC error\n";
           return ();
       }
   }
   
   
   sub select_sso_user {
       my($id) = @_;
   
       $cnclient->GET("/chivanet/validate_user?id=$id");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
       
       if($hashref->{exists} == 1) {
   
           $cnclient->GET("/chivanet/user?id=$id");
           my $json = $cnclient->responseContent();
           $account = decode_json($json);
   
           return $id;
     }      }
       else {
           return "---";
       }            
   }
   
   sub select_ras_user {
       my($id) = @_;
   
       $cnclient->GET("/chivanet/validate_sn?id=$id");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
   
       if($hashref->{exists} == 1) {
           return $id;
       }
       else {
           return "---";
       }
   }
   
   sub trace_ras_sn {
       my($user) = @_;
       
       $cnclient->GET("/chivanet/trace_sn?id=$user");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
       my $record = $hashref->{account};
       my $result = $record->{id};
       
       print "RAS screen name $user belongs to SSO account $result; switching to SSO mode\n";
       return $result;   
   }
   
   sub list_ras_sessions {
       $cnclient->GET("/chivanet/ras_sessions");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
       my $sessions = $hashref->{sessions};
       my $arrayref = $sessions->{sessions};
       my @result = ();
       
       foreach my $session (@{$arrayref}) {
           push(@result, $session->{id});
       }
       
       return @result;
   }
   
   sub list_ras_screennames {
       my($id) = @_;
   
       my @result = ();
       $cnclient->GET("/chivanet/user_ras_screen_names?id=$id");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
       my $arrayref = $hashref->{screen_names};
   
       foreach my $item (@{$arrayref}) {
           push(@result, $item->{screen_name});
       }
   
       
       return @result;   
 }  }
   
 sub list_ras_users {  sub list_ras_users {
   
       my @result = ();
       
       $cnclient->GET("/chivanet/all_ras_screen_names");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
   
       if($hashref->{ok} == 0) {
           print "RPC error\n";
           return @result;
       }
       
       my $arrayref = $hashref->{screen_names};
   
       foreach my $entryref (@{$arrayref}) {
           push(@result, $entryref->{id});
       }
   
       return @result;    
   }
   
   sub print_sso_user {
       my $act = $account->{account};
   
       print "\n";
       print "Username          :  $act->{id}\n";
       print "Real Name         :  $act->{last_name}, $act->{first_name}\n";
       print "Display Name      :  $act->{display_name}\n";
       print "Pronouns          :  $act->{pronouns}\n";
       print "Profile Image     :  https://chivanet.org$act->{profile_photo}\n";        
       print "E-Mail Address    :  $act->{email}\n";
       print "Permission Level  :  $act->{perm_level}\n";
       print "Created           :  $act->{create_ts}\n";
       print "Banned            :  $act->{mod_banned}\n\n";
   }
   
   sub print_ras_user {
       my($id) = @_;
   
       $cnclient->GET("/chivanet/sn_status?id=$id");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
       my $status = $hashref->{status};
       my $online = "offline";
       
       if($status->{online} == 1) {        
           $online = "online";        
       }
       
       print "\n";
   
   
       if($online eq "online") {
           my $sess = $status->{session};
           my $service = 'AIM';
           
           if($sess->{is_icq} == 1) {
               $service = 'ICQ';
           }
   
           if($sess->{idle_seconds} > 0) {
               $online = "idle";
           }
           
           print "Screen Name       :  $id [$online]\n";
           print "Service           :  $service\n";
           if($online eq "online") {
               print "Time Online (secs):  $sess->{online_seconds}\n";
           }
           else {
               print "Time Idle (secs)  :  $sess->{idle_seconds}\n";
           }
           print "Away Message      :  $sess->{away_message}\n\n";
       }
       else {
           print "Screen Name       :  $id [$online]\n\n";
       }    
       
   }
   
   sub send_im {
       my($user, $msgbody) = @_;
   
       print "sending message \"$msgbody\" to $user...";   
       
       my $msg = "<font color=red><strong>[ChivaNet Support]:</strong></font> $msgbody";
       
       $cnclient->GET("/chivanet/send_im?from=ChivaNet&to=$user&message=$msg");
       my $json = $cnclient->responseContent();
       my $hashref = decode_json($json);
       
       if($hashref->{status} == 1) {
           print "[OK]\n";
       }
       else {
           print "[FAIL]\n";
       }
   }
   
   sub ls {
       my ($description, $match, @entries) = @_;
   
       if($match eq "") {
           $match = '*';
       }
   
       print "Directory of [$description] matching \'$match\':\n\n";
           
       my @sorted = sort(@entries);
       my $maxlen = 0;
       
       foreach my $entry (@sorted) {
           my $len = length($entry);
           if ($len > $maxlen) {
               $maxlen = $len;
           }
       }
   
       $maxlen = $maxlen + 2;
   
       my $ct = $#sorted + 1;
       foreach my $entry (@sorted) {
           if(match_glob($match, $entry)) {
               if($col + $maxlen >= $wchar) {
                   print "$entry\n";
                   $col = 0;
               }
               else {
                   printf("%-$maxlen\s", $entry);
                   $col = $col + $maxlen;
               }
           }
           else {
               $ct = $ct - 1;
           }
       }
       
       print "\n\n$ct matching items in directory\n";
 }  }
   
 sub prompt {  sub prompt {
           
     my $rawcmd = '';      my $rawcmd = '';
     my $mode = 'SSO';      my $pmode = $mode;    
     my $user = '---';      my @path = ();
       
     while (1) {      while (1) {
         print "MODCON [$mode/$user]> ";          $pmode = lc $mode;
           my $prompt = '';
           if($pmode ne "---") {
               if($user eq '---') {
                   $prompt = "$sso_account\@$site:[/$pmode]\$ ";
               }
               else {
                   $prompt = "$sso_account\@$site:[/$pmode/$user]\$ ";
               }
           }
           else {
               $prompt = "$sso_account\@$site:[/]\$ ";
           }
           print $prompt;
         my $line = <STDIN>;          my $line = <STDIN>;
         chomp($line);          chomp($line);
         $rawcmd = $line;          $rawcmd = $line;
                   
         my @cmd = split(' ', $rawcmd);          my @cmd = split(' ', $rawcmd);
                   
         if ($cmd[0] eq "quit") {          if ($cmd[0] eq "exit" || $cmd[0] eq "logout" || $cmd[0] eq "quit" || $cmd[0] eq "bye" || $cmd[0] eq "lo") {
             return;              return;
         }          }
         elsif ($cmd[0] eq "mode") {          elsif ($cmd[0] eq "pwd") {
             if($cmd[1] eq "SSO") {              my $pstr = join('/', @path);
                 $mode = "SSO";              print "/$pstr\n";        
                 $user = "---";          }        
           elsif ($cmd[0] eq "cd") {
               my $abspath = false;
   
               if($cmd[1] eq "..") {
                   if(@path) {
                       if($#path == 1) {
                           $user = "---";
                           @path = ($pmode);
                       }
                       elsif($#path == 0) {
                           $mode = "---";
                           @path = ();
                       }
                   }
                   else {
                       print "already in root directory\n";
                   }
             }              }
             elsif ($cmd[1] eq "RAS") {              else {
                 $mode = "RAS";                  my @oldpath = @path;
                 $user = "---";                  @path = split('/', $cmd[1]);
               
                   if(substr($cmd[1], 0, 1) eq '/') {
                       $abspath = true;
                       shift @path;                
                   }
                   
                   if($abspath eq true || !@oldpath) {
                       if($#path == 0) {
                           # mode, no user
                           if($path[0] eq "sso") {
                               $mode = "SSO";
                               $user = "---";
                               @path = ('sso');
                           }
                           elsif($path[0] eq "ras") {
                               $mode = "RAS";
                               $user = "---";
                               @path = ('ras');
                           }
                           else {
                               print "$path[0]:  no such directory exists\n";
                               @path = @oldpath;
                           }
                       }
                       elsif($#path == 1) {
                           # mode and user
                           if($path[0] eq "sso") {
                               $user = select_sso_user($path[1]);                          
                               if($user eq "---") {
                                   print "$path[1]:  no such file exists in $pmode\n";
                                   @path = @oldpath;
                               }
                               else {
                                   $mode = "SSO";
                                   @path = ('sso', $user);
                               }
                           }
                           elsif($path[0] eq "ras") {
                               $user = select_ras_user($path[1]);
                               if($user eq "---") {
                                   print "$path[1]:  no such file exists in $pmode\n";
                                   @path = @oldpath;
                               }
                               else {
                                   $mode = "RAS";
                                   @path = ('ras', $user);
                               }
                           }
                           else {
                               print "$path[0]:  no such directory exists\n";
                               @path = @oldpath;
                           }
                       }
                       else {
                           if($cmd[1] eq '/') {
                               $mode = '---';
                               $user = '---';
                               @path = ();
                           }
                           else {
                               print "cd:  invalid path specification\n";
                               @path = @oldpath;
                           }
                       }
                   }
                   else {
                       if($#oldpath == 1) {
                           print "invalid path specification\n";
                           @path = @oldpath;
                       }
                       else {
                           if($#path == 0) {
                               if($pmode eq "sso") {
                                   $user = select_sso_user($path[0]);                          
                                   if($user eq "---") {
                                       print "$path[0]:  no such file exists in $pmode\n";
                                       @path = @oldpath;
                                   }
                                   else {
                                       $mode = "SSO";
                                       @path = ('sso', $user);
                                   }
                               }
                               elsif($pmode eq "ras") {
                                   $user = select_ras_user($path[0]);                          
                                   if($user eq "---") {
                                       print "$path[0]:  no such file exists in $pmode\n";
                                       @path = @oldpath;
                                   }
                                   else {
                                       $mode = "RAS";
                                       @path = ('ras', $user);
                                   }
                               }
                               else {
                                   print "$path[0]:  no such directory exists\n";
                                   @path = @oldpath;                            
                               }
                           }
                           else {
                               print "invalid path specification\n";
                               @path = @oldpath;
                           }
                       }
                   }                                         
               } # if ..                                  
           }
           elsif ($cmd[0] eq "im") {
               if($mode eq "RAS") {
                   if($user ne "---") {
                       my @msga = @cmd[1..$#cmd];
                       my $msgbody = join(' ', @msga);                    
                       send_im($user, $msgbody);
                   }
                   else {
                       print "im:  no user selected\n";
                   }
               }
               else {
                   print "im:  invalid command outside of ras directory\n";
               }
           }    
           elsif ($cmd[0] eq "trace") {
               if($mode eq "RAS") {
                   if($user ne "---") {                    
                       my $id = trace_ras_sn($user);
                       $mode = "SSO";
                       $user = select_sso_user($id);
                       print_sso_user;
                   }
                   else {
                       print "trace:  no user select\n";
                   }
             }              }
             else {              else {
                 print "?\n";                  print "trace:  invalid command outside of ras directory\n";
             }              }
         }          }
         elsif ($cmd[0] eq "list") {          elsif ($cmd[0] eq "field") {
             if($cmd[1] eq "users") {              if($mode eq "SSO") {
                 if($mode eq "SSO") {                  if($user ne "---") {
                     list_sso_users();                      my $act = $account->{account};
                       print "$user\-\>$cmd[1]:  $act->{$cmd[1]}\n";
                 }                  }
                 elsif($mode eq "RAS") {                  else {
                     list_ras_users();                      print "field:  no user selected\n";
                 }                  }
             }              }
             else {              else {
                 print "?\n";                  print "field:  command invalid outside of ras directory\n";
             }              }
         }          }
           elsif ($cmd[0] eq "sessions") {
               if($mode ne "RAS") {
                   print "sessions:  must be in ras mode\n";
               }
               else {
                   if($cmd[1]) {
                       ls "active RAS sessions", $cmd[1], list_ras_sessions();
                   }
                   else {
                       ls "active RAS sessions", '*', list_ras_sessions();
                   }
               }
           }
           elsif ($cmd[0] eq "lssn") {
               if($mode ne "SSO" || $user eq "---") {
                   print "lssn:  must be in sso mode with a user selected\n";
               }
               else {
                   my @sns = list_ras_screennames($user);
                   if($cmd[1]) {
                       ls "RAS screen names for $user", $match, @sns;
                   }
                   else {
                       ls "RAS screen names for $user", '*', @sns;
                   }
               }                    
           }
           elsif ($cmd[0] eq "ls") {
               my @entries = ();
               
               if($mode eq "---") {
                   @entries = list_directories();
               }
               else {
                   if($user ne "---") {
                       if($mode eq "SSO") {
                           print_sso_user;
                       }
                       elsif($mode eq "RAS") {
                           print_ras_user($user);
                       }                                
                   }
                   else {
                       if($mode eq "SSO") {
                           @entries = list_sso_users();
                       }
                       else {
                           @entries = list_ras_users();
                       }
                   }
               }
   
               if(@entries) {
                   my $col = 0;
                   my $pstr = join('/', @path);
                   my $pfin = "/$pstr";
                   if($cmd[1]) {
                       ls $pfin, $cmd[1], @entries;
                   }
                   else {
                       ls $pfin, '*', @entries;
                   }
               }
   
           }
         else {          else {
             print "?\n"              print "$cmd[0]: command not found\n";
         }          }
     }      }
   
 }  }
   
 sub main {    sub main {  
     GetOptions("rasurl=s" => \$rasurl,                     ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();    
                "apikey=s" => \$apikey)  
         or die("error in command line arguments");  
   
     ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();      GetOptions("site=s" => \$site) or die "error in command line arguments";
       
       if($site eq "") {
           print "modcon: must supply -site command-line argument\n";
           return;
       }
           
     $cnclient = REST::Client->new({      $cnclient = REST::Client->new({
         host => 'https://chivanet.org/rest/api',          host => "https://$site/rest/api",
         timeout => 10});          timeout => 10});
   
     $cnclient->addHeader('Authorization', "Apikey $apikey");  
   
     $rasclient = REST::Client->new({  
         host => $rasurl,  
         timeout => 10});      
           
     print "ChivaNet MODCON $modcon_version\n";      print "ChivaNet MODCON $modcon_version\n";
     print " Copyright (C) 2025 Coherent Logic Development LLC\n\n";      print " Copyright (C) 2025 Coherent Logic Development LLC\n\n";
   
       print "username: ";
       $sso_account = <STDIN>;
       chomp($sso_account);
   
       print "password: ";
       ReadMode('noecho');
       my $password = <STDIN>;
       chomp($password);
       ReadMode('normal');
   
           
     prompt();      my $params = $cnclient->buildQuery([username => $sso_account, password => $password]);
       my $result = $cnclient->POST("/chivanet/modcon_auth", substr($params, 1), {'Content-type' => 'application/x-www-form-urlencoded'});
       my $http_response = $result->{_res};
       my $json = $http_response->{_content};
       my $apiresult = decode_json($json);
       
       if($apiresult->{ok} == 1) {
           $cnclient->addHeader('Authorization', "Apikey $apiresult->{token}");
   
           select_sso_user $sso_account;
           my $act = $account->{account};
           
           print "\n\nWelcome to MODCON, $act->{display_name}!\n\n";
           
           prompt();
       }
       else {
           print "\nerror: $apiresult->{error}\n";
           return;
       }
   
     print "Goodbye.\n"      print "Goodbye.\n"
 }  }
   

Removed from v.1.1  
changed lines
  Added in v.1.8


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