Bug 1153788 - Part 1 Opportunistically obtain encryption keys for FxA for Loop conversations context. r=mikedeboer

This commit is contained in:
Mark Banner 2015-04-22 19:17:15 +01:00
Родитель 3ca9465d75
Коммит 44f6b5d48e
7 изменённых файлов: 60 добавлений и 18 удалений

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

@ -147,8 +147,8 @@ let gTests = [
Assert.ok(tabOpened); Assert.ok(tabOpened);
Assert.equal(tokenData.code, "code1"); Assert.equal(tokenData.code, "code1");
Assert.equal(tokenData.state, "state"); Assert.equal(tokenData.state, "state");
Assert.equal(keys.kAr, "kAr"); Assert.deepEqual(keys.kAr, {k: "kAr"});
Assert.equal(keys.kBr, "kBr"); Assert.deepEqual(keys.kBr, {k: "kBr"});
resolve(); resolve();
}; };

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

@ -16,7 +16,9 @@
state: "state", state: "state",
code: "code1", code: "code1",
closeWindow: "signin", closeWindow: "signin",
keys: { kAr: 'kAr', kBr: 'kBr' }, // Keys normally contain more information, but this is enough
// to keep Loop's tests happy.
keys: { kAr: { k: 'kAr' }, kBr: { k: 'kBr' }},
}, },
}, },
}, },

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

