Diff for /ChivanetModcon/modcon between versions 1.3 and 1.5

version 1.3, 2025/01/31 15:39:06 version 1.5, 2025/02/01 03:17:46
Line 11 Line 11
 # Licensed AGPL-3.0  # Licensed AGPL-3.0
 #  #
 # $Log$  # $Log$
   # 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  # Revision 1.3  2025/01/31 15:39:06  snw
 # Minor fixes  # Minor fixes
 #  #
Line 24 Line 30
   
 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;
   
 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 $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 list_ras_users {  
   
 }  
   
 sub select_sso_user {  sub select_sso_user {
     my($id) = @_;      my($id) = @_;
Line 90  sub select_sso_user { Line 82  sub select_sso_user {
         $cnclient->GET("/chivanet/user?id=$id");          $cnclient->GET("/chivanet/user?id=$id");
         my $json = $cnclient->responseContent();          my $json = $cnclient->responseContent();
         $account = decode_json($json);          $account = decode_json($json);
           
         return $id;          return $id;
     }      }
     else {      else {
         print ">>> invalid SSO user $id [$hashref->{error}]\n";  
         return "---";          return "---";
     }                  }            
 }  }
Line 110  sub select_ras_user { Line 101  sub select_ras_user {
         return $id;          return $id;
     }      }
     else {      else {
         print ">>> invalid RAS screen name $id\n";  
         return "---";          return "---";
     }      }
 }  }
Line 134  sub list_ras_sessions { Line 124  sub list_ras_sessions {
     my $hashref = decode_json($json);      my $hashref = decode_json($json);
     my $sessions = $hashref->{sessions};      my $sessions = $hashref->{sessions};
     my $arrayref = $sessions->{sessions};      my $arrayref = $sessions->{sessions};
     my $ct = 0;      my @result = ();
           
     foreach my $session (@{$arrayref}) {      foreach my $session (@{$arrayref}) {
         print "$session->{screen_name}\n";          push(@result, $session->{id});
   
         $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;  
         }  
     }      }
           
     print "$sessions->{count} current sessions\n";          return @result;
 }  }
   
 sub list_ras_screennames {  sub list_ras_screennames {
     my($id) = @_;      my($id) = @_;
       
     $cnclient->GET("/chivanet/ras_screen_names?id=$id");  
   
       my @result = ();
       $cnclient->GET("/chivanet/user_ras_screen_names?id=$id");
     my $json = $cnclient->responseContent();      my $json = $cnclient->responseContent();
     my $hashref = decode_json($json);      my $hashref = decode_json($json);
     my $arrayref = $hashref->{screen_names};      my $arrayref = $hashref->{screen_names};
     my $ct = 0;  
     my $total = 0;  
   
     print "\n";      foreach my $item (@{$arrayref}) {
           push(@result, $item->{screen_name});
       }
   
           
     foreach my $sn (@{$arrayref}) {      return @result;   
         my $name = "$sn->{screen_name}\n";  }
         chomp($name);  
   
         my $bot = '';  sub list_ras_users {
         my $public = '';  
           
         if($sn->{bot_sn} eq 1) {  
             $bot = "bot";  
         }  
         else {  
             $bot = "human";  
         }  
   
         if($sn->{public_sn} eq 1) {      my @result = ();
             $public = "public";      
         }      $cnclient->GET("/chivanet/all_ras_screen_names");
         else {      my $json = $cnclient->responseContent();
             $public = "unlisted";      my $hashref = decode_json($json);
         }  
   
         print "$name:  $public $bot; created $sn->{create_ts}\n";      if($hashref->{ok} == 0) {
                   print "RPC error\n";
         $ct = $ct + 1;          return @result;
         $total = $total + 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;  
         }  
     }      }
       
       my $arrayref = $hashref->{screen_names};
   
     print "\nSSO user $id has $total screen names\n\n";      foreach my $entryref (@{$arrayref}) {
           push(@result, $entryref->{id});
       }
   
       return @result;    
 }  }
   
 sub print_sso_user {  sub print_sso_user {
Line 270  sub print_ras_user { Line 227  sub print_ras_user {
     }      }
     else {      else {
         print "Screen Name       :  $id [$online]\n\n";          print "Screen Name       :  $id [$online]\n\n";
     }      }    
       
 #    print Dumper($status);  
           
 }  }
   
