Bug 949259 followup - refactor identity config for tests and remove need to pass params to BrowserIDManager.

This commit is contained in:
Mark Hammond 2013-12-20 15:57:26 +11:00
parent a662b69b0a
commit 934662958e
4 changed files with 103 additions and 67 deletions

View File

@ -89,13 +89,12 @@ WeaveService.prototype = {
(accountData) => {
if (accountData) {
Cu.import("resource://services-sync/browserid_identity.js");
Cu.import("resource://services-common/tokenserverclient.js");
// The Sync Identity module needs to be set in both these places if
// it's swapped out as we are doing here. When Weave.Service initializes
// it grabs a reference to Weave.Status._authManager, and for references
// to Weave.Service.identity to resolve correctly, we also need to reset
// Weave.Service.identity as well.
Weave.Service.identity = Weave.Status._authManager = new BrowserIDManager(fxAccounts, new TokenServerClient()),
Weave.Service.identity = Weave.Status._authManager = new BrowserIDManager(),
// Init the identity module with any account data from
// firefox accounts. The Identity module will fetch the signed in
// user from fxAccounts directly.

View File

@ -8,16 +8,23 @@ this.EXPORTED_SYMBOLS = [
"btoa", // It comes from a module import.
"encryptPayload",
"setBasicCredentials",
"makeIdentityConfig",
"configureFxAccountIdentity",
"SyncTestingInfrastructure",
"waitForZeroTimer",
"Promise", // from a module import
];
const {utils: Cu} = Components;
Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-crypto/utils.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://testing-common/services-common/logging.js");
Cu.import("resource://testing-common/services/sync/fakeservices.js");
Cu.import("resource://gre/modules/FxAccounts.jsm");
Cu.import("resource://gre/modules/FxAccountsCommon.js");
Cu.import("resource://gre/modules/Promise.jsm");
/**
* First wait >100ms (nsITimers can take up to that much time to fire, so
@ -48,6 +55,79 @@ this.setBasicCredentials =
auth.syncKey = syncKey;
}
// Return an identity configuration suitable for testing with our identity
// providers. |overrides| can specify overrides for any default values.
this.makeIdentityConfig = function(overrides) {
// first setup the defaults.
let result = {
// Username used in both fxaccount and sync identity configs.
username: "foo",
// fxaccount specific credentials.
fxaccount: {
user: {
assertion: 'assertion',
email: 'email',
kA: 'kA',
kB: 'kB',
sessionToken: 'sessionToken',
uid: 'user_uid',
isVerified: true,
},
token: {
endpoint: Svc.Prefs.get("tokenServerURI"),
duration: 300,
id: "id",
key: "key",
// uid will be set to the username.
}
}
// XXX - todo - basic identity provider config
};
// Now handle any specified overrides.
if (overrides) {
if (overrides.username) {
result.username = overrides.username;
}
// XXX - todo - basic identity provider config
if (overrides.fxaccount) {
// TODO: allow just some attributes to be specified
result.fxaccount = overrides.fxaccount;
}
return result;
}
// Configure an instance of an FxAccount identity provider with the specified
// config (or the default config if not specified).
this.configureFxAccountIdentity = function(authService,
config = makeIdentityConfig()) {
let MockInternal = {
signedInUser: {
version: DATA_FORMAT_VERSION,
accountData: config.fxaccount.user
},
getCertificate: function(data, keyPair, mustBeValidUntil) {
this.cert = {
validUntil: Date.now() + CERT_LIFETIME,
cert: "certificate",
};
return Promise.resolve(this.cert.cert);
},
};
let fxa = new FxAccounts(MockInternal);
let mockTSC = { // TokenServerClient
getTokenFromBrowserIDAssertion: function(uri, assertion, cb) {
config.fxaccount.token.uid = config.username;
cb(null, config.fxaccount.token);
},
};
authService._fxaService = fxa;
authService._tokenServerClient = mockTSC;
// Set the "account" of the browserId manager to be the "email" of the
// logged in user of the mockFXA service.
authService._account = config.fxaccount.user.email;
}
this.SyncTestingInfrastructure = function (server, username, password, syncKey) {
let ns = {};
Cu.import("resource://services-sync/service.js", ns);

View File

@ -14,16 +14,17 @@ Cu.import("resource://services-common/tokenserverclient.js");
Cu.import("resource://services-crypto/utils.js");
Cu.import("resource://services-sync/identity.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-common/tokenserverclient.js");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://gre/modules/Promise.jsm");
// Lazy import to prevent unnecessary load on startup.
for (let symbol of ["BulkKeyBundle"]) {
XPCOMUtils.defineLazyModuleGetter(this, symbol,
"resource://services-sync/keys.js",
symbol);
}
// Lazy imports to prevent unnecessary load on startup.
XPCOMUtils.defineLazyModuleGetter(this, "BulkKeyBundle",
"resource://services-sync/keys.js");
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
"resource://gre/modules/FxAccounts.jsm");
function deriveKeyBundle(kB) {
let out = CryptoUtils.hkdf(kB, undefined,
@ -35,15 +36,9 @@ function deriveKeyBundle(kB) {
}
/**
* Fetch a token for the sync storage server by passing a BrowserID assertion
* from FxAccounts() to TokenServerClient, then wrap the token in in a Hawk
* header so that SyncStorageRequest can connect.
*/
this.BrowserIDManager = function BrowserIDManager(fxaService, tokenServerClient) {
this._fxaService = fxaService;
this._tokenServerClient = tokenServerClient;
this.BrowserIDManager = function BrowserIDManager() {
this._fxaService = fxAccounts;
this._tokenServerClient = new TokenServerClient();
this._log = Log.repository.getLogger("Sync.BrowserIDManager");
this._log.Level = Log.Level[Svc.Prefs.get("log.logger.identity")];

View File

@ -2,51 +2,14 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/FxAccounts.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://services-sync/browserid_identity.js");
Cu.import("resource://services-sync/rest.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://testing-common/services/sync/utils.js");
let mockUser = {email: 'email',
kA: 'kA',
kB: 'kB',
sessionToken: 'sessionToken',
uid: 'user_uid',
};
let _MockFXA = function(blob) {
this.user = blob;
};
_MockFXA.prototype = {
getSignedInUser: function getSignedInUser() {
return Promise.resolve(this.user);
},
whenVerified: function whenVerified(userData) {
return Promise.resolve(this.user);
},
getAssertion: function getAssertion(audience) {
return Promise.resolve("assertion");
},
};
let mockFXA = new _MockFXA(mockUser);
let mockToken = {
api_endpoint: Svc.Prefs.get("services.sync.tokenServerURI"),
duration: 300,
id: "id",
key: "key",
uid: "token_uid",
};
let mockTSC = { // TokenServerClient
getTokenFromBrowserIDAssertion: function(uri, assertion, cb) {
cb(null, mockToken);
},
};
let browseridManager = new BrowserIDManager(mockFXA, mockTSC);
// Set the "account" of the browserId manager to be the "email" of the
// logged in user of the mockFXA service.
browseridManager._account = mockUser.email;
let identityConfig = makeIdentityConfig();
let browseridManager = new BrowserIDManager();
configureFxAccountIdentity(browseridManager, identityConfig);
function run_test() {
initTestLogging("Trace");
@ -74,8 +37,8 @@ add_test(function test_getResourceAuthenticator() {
do_check_true('authorization' in output.headers);
do_check_true(output.headers.authorization.startsWith('Hawk'));
_("Expected internal state after successful call.");
do_check_eq(browseridManager._token.uid, mockToken.uid);
do_check_eq(browseridManager.account, mockUser.email);
do_check_eq(browseridManager._token.uid, identityConfig.fxaccount.token.uid);
do_check_eq(browseridManager.account, identityConfig.fxaccount.user.email);
run_next_test();
}
);
@ -97,8 +60,8 @@ add_test(function test_getRESTRequestAuthenticator() {
add_test(function test_tokenExpiration() {
_("BrowserIDManager notices token expiration:");
let bimExp = new BrowserIDManager(mockFXA, mockTSC);
bimExp._account = mockUser.email;
let bimExp = new BrowserIDManager();
configureFxAccountIdentity(bimExp, identityConfig);
let authenticator = bimExp.getResourceAuthenticator();
do_check_true(!!authenticator);
@ -124,18 +87,17 @@ add_test(function test_tokenExpiration() {
add_test(function test_userChangeAndLogOut() {
_("BrowserIDManager notices when the FxAccounts.getSignedInUser().email changes.");
let mockFXA2 = new _MockFXA(mockUser);
let bidUser = new BrowserIDManager(mockFXA2, mockTSC);
bidUser._account = mockUser.email;
let bidUser = new BrowserIDManager();
configureFxAccountIdentity(bidUser, identityConfig);
let request = new SyncStorageRequest(
"https://example.net/somewhere/over/the/rainbow");
let authenticator = bidUser.getRESTRequestAuthenticator();
do_check_true(!!authenticator);
let output = authenticator(request, 'GET');
do_check_true(!!output);
do_check_eq(bidUser.account, mockUser.email);
do_check_eq(bidUser.account, identityConfig.fxaccount.user.email);
do_check_true(bidUser.hasValidToken());
mockUser.email = "something@new";
identityConfig.fxaccount.user.email = "something@new";
do_check_false(bidUser.hasValidToken());
run_next_test();
}