@ -202,10 +202,10 @@ let LoopRoomsInternal = {
* information. * information.
*/ */
promiseEncryptRoomData: Task.async(function* (roomData) { promiseEncryptRoomData: Task.async(function* (roomData) {
// For now, disable encryption/context if context is disabled, or if // XXX We should only return unencrypted data whilst we're still working
// FxA is turned on. // on context. Once bug 1115340 is fixed, this function should no longer be
if (!MozLoopService.getLoopPref("contextInConverations.enabled") || // here.
this.sessionType == LOOP_SESSION_TYPE.FXA) { function getUnencryptedData() {
var serverRoomData = extend({}, roomData); var serverRoomData = extend({}, roomData);
delete serverRoomData.decryptedContext; delete serverRoomData.decryptedContext;
@ -218,6 +218,11 @@ let LoopRoomsInternal = {
}; };
} }
// For now, disable encryption/context if context is disabled
if (!MozLoopService.getLoopPref("contextInConverations.enabled")) {
return getUnencryptedData();
}
var newRoomData = extend({}, roomData); var newRoomData = extend({}, roomData);
if (!newRoomData.context) { if (!newRoomData.context) {
@ -227,7 +232,17 @@ let LoopRoomsInternal = {
// First get the room key. // First get the room key.
let key = yield this.promiseGetOrCreateRoomKey(newRoomData); let key = yield this.promiseGetOrCreateRoomKey(newRoomData);
try {
newRoomData.context.wrappedKey = yield this.promiseEncryptedRoomKey(key); newRoomData.context.wrappedKey = yield this.promiseEncryptedRoomKey(key);
}
catch (ex) {
// XXX Bug 1153788 should remove this, then we can remove the whole
// try/catch.
if (ex.message == "FxA re-register not implemented") {
return getUnencryptedData();
}
return Promise.reject(ex);
}
// Now encrypt the actual data. // Now encrypt the actual data.
newRoomData.context.value = yield loopCrypto.encryptBytes(key, newRoomData.context.value = yield loopCrypto.encryptBytes(key,
@ -654,8 +669,7 @@ let LoopRoomsInternal = {
}; };
// If we're not encrypting currently, then only send the roomName. // If we're not encrypting currently, then only send the roomName.
if (!Services.prefs.getBoolPref("loop.contextInConverations.enabled") || if (!Services.prefs.getBoolPref("loop.contextInConverations.enabled")) {
this.sessionType == LOOP_SESSION_TYPE.FXA) {
sendData = { sendData = {
roomName: newRoomName roomName: newRoomName
}; };

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

@ -959,6 +959,9 @@ let MozLoopServiceInternal = {
gFxAOAuthClientPromise = this.promiseFxAOAuthParameters().then( gFxAOAuthClientPromise = this.promiseFxAOAuthParameters().then(
parameters => { parameters => {
// Add the fact that we want keys to the parameters.
parameters.keys = true;
try { try {
gFxAOAuthClient = new FxAccountsOAuthClient({ gFxAOAuthClient = new FxAccountsOAuthClient({
parameters: parameters, parameters: parameters,
@ -1031,7 +1034,10 @@ let MozLoopServiceInternal = {
* @param {Deferred} deferred used to resolve the gFxAOAuthClientPromise * @param {Deferred} deferred used to resolve the gFxAOAuthClientPromise
* @param {Object} result (with code and state) * @param {Object} result (with code and state)
*/ */
_fxAOAuthComplete: function(deferred, result) { _fxAOAuthComplete: function(deferred, result, keys) {
if (keys.kBr) {
Services.prefs.setCharPref("loop.key.fxa", keys.kBr.k);
}
gFxAOAuthClientPromise = null; gFxAOAuthClientPromise = null;
// Note: The state was already verified in FxAccountsOAuthClient. // Note: The state was already verified in FxAccountsOAuthClient.
deferred.resolve(result); deferred.resolve(result);
@ -1331,8 +1337,14 @@ this.MozLoopService = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (this.userProfile) { if (this.userProfile) {
// We're an FxA user. // We're an FxA user.
// XXX Bug 1153788 will implement this for FxA. if (Services.prefs.prefHasUserValue("loop.key.fxa")) {
reject(new Error("unimplemented")); resolve(MozLoopService.getLoopPref("key.fxa"));
return;
}
// XXX If we don't have a key for FxA yet, then simply reject for now.
// We'll create some sign-in/sign-out UX in bug 1153788.
reject(new Error("FxA re-register not implemented"));
return; return;
} }

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

@ -7,7 +7,7 @@ support-files =
google_service.sjs google_service.sjs
head.js head.js
loop_fxa.sjs loop_fxa.sjs
../../../../base/content/test/general/browser_fxa_oauth.html ../../../../base/content/test/general/browser_fxa_oauth_with_keys.html
[browser_CardDavImporter.js] [browser_CardDavImporter.js]
[browser_fxa_login.js] [browser_fxa_login.js]

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

@ -134,7 +134,7 @@ function params(request, response) {
*/ */
function oauth_authorization(request, response) { function oauth_authorization(request, response) {
response.setStatusLine(request.httpVersion, 302, "Found"); response.setStatusLine(request.httpVersion, 302, "Found");
response.setHeader("Location", "browser_fxa_oauth.html"); response.setHeader("Location", "browser_fxa_oauth_with_keys.html");
} }
/** /**

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

@ -3,6 +3,7 @@
/* global Services, Assert */ /* global Services, Assert */
const kGuestKeyPref = "loop.key"; const kGuestKeyPref = "loop.key";
const kFxAKeyPref = "loop.key.fxa";
do_register_cleanup(function() { do_register_cleanup(function() {
Services.prefs.clearUserPref(kGuestKeyPref); Services.prefs.clearUserPref(kGuestKeyPref);
@ -33,12 +34,25 @@ add_task(function* test_guestGetKey() {
Assert.equal(key, kFakeKey, "should return existing key"); Assert.equal(key, kFakeKey, "should return existing key");
}); });
add_task(function* test_fxaGetKey() { add_task(function* test_fxaGetKnownKey() {
// Set the userProfile to look like we're logged into FxA. const kFakeKey = "75312468";
// Set the userProfile to look like we're logged into FxA with a key stored.
MozLoopServiceInternal.fxAOAuthTokenData = { token_type: "bearer" }; MozLoopServiceInternal.fxAOAuthTokenData = { token_type: "bearer" };
MozLoopServiceInternal.fxAOAuthProfile = { email: "fake@invalid.com" }; MozLoopServiceInternal.fxAOAuthProfile = { email: "fake@invalid.com" };
Services.prefs.setCharPref(kFxAKeyPref, kFakeKey);
let key = yield MozLoopService.promiseProfileEncryptionKey();
Assert.equal(key, kFakeKey, "should return existing key");
});
add_task(function* test_fxaGetKey() {
// Set the userProfile to look like we're logged into FxA without a key stored.
MozLoopServiceInternal.fxAOAuthTokenData = { token_type: "bearer" };
MozLoopServiceInternal.fxAOAuthProfile = { email: "fake@invalid.com" };
Services.prefs.clearUserPref(kFxAKeyPref);
// Currently unimplemented, add a test when we implement the code. // Currently unimplemented, add a test when we implement the code.
yield Assert.rejects(MozLoopService.promiseProfileEncryptionKey(), yield Assert.rejects(MozLoopService.promiseProfileEncryptionKey(),
/unimplemented/, "should reject as unimplemented"); /not implemented/, "should reject as unimplemented");
}); });