attempt at fixing login/server setup, needs more work still
authorDan Mills <thunder@mozilla.com>
Thu, 20 Nov 2008 09:18:35 +0900
changeset 45041 5e93e7de26922425095218bb8556d388c9e79c8e
parent 45040 23a02fb0477af30090f79be4abb7a953d85fe590
child 45042 e5aee2e3904034475bbbaf0f23b20fa2036d39fd
push idunknown
push userunknown
push dateunknown
attempt at fixing login/server setup, needs more work still
services/sync/modules/service.js
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -177,16 +177,24 @@ WeaveSvc.prototype = {
   },
 
   get password() { return ID.get('WeaveID').password; },
   set password(value) { ID.get('WeaveID').password = value; },
 
   get passphrase() { return ID.get('WeaveCryptoID').password; },
   set passphrase(value) { ID.get('WeaveCryptoID').password = value; },
 
+  // chrome-provided callbacks for when the service needs a password/passphrase
+  set onGetPassword(value) {
+    ID.get('WeaveID').onGetPassword = value;
+  },
+  set onGetPassphrase(value) {
+    ID.get('WeaveCryptoID').onGetPassword = value;
+  },
+
   get baseURL() {
     let url = Utils.prefs.getCharPref("serverURL");
     if (url && url[url.length-1] != '/')
       url = url + '/';
     return url;
   },
   set baseURL(value) {
     Utils.prefs.setCharPref("serverURL", value);
@@ -291,17 +299,18 @@ WeaveSvc.prototype = {
     // Create Weave identities (for logging in, and for encryption)
     ID.set('WeaveID', new Identity('Mozilla Services Password', this.username));
     Auth.defaultAuthenticator = new BasicAuthenticator(ID.get('WeaveID'));
 
     ID.set('WeaveCryptoID',
            new Identity('Mozilla Services Encryption Passphrase', this.username));
 
     let url = this.baseURL + this.username;
-    PubKeys.defaultKeyUri = url + "keys/pubkey";
+    PubKeys.defaultKeyUri = url + "/keys/pubkey";
+    PrivKeys.defaultKeyUri = url + "/keys/privkey";
 
     if (Utils.prefs.getBoolPref("autoconnect") &&
         this.username && this.username != 'nobody')
       try {
         yield this.login(self.cb);
         yield this.sync(self.cb);
       } catch (e) {}
     self.done();
@@ -484,21 +493,66 @@ WeaveSvc.prototype = {
     let cb = function WeaveSvc_serverWipeCb() {
       let self = yield;
       this._log.error("Server wipe not supported");
       this.logout();
     };
     this._notify("server-wipe", "", this._localLock(cb)).async(this, onComplete);
   },
 
+  // stuff we need to to after login, before we can really do
+  // anything (e.g. key setup)
+  _remoteSetup: function WeaveSvc__remoteSetup() {
+    let self = yield;
+    let ret = false; // false to abort sync
+
+    // FIXME: too easy to generate a keypair.  we should be absolutely certain
+    // that the keys are not there (404) and that it's not some other
+    // transient network problem instead
+    let needKeys = true;
+    let pubkey = yield PubKeys.getDefaultKey(self.cb);
+    if (pubkey) {
+      // make sure we have a matching privkey
+      let privkey = yield PrivKeys.get(self.cb, pubkey.privateKeyUri);
+      if (privkey) {
+        needKeys = false;
+        ret = true;
+      }
+    }
+
+    if (needKeys) {
+      let pass = yield ID.get('WeaveCryptoID').getPassword(self.cb);
+      if (pass) {
+        let keys = PubKeys.createKeypair(pass, PubKeys.defaultKeyUri,
+                                         PrivKeys.defaultKeyUri);
+        try {
+          yield keys.pubkey.put(self.cb);
+          yield keys.privkey.put(self.cb);
+          ret = true;
+        } catch (e) {
+          this._log.error("Could not upload keys: " + Utils.exceptionStr(e));
+          this._log.error(keys.pubkey.lastRequest.responseText);
+        }
+      } else {
+        this._log.warn("Could not get encryption passphrase");
+      }
+    }
+
+    self.done(ret);
+  },
+
   // These are per-engine
 
   _sync: function WeaveSvc__sync() {
     let self = yield;
 
+    if (!(yield this._remoteSetup.async(this, self.cb))) {
+      throw "aborting sync, remote setup failed";
+    }
+
     //this._log.debug("Refreshing client list");
     //yield ClientData.refresh(self.cb);
 
     let engines = Engines.getAll();
     for (let i = 0; i < engines.length; i++) {
       if (this.cancelRequested)
         continue;