421
422
423
424
425
426
427
428
429
430
431
432
433
434
...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
|
[ lib.emit(false, 1, 'usage: ', `argv[0], ' actor ', umode.type.helptxt.flags, ' <xid> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'actor <xid> rank <value>', 'set an actor\'s rank to <value> (remote actors cannot exercise rank-related powers, but benefit from rank immunities)' };
{ 'actor <xid> degrade', 'alias for `actor <xid> rank 0`' };
{ 'actor <xid> bestow <epithet>', 'bestow an epithet upon an actor' };
{ 'actor <xid> instantiate', 'instantiate a remote actor, retrieving their profile and posts even if no one follows them' };
{ 'actor <xid> proscribe', 'globally ban an actor from interacting with your server' };
{ 'actor <xid> rehabilitate', 'lift a proscription on an actor' };
{ 'actor <xid> purge-all <confirm-str>', 'remove all traces of a user from the database (except local user credentials -- use \27[1mauth all purge\27[m to prevent a user from accessing the instance)' };
}) ]
return 1
end
if umode.arglist.ct >= 2 then
var degrade = lib.str.cmp(umode.arglist(1),'degrade') == 0
var xid = umode.arglist(0)
................................................................................
lib.warn('completely purging actor ', usr.ptr.xid, ' and all related content from database')
dlg:actor_purge_uid(usr.ptr.id)
lib.report('actor purged')
else goto cmderr end
else goto cmderr end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'user') == 0 then
var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
if umode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' user ', umode.type.helptxt.flags, ' <handle> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'user <handle> create', 'add a new user' };
{ 'user <handle> auth <type> new', '(where applicable, managed auth only) create a new authentication token of the given type for a user' };
{ 'user <handle> auth <type> reset', '(where applicable, managed auth only) delete all of a user\'s authentication tokens of the given type and issue a new one' };
{ 'user <handle> auth (<type>|all) purge', 'delete all credentials that would allow this user to log in (where possible)' };
{ 'user <handle> (grant|revoke) (<priv>|all)', 'grant or revoke a specific power to or from a user' };
{ 'user <handle> emasculate', 'strip all administrative powers and rank from a user' };
{ 'user <handle> forgive', 'restore all default powers to a user' };
{ 'user <handle> suspend [<timespec>]', '(e.g. \27[1muser jokester suspend 5d 6h 7m 3s\27[m to suspend "jokester" for five days, six hours, seven minutes, and three seconds) suspend a user'};
}) ]
return 1
end
var handle = umode.arglist(0)
var usr = dlg:actor_fetch_xid(pstr {ptr=handle, ct=lib.str.sz(handle)})
if umode.arglist.ct == 2 and lib.str.cmp(umode.arglist(1),'create')==0 then
if usr:ref() then lib.bail('that user already exists') end
................................................................................
end
end
end
end
usr.ptr.rights.powers = newprivs
dlg:actor_save_privs(usr.ptr)
elseif lib.str.cmp(umode.arglist(1),'auth') == 0 and umode.arglist.ct == 4 then
var reset = lib.str.cmp(umode.arglist(3),'reset') == 0
if reset or lib.str.cmp(umode.arglist(3),'new') == 0 then
-- FIXME enable resetting pws for users who have
-- not logged in yet
if not usr then lib.bail('unknown handle') end
if lib.str.cmp(umode.arglist(2),'pw') == 0 then
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
|
[ lib.emit(false, 1, 'usage: ', `argv[0], ' actor ', umode.type.helptxt.flags, ' <xid> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'actor <xid> rank <value>', 'set an actor\'s rank to <value> (remote actors cannot exercise rank-related powers, but benefit from rank immunities)' };
{ 'actor <xid> degrade', 'alias for `actor <xid> rank 0`' };
{ 'actor <xid> bestow <epithet>', 'bestow an epithet upon an actor' };
{ 'actor <xid> instantiate', 'instantiate a remote actor, retrieving their profile and posts even if no one follows them' };
{ 'actor <xid> proscribe', 'globally ban an actor from interacting with your server' };
{ 'actor <xid> rehabilitate', 'lift a proscription on an actor' };
{ 'actor <xid> xkey [pem|der]', 'extract an actor\'s public key in either PEM or DER form' };
{ 'actor <xid> purge-all <confirm-str>', 'remove all traces of a user from the database (except local user credentials -- use \27[1mauth all purge\27[m to prevent a user from accessing the instance)' };
}) ]
return 1
end
if umode.arglist.ct >= 2 then
var degrade = lib.str.cmp(umode.arglist(1),'degrade') == 0
var xid = umode.arglist(0)
................................................................................
lib.warn('completely purging actor ', usr.ptr.xid, ' and all related content from database')
dlg:actor_purge_uid(usr.ptr.id)
lib.report('actor purged')
else goto cmderr end
else goto cmderr end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'user') == 0 then
if mode.arglist.ct < 3 then goto cmderr end
var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
if umode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' user ', umode.type.helptxt.flags, ' <handle> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'user <handle> create', 'add a new user' };
{ 'user <handle> auth <type> new', '(where applicable, managed auth only) create a new authentication token of the given type for a user' };
{ 'user <handle> auth <type> reset', '(where applicable, managed auth only) delete all of a user\'s authentication tokens of the given type and issue a new one' };
{ 'user <handle> auth (<type>|all) purge', 'delete all credentials that would allow this user to log in (where possible)' };
{ 'user <handle> (grant|revoke) (<priv>|all)', 'grant or revoke a specific power to or from a user' };
{ 'user <handle> emasculate', 'strip all administrative powers and rank from a user' };
{ 'user <handle> forgive', 'restore all default powers to a user' };
{ 'user <handle> suspend [<timespec>]', '(e.g. \27[1muser jokester suspend 5d 6h 7m 3s\27[m to suspend "jokester" for five days, six hours, seven minutes, and three seconds) suspend a user'};
{ 'user <handle> xkey [pem|der]', 'extract an user\'s *private* key in either PEM or DER form' };
}) ]
return 1
end
var handle = umode.arglist(0)
var usr = dlg:actor_fetch_xid(pstr {ptr=handle, ct=lib.str.sz(handle)})
if umode.arglist.ct == 2 and lib.str.cmp(umode.arglist(1),'create')==0 then
if usr:ref() then lib.bail('that user already exists') end
................................................................................
end
end
end
end
usr.ptr.rights.powers = newprivs
dlg:actor_save_privs(usr.ptr)
elseif lib.str.cmp(umode.arglist(1),'xkey') == 0 and umode.arglist.ct == 3 then
if not usr then lib.bail('unknown handle') end
if lib.str.cmp(umode.arglist(2),'pem') == 0 then
var pk = lib.crypt.loadpriv(usr().key)
if not pk.ok then
lib.bail('could not parse key! this is probably a bug')
end
var pem: lib.crypt.pemfile
if not lib.crypt.pem(false, &pk.val, &pem[0]) then
lib.bail('could not convert key to PEM! this is probably a bug')
end
lib.io.send(1, pem, lib.str.sz(&pem[0]))
pk.val:free()
elseif lib.str.cmp(umode.arglist(2),'der') == 0 then
-- TODO avoid dumping binary to tty
lib.warn('dumping user\'s \x1b[1mprivate\x1b[m key!')
lib.io.send(1, [&int8](usr().key.ptr), usr().key.ct)
else lib.bail('invalid key format') end
elseif lib.str.cmp(umode.arglist(1),'auth') == 0 and umode.arglist.ct == 4 then
var reset = lib.str.cmp(umode.arglist(3),'reset') == 0
if reset or lib.str.cmp(umode.arglist(3),'new') == 0 then
-- FIXME enable resetting pws for users who have
-- not logged in yet
if not usr then lib.bail('unknown handle') end
if lib.str.cmp(umode.arglist(2),'pw') == 0 then
|