зеркало из https://github.com/mozilla/gecko-dev.git
merging branches
This commit is contained in:
Коммит
d5a40e3690
|
@ -68,11 +68,11 @@ AsyncException.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
function Generator(object, method, onComplete, args) {
|
||||
function Generator(thisArg, method, onComplete, args) {
|
||||
this._log = Log4Moz.Service.getLogger("Async.Generator");
|
||||
this._log.level =
|
||||
Log4Moz.Level[Utils.prefs.getCharPref("log.logger.async")];
|
||||
this._object = object;
|
||||
this._thisArg = thisArg;
|
||||
this._method = method;
|
||||
this.onComplete = onComplete;
|
||||
this._args = args;
|
||||
|
@ -93,11 +93,11 @@ Generator.prototype = {
|
|||
},
|
||||
get listener() { return new Utils.EventListener(this.cb); },
|
||||
|
||||
get _object() { return this.__object; },
|
||||
set _object(value) {
|
||||
get _thisArg() { return this.__thisArg; },
|
||||
set _thisArg(value) {
|
||||
if (typeof value != "object")
|
||||
throw "Generator: expected type 'object', got type '" + typeof(value) + "'";
|
||||
this.__object = value;
|
||||
this.__thisArg = value;
|
||||
},
|
||||
|
||||
get _method() { return this.__method; },
|
||||
|
@ -161,7 +161,7 @@ Generator.prototype = {
|
|||
run: function AsyncGen_run() {
|
||||
this._continued = false;
|
||||
try {
|
||||
this._generator = this._method.apply(this._object, this._args);
|
||||
this._generator = this._method.apply(this._thisArg, this._args);
|
||||
this.generator.next(); // must initialize before sending
|
||||
this.generator.send(this);
|
||||
} catch (e) {
|
||||
|
@ -267,9 +267,9 @@ Async = {
|
|||
// where fooGen is a generator function, and gen is a Generator instance
|
||||
// ret is whatever the generator 'returns' via Generator.done().
|
||||
|
||||
run: function Async_run(object, method, onComplete /* , arg1, arg2, ... */) {
|
||||
run: function Async_run(thisArg, method, onComplete /* , arg1, arg2, ... */) {
|
||||
let args = Array.prototype.slice.call(arguments, 3);
|
||||
let gen = new Generator(object, method, onComplete, args);
|
||||
let gen = new Generator(thisArg, method, onComplete, args);
|
||||
gen.run();
|
||||
return gen;
|
||||
},
|
||||
|
@ -287,9 +287,9 @@ Async = {
|
|||
// Note that 'this' refers to the method being called, not the
|
||||
// Async object.
|
||||
|
||||
sugar: function Async_sugar(object, onComplete /* , arg1, arg2, ... */) {
|
||||
sugar: function Async_sugar(thisArg, onComplete /* , arg1, arg2, ... */) {
|
||||
let args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(object, this);
|
||||
args.unshift(thisArg, this);
|
||||
Async.run.apply(Async, args);
|
||||
},
|
||||
|
||||
|
|
|
@ -649,95 +649,21 @@ Engine.prototype = {
|
|||
self.done(ret);
|
||||
},
|
||||
|
||||
_share: function Engine__share(username) {
|
||||
let self = yield;
|
||||
let prefix = DAV.defaultPrefix;
|
||||
|
||||
this._log.debug("Sharing bookmarks with " + username);
|
||||
|
||||
this._getSymKey.async(this, self.cb);
|
||||
yield;
|
||||
|
||||
// copied from getSymKey
|
||||
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);
|
||||
|
||||
// get the other user's pubkey
|
||||
let serverURL = Utils.prefs.getCharPref("serverURL");
|
||||
try {
|
||||
DAV.defaultPrefix = "user/" + username + "/"; //FIXME: very ugly!
|
||||
DAV.GET("public/pubkey", self.cb);
|
||||
ret = yield;
|
||||
}
|
||||
catch (e) { throw e; }
|
||||
finally { DAV.defaultPrefix = prefix; }
|
||||
|
||||
Utils.ensureStatus(ret.status, "Could not get public key for " + username);
|
||||
|
||||
let id = new Identity();
|
||||
id.pubkey = ret.responseText;
|
||||
|
||||
// now encrypt the symkey with their pubkey and upload the new keyring
|
||||
Crypto.RSAencrypt.async(Crypto, self.cb, this._engineId.password, id);
|
||||
let enckey = yield;
|
||||
if (!enckey)
|
||||
throw "Could not encrypt symmetric encryption key";
|
||||
|
||||
keys.ring[username] = enckey;
|
||||
DAV.PUT(this.keysFile, this._json.encode(keys), self.cb);
|
||||
ret = yield;
|
||||
Utils.ensureStatus(ret.status, "Could not upload keyring file.");
|
||||
|
||||
this._createShare(username, username);
|
||||
|
||||
this._log.debug("All done sharing!");
|
||||
|
||||
self.done(true);
|
||||
_share: function Engine__share(guid, username) {
|
||||
/* This should be overridden by the engine subclass for each datatype.
|
||||
Implementation should share the data node identified by guid,
|
||||
and all its children, if any, with the user identified by username. */
|
||||
return;
|
||||
},
|
||||
|
||||
// FIXME: EEK bookmarks specific
|
||||
_createShare: function Engine__createShare(id, title) {
|
||||
let bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
let ans = Cc["@mozilla.org/browser/annotation-service;1"].
|
||||
getService(Ci.nsIAnnotationService);
|
||||
|
||||
let root;
|
||||
let a = ans.getItemsWithAnnotation("weave/mounted-shares-folder", {});
|
||||
if (a.length == 1)
|
||||
root = a[0];
|
||||
|
||||
if (!root) {
|
||||
root = bms.createFolder(bms.toolbarFolder, "Shared Folders",
|
||||
bms.DEFAULT_INDEX);
|
||||
ans.setItemAnnotation(root, "weave/mounted-shares-folder", true, 0,
|
||||
ans.EXPIRE_NEVER);
|
||||
}
|
||||
|
||||
let item;
|
||||
a = ans.getItemsWithAnnotation("weave/mounted-share-id", {});
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (ans.getItemAnnotation(a[i], "weave/mounted-share-id") == id) {
|
||||
item = a[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
let newId = bms.createFolder(root, title, bms.DEFAULT_INDEX);
|
||||
ans.setItemAnnotation(newId, "weave/mounted-share-id", id, 0,
|
||||
ans.EXPIRE_NEVER);
|
||||
}
|
||||
},
|
||||
// TODO need a "stop sharing" function.
|
||||
|
||||
sync: function Engine_sync(onComplete) {
|
||||
return this._sync.async(this, onComplete);
|
||||
},
|
||||
|
||||
share: function Engine_share(onComplete, username) {
|
||||
return this._share.async(this, onComplete, username);
|
||||
share: function Engine_share(onComplete, guid, username) {
|
||||
return this._share.async(this, onComplete, guid, username);
|
||||
},
|
||||
|
||||
resetServer: function Engine_resetServer(onComplete) {
|
||||
|
|
|
@ -63,6 +63,108 @@ BookmarksEngine.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
// TODO modify this as neccessary since I just moved it from the engine
|
||||
// superclass into BookmarkEngine.
|
||||
_share: function BookmarkEngine__share(guid, username) {
|
||||
let self = yield;
|
||||
let prefix = DAV.defaultPrefix;
|
||||
|
||||
this._log.debug("Sharing bookmarks with " + username);
|
||||
|
||||
this._getSymKey.async(this, self.cb);
|
||||
yield;
|
||||
|
||||
// copied from getSymKey
|
||||
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);
|
||||
|
||||
// get the other user's pubkey
|
||||
let serverURL = Utils.prefs.getCharPref("serverURL");
|
||||
|
||||
try {
|
||||
DAV.defaultPrefix = "user/" + username + "/";
|
||||
DAV.GET("public/pubkey", self.cb);
|
||||
ret = yield;
|
||||
}
|
||||
catch (e) { throw e; }
|
||||
finally { DAV.defaultPrefix = prefix; }
|
||||
|
||||
Utils.ensureStatus(ret.status, "Could not get public key for " + username);
|
||||
|
||||
let id = new Identity();
|
||||
id.pubkey = ret.responseText;
|
||||
|
||||
// now encrypt the symkey with their pubkey and upload the new keyring
|
||||
Crypto.RSAencrypt.async(Crypto, self.cb, this._engineId.password, id);
|
||||
let enckey = yield;
|
||||
if (!enckey)
|
||||
throw "Could not encrypt symmetric encryption key";
|
||||
|
||||
keys.ring[username] = enckey;
|
||||
DAV.PUT(this.keysFile, this._json.encode(keys), self.cb);
|
||||
ret = yield;
|
||||
Utils.ensureStatus(ret.status, "Could not upload keyring file.");
|
||||
|
||||
this._createShare(guid, username, username);
|
||||
|
||||
this._log.debug("All done sharing!");
|
||||
|
||||
self.done(true);
|
||||
},
|
||||
|
||||
_createShare: function BookmarkEngine__createShare(guid, id, title) {
|
||||
/* the bookmark item identified by guid, and the whole subtree under it,
|
||||
must be copied out from the main file into a separate file which is
|
||||
put into the new directory and encrypted with the key in the keychain.
|
||||
id is the userid of the user we're sharing with.
|
||||
*/
|
||||
|
||||
/* TODO it appears that this just creates the folder and puts the
|
||||
annotation on it; the mechanics of sharing must be done when syncing?
|
||||
|
||||
Or has that not been done yet at all?
|
||||
Do we have to create a new Mount?
|
||||
*/
|
||||
let bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
let ans = Cc["@mozilla.org/browser/annotation-service;1"].
|
||||
getService(Ci.nsIAnnotationService);
|
||||
|
||||
let root;
|
||||
let a = ans.getItemsWithAnnotation("weave/mounted-shares-folder", {});
|
||||
if (a.length == 1)
|
||||
root = a[0];
|
||||
|
||||
if (!root) {
|
||||
root = bms.createFolder(bms.toolbarFolder, "Shared Folders",
|
||||
bms.DEFAULT_INDEX);
|
||||
ans.setItemAnnotation(root, "weave/mounted-shares-folder", true, 0,
|
||||
ans.EXPIRE_NEVER);
|
||||
}
|
||||
|
||||
let item;
|
||||
a = ans.getItemsWithAnnotation("weave/mounted-share-id", {});
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (ans.getItemAnnotation(a[i], "weave/mounted-share-id") == id) {
|
||||
item = a[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!item) {
|
||||
let newId = bms.createFolder(root, title, bms.DEFAULT_INDEX);
|
||||
ans.setItemAnnotation(newId, "weave/mounted-share-id", id, 0,
|
||||
ans.EXPIRE_NEVER);
|
||||
}
|
||||
},
|
||||
|
||||
_stopShare: function BookmarkeEngine__stopShare( guid, username) {
|
||||
// TODO implement this; also give a way to call it from outside
|
||||
// the service.
|
||||
},
|
||||
|
||||
_syncOneMount: function BmkEngine__syncOneMount(mountData) {
|
||||
let self = yield;
|
||||
let user = mountData.userid;
|
||||
|
@ -70,10 +172,11 @@ BookmarksEngine.prototype = {
|
|||
let serverURL = Utils.prefs.getCharPref("serverURL");
|
||||
let snap = new SnapshotStore();
|
||||
|
||||
// TODO this is obviously what we want.
|
||||
this._log.debug("Syncing shared folder from user " + user);
|
||||
|
||||
try {
|
||||
DAV.defaultPrefix = "user/" + user + "/"; //FIXME: very ugly!
|
||||
DAV.defaultPrefix = "user/" + user + "/";
|
||||
|
||||
this._getSymKey.async(this, self.cb);
|
||||
yield;
|
||||
|
@ -354,6 +457,9 @@ BookmarksStore.prototype = {
|
|||
command.data.index);
|
||||
break;
|
||||
case "mounted-share":
|
||||
// TODO this is to create the shared-items folder on another machine
|
||||
// to duplicate the one that's on the first machine; we don't need that
|
||||
// anymore. OR is it to create the folder on the sharee's computer?
|
||||
this._log.debug(" -> creating share mountpoint \"" + command.data.title + "\"");
|
||||
newId = this._bms.createFolder(parentId,
|
||||
command.data.title,
|
||||
|
@ -518,6 +624,8 @@ BookmarksStore.prototype = {
|
|||
|
||||
} else if (this._ans.itemHasAnnotation(node.itemId,
|
||||
"weave/mounted-share-id")) {
|
||||
/* TODO this is for wrapping the special shared folder created by
|
||||
the old-style share command. */
|
||||
item.type = "mounted-share";
|
||||
item.title = node.title;
|
||||
item.mountId = this._ans.getItemAnnotation(node.itemId,
|
||||
|
@ -608,6 +716,7 @@ BookmarksStore.prototype = {
|
|||
|
||||
// remove any share mountpoints
|
||||
for (let guid in ret.snapshot) {
|
||||
// TODO decide what to do with this...
|
||||
if (ret.snapshot[guid].type == "mounted-share")
|
||||
delete ret.snapshot[guid];
|
||||
}
|
||||
|
|
|
@ -561,16 +561,37 @@ WeaveSvc.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
shareBookmarks: function WeaveSync_shareBookmarks(onComplete, username) {
|
||||
this._lock(this._notify("share-bookmarks",
|
||||
this._shareBookmarks,
|
||||
shareData: function WeaveSync_shareData(dataType,
|
||||
onComplete,
|
||||
guid,
|
||||
username) {
|
||||
/* Shares data of the specified datatype (which must correspond to
|
||||
one of the registered engines) with the user specified by username.
|
||||
The data node indicated by guid will be shared, along with all its
|
||||
children, if it has any. onComplete is a function that will be called
|
||||
when sharing is done; it takes an argument that will be true or false
|
||||
to indicate whether sharing succeeded or failed.
|
||||
Implementation, as well as the interpretation of what 'guid' means,
|
||||
is left up to the engine for the specific dataType. */
|
||||
|
||||
// TODO who is listening for the share-bookmarks message?
|
||||
let messageName = "share-" + dataType;
|
||||
// so for instance, if dataType is "bookmarks" then a message
|
||||
// "share-bookmarks" will be sent out to any observers who are listening
|
||||
// for it.
|
||||
this._lock(this._notify(messageName,
|
||||
this._shareData,
|
||||
dataType,
|
||||
guid,
|
||||
username)).async(this, onComplete);
|
||||
},
|
||||
_shareBookmarks: function WeaveSync__shareBookmarks(username) {
|
||||
_shareBookmarks: function WeaveSync__shareBookmarks(dataType,
|
||||
guid,
|
||||
username) {
|
||||
let self = yield;
|
||||
if (Engines.get("bookmarks").enabled)
|
||||
if (Engines.get(dataType).enabled)
|
||||
return;
|
||||
Engines.get("bookmarks").share(self.cb, username);
|
||||
Engines.get(dataType).share(self.cb, guid, username);
|
||||
let ret = yield;
|
||||
self.done(ret);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче