mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge upstream changes
This commit is contained in:
commit
a8ad7d2804
@ -63,7 +63,6 @@ function DAVCollection(baseURL, defaultPrefix) {
|
||||
this.baseURL = baseURL;
|
||||
this.defaultPrefix = defaultPrefix;
|
||||
this._identity = 'DAV:default';
|
||||
this._authProvider = new DummyAuthProvider();
|
||||
this._log = Log4Moz.Service.getLogger("Service.DAV");
|
||||
this._log.level =
|
||||
Log4Moz.Level[Utils.prefs.getCharPref("log.logger.service.dav")];
|
||||
@ -124,16 +123,15 @@ DAVCollection.prototype = {
|
||||
|
||||
path = this._defaultPrefix + path;
|
||||
|
||||
let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
|
||||
request = request.QueryInterface(Ci.nsIDOMEventTarget);
|
||||
let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
|
||||
|
||||
let cb = self.cb;
|
||||
request.addEventListener("load", new Utils.EventListener(cb, "load"), false);
|
||||
request.addEventListener("error", new Utils.EventListener(cb, "error"), false);
|
||||
request = request.QueryInterface(Ci.nsIXMLHttpRequest);
|
||||
let xhrCb = self.cb;
|
||||
|
||||
request.onload = new Utils.EventListener(xhrCb, "load");
|
||||
request.onerror = new Utils.EventListener(xhrCb, "error");
|
||||
request.mozBackgroundRequest = true;
|
||||
request.open(op, this._baseURL + path, true);
|
||||
|
||||
|
||||
// Force cache validation
|
||||
let channel = request.channel;
|
||||
channel = channel.QueryInterface(Ci.nsIRequest);
|
||||
@ -150,15 +148,10 @@ DAVCollection.prototype = {
|
||||
request.setRequestHeader(key, headers[key]);
|
||||
}
|
||||
|
||||
this._authProvider._authFailed = false;
|
||||
request.channel.notificationCallbacks = this._authProvider;
|
||||
|
||||
request.send(data);
|
||||
let event = yield;
|
||||
ret = event.target;
|
||||
|
||||
if (this._authProvider._authFailed)
|
||||
this._log.warn("_makeRequest: authentication failed");
|
||||
if (ret.status < 200 || ret.status >= 300)
|
||||
this._log.warn("_makeRequest: got status " + ret.status);
|
||||
|
||||
@ -316,8 +309,7 @@ DAVCollection.prototype = {
|
||||
this.GET("", self.cb);
|
||||
let resp = yield;
|
||||
|
||||
if (this._authProvider._authFailed ||
|
||||
resp.status < 200 || resp.status >= 300) {
|
||||
if (resp.status < 200 || resp.status >= 300) {
|
||||
self.done(false);
|
||||
return;
|
||||
}
|
||||
@ -339,8 +331,7 @@ DAVCollection.prototype = {
|
||||
"</D:propfind>", self.cb);
|
||||
let resp = yield;
|
||||
|
||||
if (this._authProvider._authFailed ||
|
||||
resp.status < 200 || resp.status >= 300) {
|
||||
if (resp.status < 200 || resp.status >= 300) {
|
||||
self.done(false);
|
||||
yield;
|
||||
}
|
||||
@ -376,8 +367,7 @@ DAVCollection.prototype = {
|
||||
"</D:lockinfo>", self.cb);
|
||||
let resp = yield;
|
||||
|
||||
if (this._authProvider._authFailed ||
|
||||
resp.status < 200 || resp.status >= 300)
|
||||
if (resp.status < 200 || resp.status >= 300)
|
||||
return;
|
||||
|
||||
let tokens = Utils.xpath(resp.responseXML, '//D:locktoken/D:href');
|
||||
@ -413,8 +403,7 @@ DAVCollection.prototype = {
|
||||
this.UNLOCK("lock", self.cb);
|
||||
let resp = yield;
|
||||
|
||||
if (this._authProvider._authFailed ||
|
||||
resp.status < 200 || resp.status >= 300) {
|
||||
if (resp.status < 200 || resp.status >= 300) {
|
||||
self.done(false);
|
||||
yield;
|
||||
}
|
||||
@ -450,154 +439,3 @@ DAVCollection.prototype = {
|
||||
self.done(unlocked);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Auth provider object
|
||||
* Taken from nsMicrosummaryService.js and massaged slightly
|
||||
*/
|
||||
|
||||
function DummyAuthProvider() {}
|
||||
DummyAuthProvider.prototype = {
|
||||
// Implement notification callback interfaces so we can suppress UI
|
||||
// and abort loads for bad SSL certs and HTTP authorization requests.
|
||||
|
||||
// Interfaces this component implements.
|
||||
interfaces: [Ci.nsIBadCertListener,
|
||||
Ci.nsIAuthPromptProvider,
|
||||
Ci.nsIAuthPrompt,
|
||||
Ci.nsIPrompt,
|
||||
Ci.nsIProgressEventSink,
|
||||
Ci.nsIInterfaceRequestor,
|
||||
Ci.nsISupports],
|
||||
|
||||
// Auth requests appear to succeed when we cancel them (since the server
|
||||
// redirects us to a "you're not authorized" page), so we have to set a flag
|
||||
// to let the load handler know to treat the load as a failure.
|
||||
get _authFailed() { return this.__authFailed; },
|
||||
set _authFailed(newValue) { return this.__authFailed = newValue; },
|
||||
|
||||
// nsISupports
|
||||
|
||||
QueryInterface: function DAP_QueryInterface(iid) {
|
||||
if (!this.interfaces.some( function(v) { return iid.equals(v); } ))
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
// nsIAuthPrompt and nsIPrompt need separate implementations because
|
||||
// their method signatures conflict. The other interfaces we implement
|
||||
// within DummyAuthProvider itself.
|
||||
switch(iid) {
|
||||
case Ci.nsIAuthPrompt:
|
||||
return this.authPrompt;
|
||||
case Ci.nsIPrompt:
|
||||
return this.prompt;
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
},
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
|
||||
getInterface: function DAP_getInterface(iid) {
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsIBadCertListener
|
||||
|
||||
// Suppress UI and abort secure loads from servers with bad SSL certificates.
|
||||
|
||||
confirmUnknownIssuer: function DAP_confirmUnknownIssuer(socketInfo, cert, certAddType) {
|
||||
return false;
|
||||
},
|
||||
|
||||
confirmMismatchDomain: function DAP_confirmMismatchDomain(socketInfo, targetURL, cert) {
|
||||
return false;
|
||||
},
|
||||
|
||||
confirmCertExpired: function DAP_confirmCertExpired(socketInfo, cert) {
|
||||
return false;
|
||||
},
|
||||
|
||||
notifyCrlNextupdate: function DAP_notifyCrlNextupdate(socketInfo, targetURL, cert) {
|
||||
},
|
||||
|
||||
// nsIAuthPromptProvider
|
||||
|
||||
getAuthPrompt: function(aPromptReason, aIID) {
|
||||
this._authFailed = true;
|
||||
throw Cr.NS_ERROR_NOT_AVAILABLE;
|
||||
},
|
||||
|
||||
// HTTP always requests nsIAuthPromptProvider first, so it never needs
|
||||
// nsIAuthPrompt, but not all channels use nsIAuthPromptProvider, so we
|
||||
// implement nsIAuthPrompt too.
|
||||
|
||||
// nsIAuthPrompt
|
||||
|
||||
get authPrompt() {
|
||||
var resource = this;
|
||||
return {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrompt]),
|
||||
prompt: function(dialogTitle, text, passwordRealm, savePassword, defaultText, result) {
|
||||
resource._authFailed = true;
|
||||
return false;
|
||||
},
|
||||
promptUsernameAndPassword: function(dialogTitle, text, passwordRealm, savePassword, user, pwd) {
|
||||
resource._authFailed = true;
|
||||
return false;
|
||||
},
|
||||
promptPassword: function(dialogTitle, text, passwordRealm, savePassword, pwd) {
|
||||
resource._authFailed = true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
// nsIPrompt
|
||||
|
||||
get prompt() {
|
||||
var resource = this;
|
||||
return {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrompt]),
|
||||
alert: function(dialogTitle, text) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
alertCheck: function(dialogTitle, text, checkMessage, checkValue) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
confirm: function(dialogTitle, text) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
confirmCheck: function(dialogTitle, text, checkMessage, checkValue) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
confirmEx: function(dialogTitle, text, buttonFlags, button0Title, button1Title, button2Title, checkMsg, checkValue) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
prompt: function(dialogTitle, text, value, checkMsg, checkValue) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
promptPassword: function(dialogTitle, text, password, checkMsg, checkValue) {
|
||||
resource._authFailed = true;
|
||||
return false;
|
||||
},
|
||||
promptUsernameAndPassword: function(dialogTitle, text, username, password, checkMsg, checkValue) {
|
||||
resource._authFailed = true;
|
||||
return false;
|
||||
},
|
||||
select: function(dialogTitle, text, count, selectList, outSelection) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
// nsIProgressEventSink
|
||||
|
||||
onProgress: function DAP_onProgress(aRequest, aContext,
|
||||
aProgress, aProgressMax) {
|
||||
},
|
||||
|
||||
onStatus: function DAP_onStatus(aRequest, aContext,
|
||||
aStatus, aStatusArg) {
|
||||
}
|
||||
};
|
||||
|
@ -570,13 +570,16 @@ Engine.prototype = {
|
||||
},
|
||||
|
||||
_share: function Engine__share(guid, username) {
|
||||
let self = yield;
|
||||
/* 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;
|
||||
self.done();
|
||||
},
|
||||
|
||||
// TODO need a "stop sharing" function.
|
||||
/* TODO need a "stop sharing" function.
|
||||
Actually, stopping an outgoing share and stopping an incoming share
|
||||
are two different things. */
|
||||
|
||||
sync: function Engine_sync(onComplete) {
|
||||
return this._sync.async(this, onComplete);
|
||||
@ -586,7 +589,7 @@ Engine.prototype = {
|
||||
return this._share.async(this, onComplete, guid, username);
|
||||
},
|
||||
|
||||
resetServer: function Engine_resetServer(onComplete) {
|
||||
resetServer: function Engimne_resetServer(onComplete) {
|
||||
this._notify("reset-server", this._resetServer).async(this, onComplete);
|
||||
},
|
||||
|
||||
|
@ -1,9 +1,50 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Bookmarks Sync.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dan Mills <thunder@mozilla.com>
|
||||
* Jono DiCarlo <jdicarlo@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const EXPORTED_SYMBOLS = ['BookmarksEngine'];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
// Annotation to use for shared bookmark folders, incoming and outgoing:
|
||||
const INCOMING_SHARED_ANNO = "weave/shared-incoming";
|
||||
const OUTGOING_SHARED_ANNO = "weave/shared-outgoing";
|
||||
|
||||
Cu.import("resource://weave/log4moz.js");
|
||||
Cu.import("resource://weave/dav.js");
|
||||
Cu.import("resource://weave/util.js");
|
||||
@ -14,6 +55,12 @@ Cu.import("resource://weave/syncCores.js");
|
||||
Cu.import("resource://weave/stores.js");
|
||||
Cu.import("resource://weave/trackers.js");
|
||||
|
||||
/* LONGTERM TODO: when we start working on the ability to share other types
|
||||
of data besides bookmarks, the xmppClient instance should be moved to hang
|
||||
off of Weave.Service instead of hanging off the BookmarksEngine. But for
|
||||
now this is the easiest place to deal with it. */
|
||||
Cu.import("resource://weave/xmpp/xmppClient.js");
|
||||
|
||||
Function.prototype.async = Async.sugar;
|
||||
|
||||
function BookmarksEngine(pbeId) {
|
||||
@ -45,16 +92,177 @@ BookmarksEngine.prototype = {
|
||||
return this.__tracker;
|
||||
},
|
||||
|
||||
syncMounts: function BmkEngine_syncMounts(onComplete) {
|
||||
this._syncMounts.async(this, onComplete);
|
||||
_init: function BmkEngine__init( pbeId ) {
|
||||
this.__proto__.__proto__._init.call( this, pbeId );
|
||||
if ( Utils.prefs.getBoolPref( "xmpp.enabled" ) ) {
|
||||
dump( "Starting XMPP client for bookmark engine..." );
|
||||
this._startXmppClient.async(this);
|
||||
//this._startXmppClient();
|
||||
}
|
||||
},
|
||||
_syncMounts: function BmkEngine__syncMounts() {
|
||||
|
||||
_startXmppClient: function BmkEngine__startXmppClient() {
|
||||
// To be called asynchronously.
|
||||
let self = yield;
|
||||
let mounts = this._store.findMounts();
|
||||
|
||||
// Get serverUrl and realm of the jabber server from preferences:
|
||||
let serverUrl = Utils.prefs.getCharPref( "xmpp.server.url" );
|
||||
let realm = Utils.prefs.getCharPref( "xmpp.server.realm" );
|
||||
|
||||
// TODO once we have ejabberd talking to LDAP, the username/password
|
||||
// for xmpp will be the same as the ones for Weave itself, so we can
|
||||
// read username/password like this:
|
||||
// let clientName = ID.get('WeaveID').username;
|
||||
// let clientPassword = ID.get('WeaveID').password;
|
||||
// until then get these from preferences as well:
|
||||
let clientName = Utils.prefs.getCharPref( "xmpp.client.name" );
|
||||
let clientPassword = Utils.prefs.getCharPref( "xmpp.client.password" );
|
||||
|
||||
let transport = new HTTPPollingTransport( serverUrl, false, 15000 );
|
||||
let auth = new PlainAuthenticator();
|
||||
// TODO use MD5Authenticator instead once we get it working -- plain is
|
||||
// a security hole.
|
||||
this._xmppClient = new XmppClient( clientName,
|
||||
realm,
|
||||
clientPassword,
|
||||
transport,
|
||||
auth );
|
||||
let bmkEngine = this;
|
||||
let messageHandler = {
|
||||
handle: function ( messageText, from ) {
|
||||
/* The callback function for incoming xmpp messages.
|
||||
We expect message text to be either:
|
||||
"share <dir>"
|
||||
(sender offers to share directory dir with us)
|
||||
or "stop <dir>"
|
||||
(sender has stopped sharing directory dir with us.)
|
||||
or "accept <dir>"
|
||||
(sharee has accepted our offer to share our dir.)
|
||||
or "decline <dir>"
|
||||
(sharee has declined our offer to share our dir.)
|
||||
*/
|
||||
let words = messageText.split(" ");
|
||||
let commandWord = words[0];
|
||||
let directoryName = words.slice(1).join(" ");
|
||||
if ( commandWord == "share" ) {
|
||||
bmkEngine._incomingShareOffer( directoryName, from );
|
||||
} else if ( commandWord == "stop" ) {
|
||||
bmkEngine._incomingShareWithdrawn( directoryName, from );
|
||||
}
|
||||
}
|
||||
}
|
||||
this._xmppClient.registerMessageHandler( messageHandler );
|
||||
this._xmppClient.connect( realm, self.cb );
|
||||
yield;
|
||||
if ( this._xmppClient._connectionStatus == this._xmppClient.FAILED ) {
|
||||
this._log.warn( "Weave can't log in to xmpp server: xmpp disabled." );
|
||||
} else if ( this._xmppClient._connectionStatus == this._xmppClient.CONNECTED ) {
|
||||
this._log.info( "Weave logged into xmpp OK." );
|
||||
}
|
||||
yield;
|
||||
self.done();
|
||||
},
|
||||
|
||||
_incomingShareOffer: function BmkEngine__incomingShareOffer( dir, user ) {
|
||||
/* Called when we receive an offer from another user to share a
|
||||
directory.
|
||||
|
||||
TODO what should happen is that we add a notification to the queue
|
||||
telling that the incoming share has been offered; when the offer
|
||||
is accepted we will call createIncomingShare and then
|
||||
updateIncomingShare.
|
||||
|
||||
But since we don't have notification in place yet, I'm going to skip
|
||||
right ahead to creating the incoming share.
|
||||
*/
|
||||
dump( "I was offered the directory " + dir + " from user " + dir );
|
||||
|
||||
},
|
||||
|
||||
_incomingShareWithdrawn: function BmkEngine__incomingShareStop( dir, user ) {
|
||||
/* Called when we receive a message telling us that a user who has
|
||||
already shared a directory with us has chosen to stop sharing
|
||||
the directory.
|
||||
|
||||
TODO Find the incomingShare in our bookmark tree that corresponds
|
||||
to the shared directory, and delete it; add a notification to
|
||||
the queue telling us what has happened.
|
||||
*/
|
||||
},
|
||||
|
||||
_sync: function BmkEngine__sync() {
|
||||
/* After syncing, also call syncMounts to get the
|
||||
incoming shared bookmark folder contents. */
|
||||
let self = yield;
|
||||
this.__proto__.__proto__._sync.async(this, self.cb );
|
||||
yield;
|
||||
this.updateAllIncomingShares(self.cb);
|
||||
yield;
|
||||
self.done();
|
||||
},
|
||||
|
||||
_share: function BmkEngine__share( selectedFolder, username ) {
|
||||
// Return true if success, false if failure.
|
||||
let ret = false;
|
||||
let ans = Cc["@mozilla.org/browser/annotation-service;1"].
|
||||
getService(Ci.nsIAnnotationService);
|
||||
let self = yield;
|
||||
|
||||
/* TODO What should the behavior be if i'm already sharing it with user
|
||||
A and I ask to share it with user B? (This should be prevented by
|
||||
the UI. */
|
||||
|
||||
// Create the outgoing share folder on the server
|
||||
// TODO do I need to call these asynchronously?
|
||||
//this._createOutgoingShare.async( this, selectedFolder, username );
|
||||
//this._updateOutgoingShare.async( this, selectedFolder, username );
|
||||
|
||||
/* Set the annotation on the folder so we know
|
||||
it's an outgoing share: */
|
||||
dump( "I'm in _share.\n" );
|
||||
let folderItemId = selectedFolder.node.itemId;
|
||||
let folderName = selectedFolder.getAttribute( "label" );
|
||||
ans.setItemAnnotation(folderItemId, OUTGOING_SHARED_ANNO, username, 0,
|
||||
ans.EXPIRE_NEVER);
|
||||
// TODO: does this clobber existing annotations?
|
||||
dump( "I set the annotation...\n" );
|
||||
// Send an xmpp message to the share-ee
|
||||
if ( this._xmppClient ) {
|
||||
if ( this._xmppClient._connectionStatus == this._xmppClient.CONNECTED ) {
|
||||
dump( "Gonna send notification...\n" );
|
||||
let msgText = "share " + folderName;
|
||||
this._xmppClient.sendMessage( username, msgText );
|
||||
} else {
|
||||
this._log.info( "XMPP connection not available for share notification." );
|
||||
}
|
||||
}
|
||||
|
||||
/* LONGTERM TODO: in the future when we allow sharing one folder
|
||||
with many people, the value of the annotation can be a whole list
|
||||
of usernames instead of just one. */
|
||||
|
||||
dump( "Bookmark engine shared " +folderName + " with " + username );
|
||||
ret = true;
|
||||
self.done( ret );
|
||||
},
|
||||
|
||||
updateAllIncomingShares: function BmkEngine_updateAllIncoming(onComplete) {
|
||||
this._updateAllIncomingShares.async(this, onComplete);
|
||||
},
|
||||
_updateAllIncomingShares: function BmkEngine__updateAllIncoming() {
|
||||
/* For every bookmark folder in my tree that has the annotation
|
||||
marking it as an incoming shared folder, pull down its latest
|
||||
contents from its owner's account on the server. (This is
|
||||
a one-way data transfer because I can't modify bookmarks that
|
||||
are owned by someone else but shared to me; any changes I make
|
||||
to the folder contents are simply wiped out by the latest
|
||||
server contents.) */
|
||||
let self = yield;
|
||||
let mounts = this._store.findIncomingShares();
|
||||
|
||||
for (i = 0; i < mounts.length; i++) {
|
||||
try {
|
||||
this._syncOneMount.async(this, self.cb, mounts[i]);
|
||||
this._updateIncomingShare.async(this, self.cb, mounts[i]);
|
||||
yield;
|
||||
} catch (e) {
|
||||
this._log.warn("Could not sync shared folder from " + mounts[i].userid);
|
||||
@ -63,13 +271,11 @@ BookmarksEngine.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
// TODO modify this as neccessary since I just moved it from the engine
|
||||
// superclass into BookmarkEngine.
|
||||
_share: function BookmarkEngine__share(guid, username) {
|
||||
_createOutgoingShare: function BmkEngine__createOutgoing(folder, username) {
|
||||
let self = yield;
|
||||
let prefix = DAV.defaultPrefix;
|
||||
|
||||
this._log.debug("Sharing bookmarks with " + username);
|
||||
this._log.debug("Sharing bookmarks from " + guid + " with " + username);
|
||||
|
||||
this._getSymKey.async(this, self.cb);
|
||||
yield;
|
||||
@ -78,6 +284,7 @@ BookmarksEngine.prototype = {
|
||||
DAV.GET(this.keysFile, self.cb);
|
||||
let ret = yield;
|
||||
Utils.ensureStatus(ret.status, "Could not get keys file.");
|
||||
// note: this._json is just an encoder/decoder, no state.
|
||||
let keys = this._json.decode(ret.responseText);
|
||||
|
||||
// get the other user's pubkey
|
||||
@ -107,25 +314,31 @@ BookmarksEngine.prototype = {
|
||||
ret = yield;
|
||||
Utils.ensureStatus(ret.status, "Could not upload keyring file.");
|
||||
|
||||
this._createShare(guid, username, username);
|
||||
|
||||
this._log.debug("All done sharing!");
|
||||
|
||||
// Call Atul's js api for setting htaccess:
|
||||
let api = new Sharing.Api( DAV );
|
||||
api.shareWithUsers( directory, [username], self.cb );
|
||||
let result = yield;
|
||||
|
||||
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.
|
||||
*/
|
||||
_updateOutgoingShare: function BmkEngine__updateOutgoing(guid, username) {
|
||||
/* TODO this needs to have the logic to break the shared bookmark
|
||||
subtree out of the store and put it in a separate file...*/
|
||||
},
|
||||
|
||||
/* TODO it appears that this just creates the folder and puts the
|
||||
annotation on it; the mechanics of sharing must be done when syncing?
|
||||
_stopOutgoingShare: function BmkEngine__stopOutgoingShare( guid, username ) {
|
||||
/* TODO implement this... */
|
||||
},
|
||||
|
||||
Or has that not been done yet at all?
|
||||
Do we have to create a new Mount?
|
||||
_createIncomingShare: function BookmarkEngine__createShare(guid, id, title) {
|
||||
|
||||
/* TODO This used to be called just _createShare, but its semantics
|
||||
have changed slightly -- its purpose now is to create a new empty
|
||||
incoming shared bookmark folder. To do this is mostly the same code,
|
||||
but it will need a few tweaks.
|
||||
*/
|
||||
let bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
@ -160,19 +373,23 @@ BookmarksEngine.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_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) {
|
||||
_updateIncomingShare: function BmkEngine__updateIncomingShare(mountData) {
|
||||
/* Pull down bookmarks from the server for a single incoming
|
||||
shared folder. */
|
||||
|
||||
/* TODO modify this: the old implementation assumes we want to copy
|
||||
everything that the other user has, by pulling down snapshot and
|
||||
diffs and applying the diffs to the snapshot. Instead, now we just
|
||||
want to get a single subfolder and its children, which will be in
|
||||
a separate file. */
|
||||
|
||||
let self = yield;
|
||||
let user = mountData.userid;
|
||||
let prefix = DAV.defaultPrefix;
|
||||
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 {
|
||||
@ -738,11 +955,15 @@ BookmarksStore.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
findMounts: function BStore_findMounts() {
|
||||
findIncomingShares: function BStore_findIncomingShares() {
|
||||
/* Returns list of mount data structures, each of which
|
||||
represents one incoming shared-bookmark folder. */
|
||||
let ret = [];
|
||||
let a = this._ans.getItemsWithAnnotation("weave/mounted-share-id", {});
|
||||
let a = this._ans.getItemsWithAnnotation(INCOMING_SHARED_ANNO, {});
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
let id = this._ans.getItemAnnotation(a[i], "weave/mounted-share-id");
|
||||
/* The value of the incoming-shared annotation is the id of the
|
||||
person who has shared it with us. Get that value: */
|
||||
let id = this._ans.getItemAnnotation(a[i], INCOMING_SHARED_ANNO);
|
||||
ret.push(this._wrapMount(this._getNode(a[i]), id));
|
||||
}
|
||||
return ret;
|
||||
|
@ -427,15 +427,6 @@ WeaveSvc.prototype = {
|
||||
_login: function WeaveSync__login(password, passphrase) {
|
||||
let self = yield;
|
||||
|
||||
// XmlHttpRequests fail when the window that triggers them goes away
|
||||
// because of bug 317600, and the first XmlHttpRequest we do happens
|
||||
// just before the login dialog closes itself (for logins prompted by
|
||||
// that dialog), so it triggers the bug. To work around it, we pause
|
||||
// here and then continue after a 0ms timeout.
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback({ notify: self.cb }, 0, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
yield;
|
||||
|
||||
// cache password & passphrase
|
||||
// if null, we'll try to get them from the pw manager below
|
||||
ID.get('WeaveID').setTempPassword(password);
|
||||
@ -546,10 +537,6 @@ WeaveSvc.prototype = {
|
||||
this._notify(engines[i].name + "-engine:sync",
|
||||
this._syncEngine, engines[i]).async(this, self.cb);
|
||||
yield;
|
||||
if (engines[i].name == "bookmarks") { // FIXME
|
||||
Engines.get("bookmarks").syncMounts(self.cb);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -595,11 +582,6 @@ WeaveSvc.prototype = {
|
||||
// overloaded, we'll contribute to the problem by trying to sync
|
||||
// repeatedly at the maximum rate.
|
||||
this._syncThresholds[engine.name] = INITIAL_THRESHOLD;
|
||||
|
||||
if (engine.name == "bookmarks") { // FIXME
|
||||
Engines.get("bookmarks").syncMounts(self.cb);
|
||||
yield;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._log.debug(engine.name + " score " + score +
|
||||
@ -677,23 +659,27 @@ WeaveSvc.prototype = {
|
||||
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.
|
||||
/* so for instance, if dataType is "bookmarks" then a message
|
||||
"share-bookmarks" will be sent out to any observers who are listening
|
||||
for it. As far as I know, there aren't currently any listeners for
|
||||
"share-bookmarks" but we'll send it out just in case. */
|
||||
dump( "This fails with an Exception: cannot aquire internal lock.\n" );
|
||||
this._lock(this._notify(messageName,
|
||||
this._shareData,
|
||||
dataType,
|
||||
guid,
|
||||
username)).async(this, onComplete);
|
||||
},
|
||||
_shareBookmarks: function WeaveSync__shareBookmarks(dataType,
|
||||
guid,
|
||||
username) {
|
||||
|
||||
_shareData: function WeaveSync__shareData(dataType,
|
||||
guid,
|
||||
username) {
|
||||
let self = yield;
|
||||
if (Engines.get(dataType).enabled)
|
||||
if (!Engines.get(dataType).enabled) {
|
||||
this._log.warn( "Can't share disabled data type: " + dataType );
|
||||
return;
|
||||
}
|
||||
Engines.get(dataType).share(self.cb, guid, username);
|
||||
let ret = yield;
|
||||
self.done(ret);
|
||||
|
@ -53,6 +53,7 @@ XmppClient.prototype = {
|
||||
this._iqResponders = [];
|
||||
this._nextIqId = 0;
|
||||
this._pendingIqs = {};
|
||||
this._callbackOnConnect = null;
|
||||
},
|
||||
|
||||
__parser: null,
|
||||
@ -81,10 +82,17 @@ XmppClient.prototype = {
|
||||
namespace */
|
||||
},
|
||||
|
||||
_finishConnectionAttempt: function() {
|
||||
if ( this._callbackOnConnect ) {
|
||||
this._callbackOnConnect.call();
|
||||
}
|
||||
},
|
||||
|
||||
setError: function( errorText ) {
|
||||
LOG( "Error: " + errorText );
|
||||
this._error = errorText;
|
||||
this._connectionStatus = this.FAILED;
|
||||
this._finishConnectionAttempt();
|
||||
},
|
||||
|
||||
onIncomingData: function( messageText ) {
|
||||
@ -126,17 +134,19 @@ XmppClient.prototype = {
|
||||
}
|
||||
|
||||
// Message is parseable, now look for message-level errors.
|
||||
|
||||
var rootElem = responseDOM.documentElement;
|
||||
|
||||
var errors = rootElem.getElementsByTagName( "stream:error" );
|
||||
if ( errors.length > 0 ) {
|
||||
this.setError( errors[0].firstChild.nodeName );
|
||||
return;
|
||||
}
|
||||
errors = rootElem.getElementsByTagName( "error" );
|
||||
if ( errors.length > 0 ) {
|
||||
this.setError( errors[0].firstChild.nodeName );
|
||||
return;
|
||||
}
|
||||
|
||||
// Stream is valid.
|
||||
|
||||
// Detect and handle mid-authentication steps.
|
||||
if ( this._connectionStatus == this.CALLED_SERVER ) {
|
||||
// skip TLS, go straight to SALS. (encryption should be negotiated
|
||||
@ -148,7 +158,7 @@ XmppClient.prototype = {
|
||||
this.setError( this._authenticationLayer.getError() );
|
||||
} else if ( response == this._authenticationLayer.COMPLETION_CODE ){
|
||||
this._connectionStatus = this.CONNECTED;
|
||||
LOG( "We be connected!!" );
|
||||
this._finishConnectionAttempt();
|
||||
} else {
|
||||
this._transportLayer.send( response );
|
||||
}
|
||||
@ -296,12 +306,16 @@ XmppClient.prototype = {
|
||||
this.setError( errorText );
|
||||
},
|
||||
|
||||
connect: function( host ) {
|
||||
// Do the handshake to connect with the server and authenticate.
|
||||
connect: function( host, callback ) {
|
||||
/* Do the handshake to connect with the server and authenticate.
|
||||
callback is optional: if provided, it will be called (with no arguments)
|
||||
when the connection has either succeeded or failed. */
|
||||
if ( callback ) {
|
||||
this._callbackOnConnect = callback;
|
||||
}
|
||||
this._transportLayer.connect();
|
||||
this._transportLayer.setCallbackObject( this );
|
||||
this._transportLayer.send( this._makeHeaderXml( host ) );
|
||||
|
||||
this._connectionStatus = this.CALLED_SERVER;
|
||||
// Now we wait... the rest of the protocol will be driven by
|
||||
// onIncomingData.
|
||||
|
@ -31,3 +31,10 @@ pref("extensions.weave.log.logger.service.crypto", "Debug");
|
||||
pref("extensions.weave.log.logger.service.dav", "Debug");
|
||||
pref("extensions.weave.log.logger.service.engine", "Debug");
|
||||
pref("extensions.weave.log.logger.service.main", "Trace");
|
||||
|
||||
pref("extensions.weave.xmpp.enabled", true);
|
||||
pref("extensions.weave.xmpp.server.url",
|
||||
"http://sm-labs01.mozilla.org:5280/http-poll");
|
||||
pref("extensions.weave.xmpp.server.realm", "sm-labs01.mozilla.org");
|
||||
pref("extensions.weave.xmpp.client.name", "");
|
||||
pref("extensions.weave.xmpp.client.password", "");
|
||||
|
Loading…
Reference in New Issue
Block a user