cli (pubsub): new secret subcommands:

commands are added to `share`, `revoke` and `rotate` secrets of an encrypted pubsub node.

rel 380
This commit is contained in:
Goffi 2022-10-15 20:38:30 +02:00
commit b9f5c6b844

View file

@ -2563,6 +2563,166 @@ class Attachments(base.CommandBase):
)
class SecretShare(base.CommandBase):
def __init__(self, host):
super().__init__(
host,
"share",
use_pubsub=True,
pubsub_flags={C.NODE},
help=_("share a secret to let other entity encrypt or decrypt items"),
)
def add_parser_options(self):
self.parser.add_argument(
"-k", "--key", metavar="ID", dest="secret_ids", action="append", default=[],
help=_(
"only share secrets with those IDs (default: share all secrets of the "
"node)"
)
)
self.parser.add_argument(
"recipient", metavar="JID", help=_("entity who must get the shared secret")
)
async def start(self):
try:
await self.host.bridge.psSecretShare(
self.args.recipient,
self.args.service,
self.args.node,
self.args.secret_ids,
self.profile,
)
except Exception as e:
self.disp(f"can't share secret: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
else:
self.disp("secrets have been shared")
self.host.quit(C.EXIT_OK)
class SecretRevoke(base.CommandBase):
def __init__(self, host):
super().__init__(
host,
"revoke",
use_pubsub=True,
pubsub_flags={C.NODE},
help=_("revoke an encrypted node secret"),
)
def add_parser_options(self):
self.parser.add_argument(
"secret_id", help=_("ID of the secrets to revoke")
)
self.parser.add_argument(
"-r", "--recipient", dest="recipients", metavar="JID", action="append",
default=[], help=_(
"entity who must get the revocation notification (default: send to all "
"entities known to have the shared secret)"
)
)
async def start(self):
try:
await self.host.bridge.psSecretRevoke(
self.args.service,
self.args.node,
self.args.secret_id,
self.args.recipients,
self.profile,
)
except Exception as e:
self.disp(f"can't revoke secret: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
else:
self.disp("secret {self.args.secret_id} has been revoked.")
self.host.quit(C.EXIT_OK)
class SecretRotate(base.CommandBase):
def __init__(self, host):
super().__init__(
host,
"rotate",
use_pubsub=True,
pubsub_flags={C.NODE},
help=_("revoke existing secrets, create a new one and send notifications"),
)
def add_parser_options(self):
self.parser.add_argument(
"-r", "--recipient", dest="recipients", metavar="JID", action="append",
default=[], help=_(
"entity who must get the revocation and shared secret notifications "
"(default: send to all entities known to have the shared secret)"
)
)
async def start(self):
try:
await self.host.bridge.psSecretRotate(
self.args.service,
self.args.node,
self.args.recipients,
self.profile,
)
except Exception as e:
self.disp(f"can't rotate secret: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
else:
self.disp("secret has been rotated")
self.host.quit(C.EXIT_OK)
class SecretList(base.CommandBase):
def __init__(self, host):
super().__init__(
host,
"list",
use_pubsub=True,
use_verbose=True,
pubsub_flags={C.NODE},
help=_("list known secrets for a pubsub node"),
use_output=C.OUTPUT_LIST_DICT
)
def add_parser_options(self):
pass
async def start(self):
try:
secrets = data_format.deserialise(await self.host.bridge.psSecretsList(
self.args.service,
self.args.node,
self.profile,
), type_check=list)
except Exception as e:
self.disp(f"can't list node secrets: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
else:
if not self.verbosity:
# we don't print key if verbosity is not a least one, to avoid showing it
# on the screen accidentally
for secret in secrets:
del secret["key"]
await self.output(secrets)
self.host.quit(C.EXIT_OK)
class Secret(base.CommandBase):
subcommands = (SecretShare, SecretRevoke, SecretRotate, SecretList)
def __init__(self, host):
super().__init__(
host,
"secret",
use_profile=False,
help=_("handle encrypted nodes secrets"),
)
class HookCreate(base.CommandBase):
def __init__(self, host):
base.CommandBase.__init__(
@ -2725,6 +2885,7 @@ class Pubsub(base.CommandBase):
Search,
Transform,
Attachments,
Secret,
Hook,
Uri,
Node,