Bug 675823 - Part 1: Implement SendCredentialsController. r=rnewman

This commit is contained in:
Philipp von Weitershausen 2011-10-02 01:16:22 -07:00
Родитель d300f82819
Коммит 66d8a89fa7
4 изменённых файлов: 185 добавлений и 3 удалений

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

@ -52,7 +52,8 @@ let lazies = {
"identity.js": ["Identity", "ID"], "identity.js": ["Identity", "ID"],
"jpakeclient.js": ["JPAKEClient"], "jpakeclient.js": ["JPAKEClient"],
"notifications.js": ["Notifications", "Notification", "NotificationButton"], "notifications.js": ["Notifications", "Notification", "NotificationButton"],
"policies.js": ["SyncScheduler", "ErrorHandler"], "policies.js": ["SyncScheduler", "ErrorHandler",
"SendCredentialsController"],
"resource.js": ["Resource", "AsyncResource", "Auth", "resource.js": ["Resource", "AsyncResource", "Auth",
"BasicAuthenticator", "NoOpAuthenticator"], "BasicAuthenticator", "NoOpAuthenticator"],
"service.js": ["Service"], "service.js": ["Service"],

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

@ -37,8 +37,9 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
const EXPORTED_SYMBOLS = ["SyncScheduler",
const EXPORTED_SYMBOLS = ["SyncScheduler", "ErrorHandler"]; "ErrorHandler",
"SendCredentialsController"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
@ -736,3 +737,91 @@ let ErrorHandler = {
} }
}, },
}; };
/**
* Send credentials over an active J-PAKE channel.
*
* This object is designed to take over as the JPAKEClient controller,
* presumably replacing one that is UI-based which would either cause
* DOM objects to leak or the JPAKEClient to be GC'ed when the DOM
* context disappears. This object stays alive for the duration of the
* transfer by being strong-ref'ed as an nsIObserver.
*
* Credentials are sent after the first sync has been completed
* (successfully or not.)
*
* Usage:
*
* jpakeclient.controller = new SendCredentialsController(jpakeclient);
*
*/
function SendCredentialsController(jpakeclient) {
this._log = Log4Moz.repository.getLogger("Sync.SendCredentialsController");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")];
this._log.trace("Loading.");
this.jpakeclient = jpakeclient;
// Register ourselves as observers the first Sync finishing (either
// successfully or unsuccessfully, we don't care) or for removing
// this device's sync configuration, in case that happens while we
// haven't finished the first sync yet.
Services.obs.addObserver(this, "weave:service:sync:finish", false);
Services.obs.addObserver(this, "weave:service:sync:error", false);
Services.obs.addObserver(this, "weave:service:start-over", false);
}
SendCredentialsController.prototype = {
unload: function unload() {
this._log.trace("Unloading.");
try {
Services.obs.removeObserver(this, "weave:service:sync:finish");
Services.obs.removeObserver(this, "weave:service:sync:error");
Services.obs.removeObserver(this, "weave:service:start-over");
} catch (ex) {
// Ignore.
}
},
observe: function observe(subject, topic, data) {
switch (topic) {
case "weave:service:sync:finish":
case "weave:service:sync:error":
Utils.nextTick(this.sendCredentials, this);
break;
case "weave:service:start-over":
// This will call onAbort which will call unload().
this.jpakeclient.abort();
break;
}
},
sendCredentials: function sendCredentials() {
this._log.trace("Sending credentials.");
let credentials = {account: Weave.Service.account,
password: Weave.Service.password,
synckey: Weave.Service.passphrase,
serverURL: Weave.Service.serverURL};
this.jpakeclient.sendAndComplete(credentials);
},
// JPAKEClient controller API
onComplete: function onComplete() {
this._log.debug("Exchange was completed successfully!");
this.unload();
},
onAbort: function onAbort(error) {
// It doesn't really matter why we aborted, but the channel is closed
// for sure, so we won't be able to do anything with it.
this._log.debug("Exchange was aborted with error: " + error);
this.unload();
},
// Irrelevant methods for this controller:
displayPIN: function displayPIN() {},
onPairingStart: function onPairingStart() {},
onPaired: function onPaired() {}
};

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

@ -0,0 +1,91 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/service.js");
Cu.import("resource://services-sync/util.js");
function run_test() {
Service.account = "johndoe";
Service.password = "ilovejane";
Service.passphrase = Utils.generatePassphrase();
Service.serverURL = "http://weave.server/";
run_next_test();
}
function make_sendCredentials_test(topic) {
return function test_sendCredentials() {
_("Test sending credentials on " + topic + " observer notification.");
let sendAndCompleteCalled = false;
let jpakeclient = {
sendAndComplete: function sendAndComplete(data) {
// Verify that the controller unregisters itself as an observer
// when the exchange is complete by faking another notification.
do_check_false(sendAndCompleteCalled);
sendAndCompleteCalled = true;
this.controller.onComplete();
Svc.Obs.notify(topic);
// Verify it sends the correct data.
do_check_eq(data.account, Service.account);
do_check_eq(data.password, Service.password);
do_check_eq(data.synckey, Service.passphrase);
do_check_eq(data.serverURL, Service.serverURL);
Utils.nextTick(run_next_test);
}
};
jpakeclient.controller = new SendCredentialsController(jpakeclient);
Svc.Obs.notify(topic);
};
}
add_test(make_sendCredentials_test("weave:service:sync:finish"));
add_test(make_sendCredentials_test("weave:service:sync:error"));
add_test(function test_abort() {
_("Test aborting the J-PAKE exchange.");
let jpakeclient = {
sendAndComplete: function sendAndComplete() {
do_throw("Shouldn't get here!");
}
};
jpakeclient.controller = new SendCredentialsController(jpakeclient);
// Verify that the controller unregisters itself when the exchange
// was aborted.
jpakeclient.controller.onAbort(JPAKE_ERROR_USERABORT);
Svc.Obs.notify("weave:service:sync:finish");
Utils.nextTick(run_next_test);
});
add_test(function test_startOver() {
_("Test wiping local Sync config aborts transaction.");
let abortCalled = false;
let jpakeclient = {
abort: function abort() {
abortCalled = true;
this.controller.onAbort(JPAKE_ERROR_USERABORT);
},
sendAndComplete: function sendAndComplete() {
do_throw("Shouldn't get here!");
}
};
jpakeclient.controller = new SendCredentialsController(jpakeclient);
Svc.Obs.notify("weave:service:start-over");
do_check_true(abortCalled);
// Ensure that the controller no longer does anything if a sync
// finishes now or -- more likely -- errors out.
Svc.Obs.notify("weave:service:sync:error");
Utils.nextTick(run_next_test);
});

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

@ -62,6 +62,7 @@ skip-if = os == "win" || os == "android"
[test_resource_ua.js] [test_resource_ua.js]
[test_restrequest.js] [test_restrequest.js]
[test_score_triggers.js] [test_score_triggers.js]
[test_sendcredentials_controller.js]
[test_service_attributes.js] [test_service_attributes.js]
[test_service_changePassword.js] [test_service_changePassword.js]
[test_service_checkAccount.js] [test_service_checkAccount.js]