Line 295  sub send_im { Line 250  sub send_im {
     }      }
 }  }
   
   sub ls {
       my ($description, @entries) = @_;
   
       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($col + $maxlen >= $wchar) {
               print "\n";
               $col = 0;
           }
           else {
               printf("%-$maxlen\s", $entry);
               $col = $col + $maxlen;
           }                    
       }                
       print "\n$ct items in $description\n";
       
   }
   
 sub prompt {  sub prompt {
           
     my $rawcmd = '';      my $rawcmd = '';
     my $mode = '---';      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 = "---";          }        
                 $account = '';          elsif ($cmd[0] eq "cd") {
             }              my $abspath = false;
             elsif ($cmd[1] eq "ras") {  
                 $mode = "RAS";              if($cmd[1] eq "..") {
                 $user = "---";                  if(@path) {
                 $account = '';                      if($#path == 1) {
             }                          $user = "---";
             else {                          @path = ($pmode);
                 print "?\n";                      }
             }                      elsif($#path == 0) {
         }                          $mode = "---";
         elsif ($cmd[0] eq "select") {                          @path = ();
             if($cmd[1] eq "user") {                      }
                 if($mode eq "SSO") {  
                     $user = select_sso_user($cmd[2]);                      
                     chomp($user);  
                     print_sso_user;  
                 }  
                 elsif($mode eq "RAS") {  
                     $user = select_ras_user($cmd[2]);  
                     chomp($user);  
                     print_ras_user $user;  
                 }                  }
                 else {                  else {
                     print "?\n";                      print "already in root directory\n";
                 }                  }
             }              
             else {  
                 print "?\n";  
             }              }
               else {
                   my @oldpath = @path;
                   @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 = "SSO";
                                       @path = ('sso', $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") {          elsif ($cmd[0] eq "im") {
             if($mode eq "RAS") {              if($mode eq "RAS") {
Line 355  sub prompt { Line 447  sub prompt {
                     send_im($user, $msgbody);                      send_im($user, $msgbody);
                 }                  }
                 else {                  else {
                     print "?\n";                      print "im:  no user selected\n";
                 }                  }
             }              }
             else {              else {
                 print "?\n";                  print "im:  invalid command outside of ras directory\n";
             }              }
         }              }    
         elsif ($cmd[0] eq "trace") {          elsif ($cmd[0] eq "trace") {
Line 371  sub prompt { Line 463  sub prompt {
                     print_sso_user;                      print_sso_user;
                 }                  }
                 else {                  else {
                     print "?\n";                      print "trace:  no user select\n";
                 }                  }
             }              }
             else {              else {
                 print "?\n";                  print "trace:  invalid command outside of ras directory\n";
             }              }
         }          }
         elsif ($cmd[0] eq "field") {          elsif ($cmd[0] eq "field") {
             if($user ne "---") {              if($mode eq "SSO") {
                 my $act = $account->{account};                  if($user ne "---") {
                 print "$user\-\>$cmd[1]:  $act->{$cmd[1]}\n";                      my $act = $account->{account};
                       print "$user\-\>$cmd[1]:  $act->{$cmd[1]}\n";
                   }
                   else {
                       print "field:  no user selected\n";
                   }
             }              }
             else {              else {
                 print "?\n";                  print "field:  command invalid outside of ras directory\n";
             }              }
         }          }
         elsif ($cmd[0] eq "describe") {          elsif ($cmd[0] eq "sessions") {
             if($user ne "---") {              if($mode ne "RAS") {
                 if($mode eq "SSO") {                  print "sessions:  must be in ras mode\n";
                     print_sso_user;  
                 }  
                 elsif($mode eq "RAS") {  
                     print_ras_user($user);  
                 }                                  
             }              }
             else {              else {
                 print "?\n";                  ls "active RAS sessions", list_ras_sessions();
             }              }
         }          }
         elsif ($cmd[0] eq "list") {          elsif ($cmd[0] eq "lssn") {
             if($cmd[1] eq "users") {              if($mode ne "SSO" || $user eq "---") {
                 if($mode eq "SSO") {                  print "lssn:  must be in sso mode with a user selected\n";
                     list_sso_users();  
                 }  
                 elsif($mode eq "RAS") {  
                     list_ras_users();  
                 }  
             }              }
             elsif($cmd[1] eq "sessions") {              else {
                 if($mode eq "RAS") {                  my @sns = list_ras_screennames($user);
                     list_ras_sessions();                  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 {                  else {
                     print "?\n";                      if($mode eq "SSO") {
                 }                          @entries = list_sso_users();
             }  
             elsif($cmd[1] eq "sn") {  
                 if($mode eq "SSO") {  
                     if($user ne "---") {  
                         list_ras_screennames $user;  
                     }                      }
                     else {                      else {
                         print "?\n";                          @entries = list_ras_users();
                     }                      }
                 }                  }
                 else {  
                     print "?\n";  
                 }  
             }              }
             else {  
                 print "?\n";              if(@entries) {
                   my $col = 0;
                   my $pstr = join('/', @path);
                   my $pfin = "/$pstr";
                   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');
   
       
       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);
           
     prompt();      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.3  
changed lines
  Added in v.1.5


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