From 24ddd90b4504da4eba7621d4c97085e33a251850 Mon Sep 17 00:00:00 2001
From: David Stainton <dstainton415@gmail.com>
Date: Mon, 22 Jun 2015 23:29:02 -0700
Subject: [PATCH] Implement most of the join command

---
 src/allmydata/scripts/magic_folder_cli.py   | 66 ++++++++++++++-------
 src/allmydata/test/test_cli_magic_folder.py |  6 ++
 2 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/src/allmydata/scripts/magic_folder_cli.py b/src/allmydata/scripts/magic_folder_cli.py
index 5a88ff75..99cb7115 100644
--- a/src/allmydata/scripts/magic_folder_cli.py
+++ b/src/allmydata/scripts/magic_folder_cli.py
@@ -7,6 +7,10 @@ from allmydata.scripts.common import BaseOptions
 from .common import BaseOptions, BasedirOptions, get_aliases
 from .cli import MakeDirectoryOptions, ListOptions, LnOptions
 import tahoe_ls, tahoe_mv
+from allmydata.util import fileutil
+
+
+INVITE_SEPERATOR = "~"
 
 class CreateOptions(BasedirOptions):
     nickname = None
@@ -27,19 +31,6 @@ def create(options):
     rc = tahoe_add_alias.create_alias(options)
     return rc
 
-class InviteOptions(BasedirOptions):
-    nickname = None
-    synopsis = "MAGIC_ALIAS: NICKNAME"
-    stdin = StringIO("")
-    def parseArgs(self, alias, nickname=None):
-        BasedirOptions.parseArgs(self)
-        self.alias = alias
-        self.nickname = nickname
-        node_url_file = os.path.join(self['node-directory'], "node.url")
-        self['node-url'] = open(node_url_file, "r").read().strip()
-        aliases = get_aliases(self['node-directory'])
-        self.aliases = aliases
-
 def diminish_readonly(write_cap, node_url):
     """
     given a write cap and a node url I will return the corresponding readcap
@@ -62,27 +53,40 @@ def diminish_readonly(write_cap, node_url):
     readonly_cap = json.loads(ls_json)[1][u"ro_uri"]
     return readonly_cap
 
+class InviteOptions(BasedirOptions):
+    nickname = None
+    synopsis = "MAGIC_ALIAS: NICKNAME"
+    stdin = StringIO("")
+    def parseArgs(self, alias, nickname=None):
+        BasedirOptions.parseArgs(self)
+        self.alias = alias
+        self.nickname = nickname
+        node_url_file = os.path.join(self['node-directory'], "node.url")
+        self['node-url'] = open(node_url_file, "r").read().strip()
+        aliases = get_aliases(self['node-directory'])
+        self.aliases = aliases
+
 def invite(options):
     from allmydata.scripts import tahoe_mkdir
     mkdir_options = MakeDirectoryOptions()
     mkdir_options.where = None
-    mkdir_options.stdout = options.stdout
-    mkdir_options.stdin = options.stdin
-    mkdir_options.stderr = options.stderr
-    mkdir_options['node-url'] = options['node-url']
+    mkdir_options.stdin = StringIO("")
+    mkdir_options.stdout = StringIO()
+    mkdir_options.stderr = StringIO()
     mkdir_options.aliases = options.aliases
+    mkdir_options['node-url'] = options['node-url']
     mkdir_options['node-directory'] = options['node-directory']
 
     rc = tahoe_mkdir.mkdir(mkdir_options)
     if rc != 0:
         # XXX failure
-        print "tahoe mkdir FAIL"
+        print >>options.stderr, "magic-folder: failed to mkdir\n"
         return rc
     dmd_write_cap = mkdir_options.stdout.getvalue().strip()
     dmd_readonly_cap = diminish_readonly(dmd_write_cap, options["node-url"])
     if dmd_readonly_cap is None:
         # XXX failure
-        print "failure to diminish dmd write cap"
+        print >>options.stderr, "magic-folder: failed to diminish dmd write cap\n"
         return -1
 
     magic_write_cap = get_aliases(options["node-directory"])[options.alias]
@@ -100,16 +104,32 @@ def invite(options):
     rc = tahoe_mv.mv(ln_options, mode="link")
     if rc != 0:
         # XXX failure
-        print "tahoe ln FAIL"
+        print >>options.stderr, "magic-folder: failed to create link\n"
         return -1
-    print "\ninvite code:\n%s-%s\n" % (magic_readonly_cap, dmd_write_cap)
+
+    print >>options.stdout, "%s%s%s" % (magic_readonly_cap, INVITE_SEPERATOR, dmd_write_cap)
     return rc
 
 class JoinOptions(BasedirOptions):
-    pass
+    synopsis = "INVITE_CODE LOCAL_DIR"
+    def parseArgs(self, invite_code, local_dir):
+        BasedirOptions.parseArgs(self)
+        self.invite_code = invite_code
+        self.local_dir = local_dir
 
 def join(options):
-    pass
+    fields = options.invite_code.split(INVITE_SEPERATOR)
+    assert len(fields) == 2
+    magic_readonly_cap, dmd_write_cap = fields
+
+    dmd_cap_file = os.path.join(options["node-directory"], "private/magic_folder_dircap")
+    fileutil.write(dmd_cap_file, dmd_write_cap)
+
+    collective_readcap_file = os.path.join(options["node-directory"], "private/collective_dircap")
+    fileutil.write(collective_readcap_file, magic_readonly_cap)
+
+    # Edit the client's tahoe.cfg to set [magic_folder] enabled = True and [magic_folder] local.directory = LOCAL_DIR.
+    # ...
 
 class MagicFolderCommand(BaseOptions):
     subCommands = [
diff --git a/src/allmydata/test/test_cli_magic_folder.py b/src/allmydata/test/test_cli_magic_folder.py
index 820ac446..c65a93b6 100644
--- a/src/allmydata/test/test_cli_magic_folder.py
+++ b/src/allmydata/test/test_cli_magic_folder.py
@@ -28,9 +28,15 @@ class CreateMagicFolder(GridTestMixin, CLITestMixin, unittest.TestCase):
         d = self.do_cli("magic-folder", "invite", u"magic", u"Alice")
         return d
 
+    def _join(self, result):
+        invite_code = result[1].strip()
+        d = self.do_cli("magic-folder", "join", invite_code, u"LOCAL_DIR")
+        return d
+
     def test_create_invite_join(self):
         self.basedir = "cli/MagicFolder/create-invite-join"
         self.set_up_grid()
         d = self._create_magic_folder()
         d.addCallback(self._invite)
+        d.addCallback(self._join)
         return d
-- 
2.45.2