# HG changeset patch # User Goffi # Date 1596291950 -7200 # Node ID 7ebda4b54170c4db0533a85374ec148f1d9c40dc # Parent b57b5e42e894892a43b14edf98dab35fecb04900 jp (file/share): added commands to manage affiliations and configuration + documentation diff -r b57b5e42e894 -r 7ebda4b54170 doc/jp/file_share.rst --- a/doc/jp/file_share.rst Sat Aug 01 16:24:03 2020 +0200 +++ b/doc/jp/file_share.rst Sat Aug 01 16:25:50 2020 +0200 @@ -96,3 +96,13 @@ $ jp file share invite -P "photos/summer holidays" -t photos pierre@files.example.net louise@example.org + +affiliations +============ + +subcommands for file sharing affiliations management. please check :ref:`jp-file_share_affiliations`. + +configuration +============= + +subcommands for retrieving/modifying file sharing node configuration. please check :ref:`jp-file_share_configuration`. diff -r b57b5e42e894 -r 7ebda4b54170 doc/jp/file_share_affiliations.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/jp/file_share_affiliations.rst Sat Aug 01 16:25:50 2020 +0200 @@ -0,0 +1,56 @@ +.. _jp-file_share_affiliations: + +============================================================= +file/share/affiliations: file sharing affiliations management +============================================================= + +``affiliations`` let you manage access permission to your shared files repository, in a +way similar as for pubsub. + +Affiliations with file sharing are not standard and will only work with the SàT file +sharing component. + +Affiliations are similar to pubsub ones: + +``owner`` + Has full permissions on the node, including changing affiliations. Owner can't be + changed at the moment. + +``publisher`` + Can read, upload and delete files + +``member`` + Can access file but can't modify them or add new ones + +``none`` + Is not a member of this node, use it to remove an existing affiliation. + + +get +=== + +Retrieve entities affiliated to this file sharing node, and their role + +example +------- + +Get affiliations of a file sharing node:: + + $ jp file share affiliations get -P "/some/path" louise@files.example.org + +set +=== + +Set affiliations of an entity to a file sharing node. + +examples +-------- + +Allow read access to a photo album to Louise:: + + $ jp file share affiliations set -c files.example.net -P "/albums/holidays" -a louise@tazar2.int member + +Remove access to a directory from an old address of Pierre, and give it to the new one:: + + $ jp file share affiliations set -c files.example.net -N "some_namespace" -P + "/interesting/directory" -a pierre@example.com none -a pierre@example.org member diff -r b57b5e42e894 -r 7ebda4b54170 doc/jp/file_share_configuration.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/jp/file_share_configuration.rst Sat Aug 01 16:25:50 2020 +0200 @@ -0,0 +1,38 @@ +.. _jp-file_share_configuration: + +========================================================= +file/share/configuration: file sharing node configuration +========================================================= + +``configuration`` commands are use to check or modify settings of a file sharing node. +This is not standard and specific to SàT file sharing component. + +The configuration is similar as pubsub one. + +Only ``access_model`` can be used so far, with the ``open`` or ``whitelist`` values. + + +get +=== + +Retrieve file sharing node configuration. + +example +------- + +Get configuration of a file sharing node:: + + $ jp file share configuration get -P "/some/path" louise@files.example.org + +set +=== + +Set configuration of a file sharing node. + +example +------- + +Make a repository public:: + + $ jp file share configuration set -c files.example.net -P "/public_files" -f + access_model open diff -r b57b5e42e894 -r 7ebda4b54170 sat_frontends/jp/cmd_file.py --- a/sat_frontends/jp/cmd_file.py Sat Aug 01 16:24:03 2020 +0200 +++ b/sat_frontends/jp/cmd_file.py Sat Aug 01 16:25:50 2020 +0200 @@ -582,6 +582,221 @@ await self.gotId(upload_data, file_) +class ShareAffiliationsSet(base.CommandBase): + + def __init__(self, host): + super(ShareAffiliationsSet, self).__init__( + host, + "set", + use_output=C.OUTPUT_DICT, + help=_("set affiliations for a shared file/directory"), + ) + + def add_parser_options(self): + self.parser.add_argument( + "-N", + "--namespace", + default="", + help=_("namespace of the repository"), + ) + self.parser.add_argument( + "-P", + "--path", + default="", + help=_("path to the repository"), + ) + self.parser.add_argument( + "-a", + "--affiliation", + dest="affiliations", + metavar=("JID", "AFFILIATION"), + required=True, + action="append", + nargs=2, + help=_("entity/affiliation couple(s)"), + ) + self.parser.add_argument( + "jid", + help=_("jid of file sharing entity"), + ) + + async def start(self): + affiliations = dict(self.args.affiliations) + try: + affiliations = await self.host.bridge.FISAffiliationsSet( + self.args.jid, + self.args.namespace, + self.args.path, + affiliations, + self.profile, + ) + except Exception as e: + self.disp(f"can't set affiliations: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + else: + self.host.quit() + + +class ShareAffiliationsGet(base.CommandBase): + def __init__(self, host): + super(ShareAffiliationsGet, self).__init__( + host, + "get", + use_output=C.OUTPUT_DICT, + help=_("retrieve affiliations of a shared file/directory"), + ) + + def add_parser_options(self): + self.parser.add_argument( + "-N", + "--namespace", + default="", + help=_("namespace of the repository"), + ) + self.parser.add_argument( + "-P", + "--path", + default="", + help=_("path to the repository"), + ) + self.parser.add_argument( + "jid", + help=_("jid of sharing entity"), + ) + + async def start(self): + try: + affiliations = await self.host.bridge.FISAffiliationsGet( + self.args.jid, + self.args.namespace, + self.args.path, + self.profile, + ) + except Exception as e: + self.disp(f"can't get affiliations: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + else: + await self.output(affiliations) + self.host.quit() + + +class ShareAffiliations(base.CommandBase): + subcommands = (ShareAffiliationsGet, ShareAffiliationsSet) + + def __init__(self, host): + super(ShareAffiliations, self).__init__( + host, "affiliations", use_profile=False, help=_("affiliations management") + ) + + +class ShareConfigurationSet(base.CommandBase): + + def __init__(self, host): + super(ShareConfigurationSet, self).__init__( + host, + "set", + use_output=C.OUTPUT_DICT, + help=_("set configuration for a shared file/directory"), + ) + + def add_parser_options(self): + self.parser.add_argument( + "-N", + "--namespace", + default="", + help=_("namespace of the repository"), + ) + self.parser.add_argument( + "-P", + "--path", + default="", + help=_("path to the repository"), + ) + self.parser.add_argument( + "-f", + "--field", + action="append", + nargs=2, + dest="fields", + required=True, + metavar=("KEY", "VALUE"), + help=_("configuration field to set (required)"), + ) + self.parser.add_argument( + "jid", + help=_("jid of file sharing entity"), + ) + + async def start(self): + configuration = dict(self.args.fields) + try: + configuration = await self.host.bridge.FISConfigurationSet( + self.args.jid, + self.args.namespace, + self.args.path, + configuration, + self.profile, + ) + except Exception as e: + self.disp(f"can't set configuration: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + else: + self.host.quit() + + +class ShareConfigurationGet(base.CommandBase): + def __init__(self, host): + super(ShareConfigurationGet, self).__init__( + host, + "get", + use_output=C.OUTPUT_DICT, + help=_("retrieve configuration of a shared file/directory"), + ) + + def add_parser_options(self): + self.parser.add_argument( + "-N", + "--namespace", + default="", + help=_("namespace of the repository"), + ) + self.parser.add_argument( + "-P", + "--path", + default="", + help=_("path to the repository"), + ) + self.parser.add_argument( + "jid", + help=_("jid of sharing entity"), + ) + + async def start(self): + try: + configuration = await self.host.bridge.FISConfigurationGet( + self.args.jid, + self.args.namespace, + self.args.path, + self.profile, + ) + except Exception as e: + self.disp(f"can't get configuration: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + else: + await self.output(configuration) + self.host.quit() + + +class ShareConfiguration(base.CommandBase): + subcommands = (ShareConfigurationGet, ShareConfigurationSet) + + def __init__(self, host): + super(ShareConfiguration, self).__init__( + host, "configuration", use_profile=False, + help=_("file sharing node configuration") + ) + + class ShareList(base.CommandBase): def __init__(self, host): extra_outputs = {"default": self.default_output} @@ -804,7 +1019,8 @@ class Share(base.CommandBase): - subcommands = (ShareList, SharePath, ShareInvite) + subcommands = ( + ShareList, SharePath, ShareInvite, ShareAffiliations, ShareConfiguration) def __init__(self, host): super(Share, self).__init__( diff -r b57b5e42e894 -r 7ebda4b54170 sat_frontends/jp/cmd_pubsub.py --- a/sat_frontends/jp/cmd_pubsub.py Sat Aug 01 16:24:03 2020 +0200 +++ b/sat_frontends/jp/cmd_pubsub.py Sat Aug 01 16:25:50 2020 +0200 @@ -415,7 +415,7 @@ def add_parser_options(self): # XXX: we use optional argument syntax for a required one because list of list of 2 elements - # (uses to construct dicts) don't work with positional arguments + # (used to construct dicts) don't work with positional arguments self.parser.add_argument( "-a", "--affiliation",