diff --git a/docs/usage.rst b/docs/usage.rst index 3b7d1378b..e7f82c0ec 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -153,38 +153,31 @@ Inviting Participant Devices A new participant device is invited to collaborate on a magic folder using the ``magic-folder invite`` command. This produces an "invite -code" which **contains secret information**. It must be shared in a -secure way; anyone viewing the "invite code" can impersonate the -invitee (if they also have access to the Tahoe Grid). +code" which is a one-time code. This code should be communicated +securely to the invitee. The code will allow the invitee's device to +establish a connection to this device and exchange details. Thus, the +code can only be used while this device is connected to the +Internet. The code may only be used once, for a single invitee. .. code-block:: console - $ magic-folder --config ./foo invite --name default bob + $ magic-folder --config ./foo invite --name default An invitation code is created using an existing magic folder (``--name -default`` above) and a nickname for the new participant device -(``bob`` above). The magic-folder identified must have been created on -this device. The nickname is assigned to the participant device in -the magic folder configuration and grid state. - -**Technical details**: A new mutable directory is created in the Tahoe -LAFS grid, producing a write-capability. This is "attenuated" to a -read-capability. This read-capability is written into the "collective -Distributed Mutable Diractory (DMD)" with the invitee's name; this -allows other magic-folder participants to notice this new participant -when they next download it. - -The invite-code includes the write-capability for the participant's -"personal DMD"; this is where updates produced by the invitee will be -written. Notice that the administrator of the magic-folder (the one -device holding the write-capability for the "collective DMD") could -retain the invitee's "personal DMD" write-capbility and use it to -impersonate that participant. **The invite-code MUST be communicated -securely to the invitee**. - -Another part of the invite-code is a read-capability for the -"collective DMD" allowing the new participant to learn of all other -participants. +default`` above). The magic-folder identified must have been created on +this device. + +Once the invitee runs ``magic-folder join`` (see below) the two +devices will connect and exchange some information; this will complete +the invitation. The "invite" command won't exit until the invitee has +actually completed and will print out some details. If you pass +``--no-wait`` then the command will exist immediately (although the +invite will still be valid). + +Invites are valid until the magic-folder daemon stops running or until +the default number of minutes pass (whichever is sooner). See the +``--timeout`` for the default (or you can pass a different number of +mintues if you prefer). Joining a Magic Folder @@ -203,7 +196,10 @@ required is the path to a local directory. This is the directory to which content will be downloaded and from which it will be uploaded. You must choose a name to identify content from this device with -``--author``. +``--author``. The device which has invited you must also be connected +to the internet for the invite to work: once a connection is +established, the two devices exchange some information and the invite +is complete. Further options are documented in ``magic-folder join --help``. diff --git a/src/magic_folder/invite.py b/src/magic_folder/invite.py index d41c6878f..8ba4c84ac 100644 --- a/src/magic_folder/invite.py +++ b/src/magic_folder/invite.py @@ -29,7 +29,7 @@ @inlineCallbacks -def magic_folder_invite(config, folder_name, invitee_name, treq): +def magic_folder_invite(config, folder_name, treq): """ Invite a user identified by the nickname to a folder owned by the alias @@ -37,63 +37,11 @@ def magic_folder_invite(config, folder_name, invitee_name, treq): :param unicode folder_name: The name of an existing magic-folder - :param unicode invitee_name: The nickname for the new participant - :param HTTPClient treq: An ``HTTPClient`` or similar object to use to make the queries. - :return Deferred[unicode]: A secret invitation code. + :return Deferred[unicode]: A secret magic-wormhole invitation code. """ - # XXX probably want to pass this in, instead of "treq"? - tahoe_client = create_tahoe_client(config.tahoe_client_url, treq) - - # get configuration for this magic-folder (or error if it doesn't - # exist) - try: - folder_config = config.get_magic_folder(folder_name) - except ValueError: - raise usage.UsageError( - u"No magic-folder named '{}'".format(folder_name) - ) - - if not folder_config.is_admin(): - raise usage.UsageError( - u"This device is not the administrator for '{}'".format(folder_name) - ) - - # create an unlinked directory and get the dmd write-cap - dmd_write_cap = yield tahoe_client.create_mutable_directory() - - # derive a dmd read-only cap from it. - dmd_readonly_cap = uri.from_string(dmd_write_cap.encode("utf8")).get_readonly().to_string() - if dmd_readonly_cap is None: - raise Exception("failed to diminish dmd write cap") - - # Now, we need to create a link to the nickname from inside the - # collective to this read-cap. For that we will need to know the - # write-cap of the collective (which will only be true if we're - # the administrator device) so that a link can be created inside - # it. - - # we already checked above that this is a write-cap using .is_admin() - magic_write_cap = folder_config.collective_dircap - magic_readonly_cap = uri.from_string(magic_write_cap.encode("utf8")).get_readonly().to_string() - - # ...we're adding a sub-directory to the global DMD; the name of - # this sub-directory is the invitee's name and it points to the - # mutable directory we created for them (which will be included in - # the invite code) - - yield tahoe_client.add_entry_to_mutable_directory( - magic_write_cap, - invitee_name, - dmd_readonly_cap, - ) - - invite_code = "{}{}{}".format( - magic_readonly_cap, - INVITE_SEPARATOR, - dmd_write_cap, - ) - - returnValue(invite_code) + # FIXME TODO + # see https://github.com/LeastAuthority/magic-folder/issues/232 + raise NotImplemented diff --git a/src/magic_folder/join.py b/src/magic_folder/join.py index 0fafcee3d..35208e2a6 100644 --- a/src/magic_folder/join.py +++ b/src/magic_folder/join.py @@ -35,23 +35,6 @@ def magic_folder_join(config, invite_code, local_dir, name, poll_interval, autho :return: None or exception is raised on error. """ - fields = invite_code.split(INVITE_SEPARATOR) - if len(fields) != 2: - raise usage.UsageError("Invalid invite code.") - magic_readonly_cap, dmd_write_cap = fields - - if name in config.list_magic_folders(): - raise Exception( - "This client already has a magic-folder named '{}'".format(name) - ) - - author = create_local_author(author_name) - config.create_magic_folder( - name, - local_dir, - config.get_default_state_path(name), - author, - magic_readonly_cap, - dmd_write_cap, - poll_interval, - ) + # FIXME TODO + # https://github.com/LeastAuthority/magic-folder/issues/232 + raise NotImplemented