[mostly] beat login dialog into submission; use DAV singleton instead of making a new DAVCollection in service.js; split up checks from login into their own functions, call them on sync(); check we are logged in before syncing

This commit is contained in:
Dan Mills 2008-03-31 07:20:09 -07:00
Родитель c5ddd41680
Коммит eb446df148
4 изменённых файлов: 141 добавлений и 134 удалений

Просмотреть файл

@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ***** */
const EXPORTED_SYMBOLS = ['DAVCollection'];
const EXPORTED_SYMBOLS = ['DAV', 'DAVCollection'];
const Cc = Components.classes;
const Ci = Components.interfaces;

Просмотреть файл

@ -46,6 +46,7 @@ Cu.import("resource://weave/log4moz.js");
Cu.import("resource://weave/constants.js");
Cu.import("resource://weave/util.js");
Cu.import("resource://weave/crypto.js");
Cu.import("resource://weave/dav.js");
Cu.import("resource://weave/identity.js");
Cu.import("resource://weave/stores.js");
Cu.import("resource://weave/syncCores.js");
@ -115,7 +116,6 @@ Engine.prototype = {
},
_init: function Engine__init(davCollection, pbeId) {
this._dav = davCollection;
this._pbeId = pbeId;
this._engineId = new Identity(pbeId.realm + " - " + this.logName,
pbeId.username);
@ -129,7 +129,7 @@ Engine.prototype = {
_getSymKey: function Engine__getSymKey() {
let self = yield;
this._dav.GET(this.keysFile, self.cb);
DAV.GET(this.keysFile, self.cb);
let keysResp = yield;
Utils.ensureStatus(keysResp.status,
"Could not get keys file.", [[200,300]]);
@ -167,11 +167,11 @@ Engine.prototype = {
this._os.notifyObservers(null, this._osPrefix + "reset-server:start", "");
// try to delete all 3, check status after
this._dav.DELETE(this.statusFile, self.cb);
DAV.DELETE(this.statusFile, self.cb);
let statusResp = yield;
this._dav.DELETE(this.snapshotFile, self.cb);
DAV.DELETE(this.snapshotFile, self.cb);
let snapshotResp = yield;
this._dav.DELETE(this.deltasFile, self.cb);
DAV.DELETE(this.deltasFile, self.cb);
let deltasResp = yield;
Utils.ensureStatus(statusResp.status,
@ -255,7 +255,7 @@ Engine.prototype = {
this._log.info("Beginning sync");
// Before we get started, make sure we have a remote directory to play in
this._dav.MKCOL(this.serverPrefix, self.cb);
DAV.MKCOL(this.serverPrefix, self.cb);
let ret = yield;
if (!ret)
throw "Could not create remote folder";
@ -399,14 +399,14 @@ Engine.prototype = {
this._serializeCommands(server.deltas),
this._engineId);
let data = yield;
this._dav.PUT(this.deltasFile, data, self.cb);
DAV.PUT(this.deltasFile, data, self.cb);
let deltasPut = yield;
let c = 0;
for (GUID in this._snapshot.data)
c++;
this._dav.PUT(this.statusFile,
DAV.PUT(this.statusFile,
this._json.encode(
{GUID: this._snapshot.GUID,
formatVersion: ENGINE_STORAGE_FORMAT_VERSION,
@ -465,7 +465,7 @@ Engine.prototype = {
snapshot: null, deltas: null, updates: null};
this._log.debug("Getting status file from server");
this._dav.GET(this.statusFile, self.cb);
DAV.GET(this.statusFile, self.cb);
let resp = yield;
let status = resp.status;
@ -510,7 +510,7 @@ Engine.prototype = {
this._log.info("Local snapshot is out of date");
this._log.info("Downloading server snapshot");
this._dav.GET(this.snapshotFile, self.cb);
DAV.GET(this.snapshotFile, self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not download snapshot.");
Crypto.PBEdecrypt.async(Crypto, self.cb,
@ -521,7 +521,7 @@ Engine.prototype = {
snap.data = this._json.decode(data);
this._log.info("Downloading server deltas");
this._dav.GET(this.deltasFile, self.cb);
DAV.GET(this.deltasFile, self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not download deltas.");
Crypto.PBEdecrypt.async(Crypto, self.cb,
@ -538,7 +538,7 @@ Engine.prototype = {
snap.data = Utils.deepCopy(this._snapshot.data);
this._log.info("Downloading server deltas");
this._dav.GET(this.deltasFile, self.cb);
DAV.GET(this.deltasFile, self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not download deltas.");
Crypto.PBEdecrypt.async(Crypto, self.cb,
@ -555,7 +555,7 @@ Engine.prototype = {
// FIXME: could optimize this case by caching deltas file
this._log.info("Downloading server deltas");
this._dav.GET(this.deltasFile, self.cb);
DAV.GET(this.deltasFile, self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not download deltas.");
Crypto.PBEdecrypt.async(Crypto, self.cb,
@ -641,7 +641,7 @@ Engine.prototype = {
let keys = {ring: {}};
keys.ring[this._engineId.userHash] = enckey;
this._dav.PUT(this.keysFile, this._json.encode(keys), self.cb);
DAV.PUT(this.keysFile, this._json.encode(keys), self.cb);
let resp = yield;
Utils.ensureStatus(resp.status, "Could not upload keyring file.");
@ -650,11 +650,11 @@ Engine.prototype = {
this._engineId);
let data = yield;
this._dav.PUT(this.snapshotFile, data, self.cb);
DAV.PUT(this.snapshotFile, data, self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not upload snapshot.");
this._dav.PUT(this.deltasFile, "[]", self.cb);
DAV.PUT(this.deltasFile, "[]", self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not upload deltas.");
@ -662,7 +662,7 @@ Engine.prototype = {
for (GUID in this._snapshot.data)
c++;
this._dav.PUT(this.statusFile,
DAV.PUT(this.statusFile,
this._json.encode(
{GUID: this._snapshot.GUID,
formatVersion: ENGINE_STORAGE_FORMAT_VERSION,
@ -681,7 +681,7 @@ Engine.prototype = {
_share: function Engine__share(username) {
let self = yield;
let base = this._dav.baseURL;
let base = DAV.baseURL;
this._log.debug("Sharing bookmarks with " + username);
@ -689,7 +689,7 @@ Engine.prototype = {
yield;
// copied from getSymKey
this._dav.GET(this.keysFile, self.cb);
DAV.GET(this.keysFile, self.cb);
let ret = yield;
Utils.ensureStatus(ret.status, "Could not get keys file.");
let keys = this._json.decode(ret.responseText);
@ -699,12 +699,12 @@ Engine.prototype = {
let serverURL = Utils.prefs.getCharPref("serverURL");
try {
this._dav.baseURL = serverURL + "user/" + hash + "/"; //FIXME: very ugly!
this._dav.GET("public/pubkey", self.cb);
DAV.baseURL = serverURL + "user/" + hash + "/"; //FIXME: very ugly!
DAV.GET("public/pubkey", self.cb);
ret = yield;
}
catch (e) { throw e; }
finally { this._dav.baseURL = base; }
finally { DAV.baseURL = base; }
Utils.ensureStatus(ret.status, "Could not get public key for " + username);
@ -718,7 +718,7 @@ Engine.prototype = {
throw "Could not encrypt symmetric encryption key";
keys.ring[hash] = enckey;
this._dav.PUT(this.keysFile, this._json.encode(keys), self.cb);
DAV.PUT(this.keysFile, this._json.encode(keys), self.cb);
ret = yield;
Utils.ensureStatus(ret.status, "Could not upload keyring file.");
@ -824,7 +824,7 @@ BookmarksEngine.prototype = {
_syncOneMount: function BmkEngine__syncOneMount(mountData) {
let self = yield;
let user = mountData.userid;
let base = this._dav.baseURL;
let base = DAV.baseURL;
let serverURL = Utils.prefs.getCharPref("serverURL");
let snap = new SnapshotStore();
@ -832,19 +832,19 @@ BookmarksEngine.prototype = {
try {
let hash = Utils.sha1(user);
this._dav.baseURL = serverURL + "user/" + hash + "/"; //FIXME: very ugly!
DAV.baseURL = serverURL + "user/" + hash + "/"; //FIXME: very ugly!
this._getSymKey.async(this, self.cb);
yield;
this._log.trace("Getting status file for " + user);
this._dav.GET(this.statusFile, self.cb);
DAV.GET(this.statusFile, self.cb);
let resp = yield;
Utils.ensureStatus(resp.status, "Could not download status file.");
let status = this._json.decode(resp.responseText);
this._log.trace("Downloading server snapshot for " + user);
this._dav.GET(this.snapshotFile, self.cb);
DAV.GET(this.snapshotFile, self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not download snapshot.");
Crypto.PBEdecrypt.async(Crypto, self.cb, resp.responseText,
@ -853,7 +853,7 @@ BookmarksEngine.prototype = {
snap.data = this._json.decode(data);
this._log.trace("Downloading server deltas for " + user);
this._dav.GET(this.deltasFile, self.cb);
DAV.GET(this.deltasFile, self.cb);
resp = yield;
Utils.ensureStatus(resp.status, "Could not download deltas.");
Crypto.PBEdecrypt.async(Crypto, self.cb, resp.responseText,
@ -862,7 +862,7 @@ BookmarksEngine.prototype = {
deltas = this._json.decode(data);
}
catch (e) { throw e; }
finally { this._dav.baseURL = base; }
finally { DAV.baseURL = base; }
// apply deltas to get current snapshot
for (var i = 0; i < deltas.length; i++) {

Просмотреть файл

@ -56,16 +56,16 @@ Function.prototype.async = Async.sugar;
// for export
let Weave = {};
Components.utils.import("resource://weave/constants.js", Weave);
Components.utils.import("resource://weave/util.js", Weave);
Components.utils.import("resource://weave/async.js", Weave);
Components.utils.import("resource://weave/crypto.js", Weave);
Components.utils.import("resource://weave/identity.js", Weave);
Components.utils.import("resource://weave/dav.js", Weave);
Components.utils.import("resource://weave/stores.js", Weave);
Components.utils.import("resource://weave/syncCores.js", Weave);
Components.utils.import("resource://weave/engines.js", Weave);
Components.utils.import("resource://weave/service.js", Weave);
Cu.import("resource://weave/constants.js", Weave);
Cu.import("resource://weave/util.js", Weave);
Cu.import("resource://weave/async.js", Weave);
Cu.import("resource://weave/crypto.js", Weave);
Cu.import("resource://weave/identity.js", Weave);
Cu.import("resource://weave/dav.js", Weave);
Cu.import("resource://weave/stores.js", Weave);
Cu.import("resource://weave/syncCores.js", Weave);
Cu.import("resource://weave/engines.js", Weave);
Cu.import("resource://weave/service.js", Weave);
Utils.lazy(Weave, 'Service', WeaveSvc);
/*
@ -109,32 +109,22 @@ WeaveSvc.prototype = {
return this.__dirSvc;
},
__dav: null,
get _dav() {
if (!this.__dav)
this.__dav = new DAVCollection();
return this.__dav;
},
// FIXME: engines should be loaded dynamically somehow / need API to register
__bmkEngine: null,
get _bmkEngine() {
if (!this.__bmkEngine)
this.__bmkEngine = new BookmarksEngine(this._dav, this._cryptoId);
this.__bmkEngine = new BookmarksEngine(DAV, this._cryptoId);
return this.__bmkEngine;
},
__histEngine: null,
get _histEngine() {
if (!this.__histEngine)
this.__histEngine = new HistoryEngine(this._dav, this._cryptoId);
this.__histEngine = new HistoryEngine(DAV, this._cryptoId);
return this.__histEngine;
},
// Logger object
_log: null,
// Timer object for automagically syncing
_scheduleTimer: null,
@ -176,7 +166,7 @@ WeaveSvc.prototype = {
get userPath() { return this._mozId.userHash; },
get currentUser() {
if (this._dav.loggedIn)
if (DAV.loggedIn)
return this.username;
return null;
},
@ -276,34 +266,15 @@ WeaveSvc.prototype = {
this._debugApp.clear();
},
_createUserDir: function WeaveSync__createUserDir(serverURL) {
let self = yield;
this._log.debug("Attempting to create user directory");
this._dav.baseURL = serverURL;
this._dav.MKCOL("user/" + this.userPath, self.cb);
let ret = yield;
if (!ret)
throw "Could not create user directory";
this._log.debug("Successfully created user directory. Re-attempting login.");
this._dav.baseURL = serverURL + "user/" + this.userPath + "/";
this._dav.login.async(this._dav, self.cb, this.username, this.password);
let success = yield;
if (!success)
throw "Created user directory, but login still failed. Aborting.";
},
_uploadVersion: function WeaveSync__uploadVersion() {
let self = yield;
this._dav.MKCOL("meta", self.cb);
DAV.MKCOL("meta", self.cb);
let ret = yield;
if (!ret)
throw "Could not create meta information directory";
this._dav.PUT("meta/version", STORAGE_FORMAT_VERSION, self.cb);
DAV.PUT("meta/version", STORAGE_FORMAT_VERSION, self.cb);
ret = yield;
Utils.ensureStatus(ret.status, "Could not upload server version file");
},
@ -312,7 +283,7 @@ WeaveSvc.prototype = {
_versionCheck: function WeaveSync__versionCheck() {
let self = yield;
this._dav.GET("meta/version", self.cb);
DAV.GET("meta/version", self.cb);
let ret = yield;
if (!Utils.checkStatus(ret.status)) {
@ -334,6 +305,44 @@ WeaveSvc.prototype = {
}
},
_checkUserDir: function WeaveSvc__checkUserDir() {
let self = yield;
this._log.trace("Checking user directory exists");
let serverURL = Utils.prefs.getCharPref("serverURL");
if (serverURL[serverURL.length-1] != '/')
serverURL = serverURL + '/';
DAV.baseURL = serverURL;
DAV.MKCOL("user/" + this.userPath, self.cb);
let ret = yield;
if (!ret)
throw "Could not create user directory";
DAV.baseURL = serverURL + "user/" + this.userPath + "/";
this._log.info("Using server URL: " + DAV.baseURL);
},
_keyCheck: function WeaveSvc__keyCheck() {
let self = yield;
DAV.GET("private/privkey", self.cb);
let keyResp = yield;
Utils.ensureStatus(keyResp.status,
"Could not get private key from server", [[200,300],404]);
if (keyResp.status != 404) {
this._cryptoId.privkey = keyResp.responseText;
Crypto.RSAkeydecrypt.async(Crypto, self.cb, this._cryptoId);
this._cryptoId.pubkey = yield;
} else {
this._generateKeys.async(this, self.cb);
yield;
}
},
_generateKeys: function WeaveSync__generateKeys() {
let self = yield;
@ -344,21 +353,21 @@ WeaveSvc.prototype = {
this._cryptoId.privkey = privkey;
this._cryptoId.pubkey = pubkey;
this._dav.MKCOL("private/", self.cb);
DAV.MKCOL("private/", self.cb);
let ret = yield;
if (!ret)
throw "Could not create private key directory";
this._dav.MKCOL("public/", self.cb);
DAV.MKCOL("public/", self.cb);
ret = yield;
if (!ret)
throw "Could not create public key directory";
this._dav.PUT("private/privkey", privkey, self.cb);
DAV.PUT("private/privkey", privkey, self.cb);
ret = yield;
Utils.ensureStatus(ret.status, "Could not upload private key");
this._dav.PUT("public/pubkey", pubkey, self.cb);
DAV.PUT("public/pubkey", pubkey, self.cb);
ret = yield;
Utils.ensureStatus(ret.status, "Could not upload public key");
},
@ -400,46 +409,26 @@ WeaveSvc.prototype = {
if (!this.password)
throw "No password given or found in password manager";
let serverURL = Utils.prefs.getCharPref("serverURL");
if (serverURL[serverURL.length-1] != '/')
serverURL = serverURL + '/';
this._dav.baseURL = serverURL + "user/" + this.userPath + "/";
this._log.info("Using server URL: " + this._dav.baseURL);
this._dav.login.async(this._dav, self.cb, this.username, this.password);
let success = yield;
if (!success) {
// FIXME: we should actually limit this to when we get a 404
this._createUserDir.async(this, self.cb, serverURL);
this._checkUserDir.async(this, self.cb);
yield;
}
DAV.login.async(DAV, self.cb, this.username, this.password);
let success = yield;
if (!success)
throw "Login failed";
this._versionCheck.async(this, self.cb);
yield;
this._dav.GET("private/privkey", self.cb);
let keyResp = yield;
Utils.ensureStatus(keyResp.status,
"Could not get private key from server", [[200,300],404]);
if (keyResp.status != 404) {
this._cryptoId.privkey = keyResp.responseText;
Crypto.RSAkeydecrypt.async(Crypto, self.cb, this._cryptoId);
this._cryptoId.pubkey = yield;
} else {
this._generateKeys.async(this, self.cb);
this._keyCheck.async(this, self.cb);
yield;
}
this._passphrase = null;
self.done(true);
},
logout: function WeaveSync_logout() {
this._log.info("Logging out");
this._dav.logout();
DAV.logout();
this._mozId.setTempPassword(null); // clear cached password
this._cryptoId.setTempPassword(null); // and passphrase
this._os.notifyObservers(null, "weave:service:logout:success", "");
@ -450,29 +439,33 @@ WeaveSvc.prototype = {
},
_resetLock: function WeaveSvc__resetLock() {
let self = yield;
this._dav.forceUnlock.async(this._dav, self.cb);
DAV.forceUnlock.async(DAV, self.cb);
yield;
},
serverWipe: function WeaveSvc_serverWipe(onComplete) {
this._lock(this._notify("server-wipe",
this._serverWipe)).async(this, onComplete);
let cb = function WeaveSvc_serverWipeCb() {
let self = yield;
this._serverWipe.async(this, self.cb);
yield;
this.logout();
self.done();
};
this._lock(this._notify("server-wipe", cb)).async(this, onComplete);
},
_serverWipe: function WeaveSvc__serverWipe() {
let self = yield;
this._dav.listFiles.async(this._dav, self.cb);
DAV.listFiles.async(DAV, self.cb);
let names = yield;
for (let i = 0; i < names.length; i++) {
this._dav.DELETE(names[i], self.cb);
DAV.DELETE(names[i], self.cb);
let resp = yield;
this._log.debug(resp.status);
}
},
// These are per-engine
sync: function WeaveSync_sync(onComplete) {
@ -481,6 +474,15 @@ WeaveSvc.prototype = {
_sync: function WeaveSync__sync() {
let self = yield;
if (!DAV.loggedIn)
throw "Can't sync: Not logged in";
this._versionCheck.async(this, self.cb);
yield;
this._keyCheck.async(this, self.cb);
yield;
if (Utils.prefs.getBoolPref("bookmarks")) {
this._notify(this._bmkEngine.name + ":sync",
this._syncEngine, this._bmkEngine).async(this, self.cb);
@ -506,6 +508,10 @@ WeaveSvc.prototype = {
},
_resetServer: function WeaveSync__resetServer() {
let self = yield;
if (!DAV.loggedIn)
throw "Can't reset server: Not logged in";
this._bmkEngine.resetServer(self.cb);
yield;
this._histEngine.resetServer(self.cb);

Просмотреть файл

@ -43,6 +43,7 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://weave/log4moz.js");
Cu.import("resource://weave/dav.js");
Cu.import("resource://weave/async.js");
Function.prototype.async = Async.sugar;
@ -112,7 +113,7 @@ let Wrap = {
let ret;
let args = Array.prototype.slice.call(arguments);
this._dav.lock.async(this._dav, self.cb);
DAV.lock.async(DAV, self.cb);
let locked = yield;
if (!locked)
throw "Could not acquire lock";
@ -127,7 +128,7 @@ let Wrap = {
throw e;
} finally {
this._dav.unlock.async(this._dav, self.cb);
DAV.unlock.async(DAV, self.cb);
yield;
}
@ -146,9 +147,9 @@ let Wrap = {
let ret;
let args = Array.prototype.slice.call(arguments);
if (this._dav.locked)
if (DAV.locked)
throw "Could not acquire lock";
this._dav.allowLock = false;
DAV.allowLock = false;
try {
args = savedArgs.concat(args);
@ -157,7 +158,7 @@ let Wrap = {
ret = yield;
}
catch (e) { throw e; }
finally { this._dav.allowLock = true; }
finally { DAV.allowLock = true; }
self.done(ret);
};