Move remote init code ('fullUpload') into RemoteStore; make RemoteStore hold an Engine object (tightly coupling them); make the server prefix and identity properties of Engine public

This commit is contained in:
Dan Mills 2008-06-14 17:07:06 +09:00
Родитель 0c475dfe37
Коммит 25f6da01d1
2 изменённых файлов: 75 добавлений и 112 удалений

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

@ -105,7 +105,7 @@ Engine.prototype = {
get _remote() { get _remote() {
if (!this.__remote) if (!this.__remote)
this.__remote = new RemoteStore(this.serverPrefix, 'Engine:' + this.name); this.__remote = new RemoteStore(this);
return this.__remote; return this.__remote;
}, },
@ -161,7 +161,7 @@ Engine.prototype = {
this.__snapshot = value; this.__snapshot = value;
}, },
get _pbeId() { get pbeId() {
let id = ID.get('Engine:PBE:' + this.name); let id = ID.get('Engine:PBE:' + this.name);
if (!id) if (!id)
id = ID.get('Engine:PBE:default'); id = ID.get('Engine:PBE:default');
@ -170,15 +170,15 @@ Engine.prototype = {
return id; return id;
}, },
get _engineId() { get engineId() {
let id = ID.get('Engine:' + this.name); let id = ID.get('Engine:' + this.name);
if (!id || if (!id ||
id.username != this._pbeId.username || id.realm != this._pbeId.realm) { id.username != this.pbeId.username || id.realm != this.pbeId.realm) {
let password = null; let password = null;
if (id) if (id)
password = id.password; password = id.password;
id = new Identity(this._pbeId.realm + ' - ' + this.logName, id = new Identity(this.pbeId.realm + ' - ' + this.logName,
this._pbeId.username, password); this.pbeId.username, password);
ID.set('Engine:' + this.name, id); ID.set('Engine:' + this.name, id);
} }
return id; return id;
@ -194,15 +194,10 @@ Engine.prototype = {
_getSymKey: function Engine__getSymKey() { _getSymKey: function Engine__getSymKey() {
let self = yield; let self = yield;
if ("none" == Utils.prefs.getCharPref("encryption")) if ("none" == Utils.prefs.getCharPref("encryption"))
return; return;
let symkey = yield this._remote.keys.getKey(self.cb, this.pbeId);
this._remote.keys.getKey(self.cb, this._pbeId); this.engineId.setTempPassword(symkey);
let symkey = yield;
this._engineId.setTempPassword(symkey);
self.done();
}, },
_serializeCommands: function Engine__serializeCommands(commands) { _serializeCommands: function Engine__serializeCommands(commands) {
@ -392,13 +387,8 @@ Engine.prototype = {
this._snapshot.data = newSnapshot; this._snapshot.data = newSnapshot;
this._snapshot.version = ++server.maxVersion; this._snapshot.version = ++server.maxVersion;
/* if (server.formatVersion != ENGINE_STORAGE_FORMAT_VERSION)
if (server.formatVersion != ENGINE_STORAGE_FORMAT_VERSION) { yield this._remote.initialize(self.cb, this._snapshot);
this._fullUpload.async(this, self.cb);
let status = yield;
if (!status)
this._log.error("Could not upload files to server"); // eep?
*/
this._remote.appendDelta(self.cb, serverDelta); this._remote.appendDelta(self.cb, serverDelta);
yield; yield;
@ -421,6 +411,15 @@ Engine.prototype = {
self.done(true); self.done(true);
}, },
_initialUpload: function Engine__initialUpload() {
this._log.info("Initial upload to server");
this._snapshot.data = this._store.wrap();
this._snapshot.version = 0;
this._snapshot.GUID = null; // in case there are other snapshots out there
yield this._remote.initialize(self.cb, this._snapshot);
this._snapshot.save();
},
/* Get the deltas/combined updates from the server /* Get the deltas/combined updates from the server
* Returns: * Returns:
* status: * status:
@ -445,7 +444,7 @@ Engine.prototype = {
* the relevant deltas (from our snapshot version to current), * the relevant deltas (from our snapshot version to current),
* combined into a single set. * combined into a single set.
*/ */
_getServerData: function BmkEngine__getServerData() { _getServerData: function Engine__getServerData() {
let self = yield; let self = yield;
let status; let status;
@ -456,20 +455,7 @@ Engine.prototype = {
this._log.info("Got status file from server"); this._log.info("Got status file from server");
} catch (e if e.message.status == 404) { } catch (e if e.message.status == 404) {
this._log.info("Server has no status file, Initial upload to server"); this._initialUpload.async(this, self.cb);
this._snapshot.data = this._store.wrap();
this._snapshot.version = 0;
this._snapshot.GUID = null; // in case there are other snapshots out there
this._fullUpload.async(this, self.cb);
let uploadStatus = yield;
if (!uploadStatus)
throw "Initial upload failed";
this._log.info("Initial upload to server successful");
this._snapshot.save();
self.done({status: 0, self.done({status: 0,
formatVersion: ENGINE_STORAGE_FORMAT_VERSION, formatVersion: ENGINE_STORAGE_FORMAT_VERSION,
maxVersion: this._snapshot.version, maxVersion: this._snapshot.version,
@ -583,55 +569,6 @@ Engine.prototype = {
self.done(ret); self.done(ret);
}, },
_fullUpload: function Engine__fullUpload() {
let self = yield;
let ret = false;
Crypto.PBEkeygen.async(Crypto, self.cb);
let symkey = yield;
this._engineId.setTempPassword(symkey);
if (!this._engineId.password)
throw "Could not generate a symmetric encryption key";
let enckey = this._engineId.password;
if ("none" != Utils.prefs.getCharPref("encryption")) {
Crypto.RSAencrypt.async(Crypto, self.cb,
this._engineId.password, this._pbeId);
enckey = yield;
}
if (!enckey)
throw "Could not encrypt symmetric encryption key";
let keys = {ring: {}};
keys.ring[this._engineId.username] = enckey;
this._remote.keys.put(self.cb, keys);
yield;
this._remote.snapshot.put(self.cb, this._snapshot.wrap());
yield;
this._remote.deltas.put(self.cb, []);
yield;
let c = 0;
for (GUID in this._snapshot.data)
c++;
this._remote.status.put(self.cb,
{GUID: this._snapshot.GUID,
formatVersion: ENGINE_STORAGE_FORMAT_VERSION,
snapVersion: this._snapshot.version,
maxVersion: this._snapshot.version,
snapEncryption: Crypto.defaultAlgorithm,
deltasEncryption: "none",
itemCount: c});
yield;
this._log.info("Full upload to server successful");
ret = true;
self.done(ret);
},
_share: function Engine__share(guid, username) { _share: function Engine__share(guid, username) {
/* This should be overridden by the engine subclass for each datatype. /* This should be overridden by the engine subclass for each datatype.
Implementation should share the data node identified by guid, Implementation should share the data node identified by guid,

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

@ -282,7 +282,7 @@ CryptoFilter.prototype = {
beforePUT: function CryptoFilter_beforePUT(data) { beforePUT: function CryptoFilter_beforePUT(data) {
let self = yield; let self = yield;
this._log.debug("Encrypting data"); this._log.debug("Encrypting data");
Crypto.PBEencrypt.async(Crypto, self.cb, data, ID.get(this._remote.cryptoId)); Crypto.PBEencrypt.async(Crypto, self.cb, data, this._remote.engineId);
let ret = yield; let ret = yield;
self.done(ret); self.done(ret);
}, },
@ -293,7 +293,7 @@ CryptoFilter.prototype = {
if (!this._remote.status.data) if (!this._remote.status.data)
throw "Remote status must be initialized before crypto filter can be used" throw "Remote status must be initialized before crypto filter can be used"
let alg = this._remote.status.data[this._algProp]; let alg = this._remote.status.data[this._algProp];
Crypto.PBEdecrypt.async(Crypto, self.cb, data, ID.get(this._remote.cryptoId)); Crypto.PBEdecrypt.async(Crypto, self.cb, data, this._remote.engineId);
let ret = yield; let ret = yield;
self.done(ret); self.done(ret);
} }
@ -366,26 +366,14 @@ Deltas.prototype = {
} }
}; };
function RemoteStore(serverPrefix, cryptoId) { function RemoteStore(engine) {
this._prefix = serverPrefix; this._engine = engine;
this._cryptoId = cryptoId;
this._log = Log4Moz.Service.getLogger("Service.RemoteStore"); this._log = Log4Moz.Service.getLogger("Service.RemoteStore");
} }
RemoteStore.prototype = { RemoteStore.prototype = {
get serverPrefix() this._prefix, get serverPrefix() this._engine.serverPrefix,
set serverPrefix(value) { get engineId() this._engine.engineId,
this._prefix = value; get pbeId() this._engine.pbeId,
this.status.serverPrefix = value;
this.keys.serverPrefix = value;
this.snapshot.serverPrefix = value;
this.deltas.serverPrefix = value;
},
get cryptoId() this._cryptoId,
set cryptoId(value) {
this.__cryptoId = value;
// FIXME: do we need to reset anything here?
},
get status() { get status() {
let status = new Status(this); let status = new Status(this);
@ -411,15 +399,11 @@ RemoteStore.prototype = {
return deltas; return deltas;
}, },
_initSession: function RStore__initSession(serverPrefix, cryptoId) { _initSession: function RStore__initSession() {
let self = yield; let self = yield;
if (serverPrefix) if (!this.serverPrefix || !this.engineId)
this.serverPrefix = serverPrefix; throw "Cannot initialize RemoteStore: engine has no server prefix or crypto ID";
if (cryptoId)
this.cryptoId = cryptoId;
if (!this.serverPrefix || !this.cryptoId)
throw "RemoteStore: cannot initialize without a server prefix and crypto ID";
this.status.data = null; this.status.data = null;
this.keys.data = null; this.keys.data = null;
@ -438,8 +422,8 @@ RemoteStore.prototype = {
this._inited = true; this._inited = true;
}, },
initSession: function RStore_initSession(onComplete, serverPrefix, cryptoId) { initSession: function RStore_initSession(onComplete) {
this._initSession.async(this, onComplete, serverPrefix, cryptoId); this._initSession.async(this, onComplete);
}, },
closeSession: function RStore_closeSession() { closeSession: function RStore_closeSession() {
@ -450,6 +434,48 @@ RemoteStore.prototype = {
this.deltas.data = null; this.deltas.data = null;
}, },
_initialize: function RStore__initialize(snapshot) {
let self = yield;
let symkey;
if ("none" != Utils.prefs.getCharPref("encryption")) {
symkey = yield Crypto.PBEkeygen.async(Crypto, self.cb);
if (!symkey)
throw "Could not generate a symmetric encryption key";
this.engineId.setTempPassword(symkey);
symkey = yield Crypto.RSAencrypt.async(Crypto, self.cb,
this.engineId.password,
this.pbeId);
if (!symkey)
throw "Could not encrypt symmetric encryption key";
}
let keys = {ring: {}};
keys.ring[this.engineId.username] = symkey;
yield this._remote.keys.put(self.cb, keys);
this.snapshot.put(self.cb, snapshot.data);
this.deltas.put(self.cb, []);
let c = 0;
for (GUID in snapshot.data)
c++;
yield this.status.put(self.cb,
{GUID: snapshot.GUID,
formatVersion: ENGINE_STORAGE_FORMAT_VERSION,
snapVersion: snapshot.version,
maxVersion: snapshot.version,
snapEncryption: Crypto.defaultAlgorithm,
deltasEncryption: Crypto.defaultAlgorithm,
itemCount: c});
this._log.info("Full upload to server successful");
},
initialize: function RStore_initialize(onComplete, snapshot) {
this._initialize.async(this, onComplete, snapshot);
},
_appendDelta: function RStore__appendDelta(delta) { _appendDelta: function RStore__appendDelta(delta) {
let self = yield; let self = yield;
if (this.deltas.data == null) { if (this.deltas.data == null) {