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>