Bug 1441666 - Add helper functions for inserting encrypted records to the test server r=kitcambridge

This also converts some of our tests to use them. In particular,

1. All of the new functions should have coverage.
2. None of the existing tests should assume we can decrypt records by
   JSON.parsing them.

MozReview-Commit-ID: y7Hw3q9Wko

--HG--
extra : rebase_source : 9c20066da174c598c02ca70882afa0b17ed8a932
This commit is contained in:
Thom Chiovoloni 2018-02-21 16:35:45 -05:00
parent fd5acb461a
commit 9eb8addbc6
8 changed files with 223 additions and 166 deletions

View File

@ -8,6 +8,8 @@ var Cm = Components.manager;
ChromeUtils.import("resource://gre/modules/Log.jsm");
ChromeUtils.import("resource://services-common/utils.js");
ChromeUtils.import("resource://testing-common/TestUtils.jsm");
ChromeUtils.import("resource://testing-common/services/sync/utils.js");
const SYNC_HTTP_LOGGER = "Sync.Test.Server";
// While the sync code itself uses 1.5, the tests hard-code 1.1,
@ -145,7 +147,27 @@ ServerWBO.prototype = {
response.setStatusLine(request.httpVersion, statusCode, status);
response.bodyOutputStream.write(body, body.length);
};
}
},
/**
* Get the cleartext data stored in the payload.
*
* This isn't `get cleartext`, because `x.cleartext.blah = 3;` wouldn't work,
* which seems like a footgun.
*/
getCleartext() {
return JSON.parse(JSON.parse(this.payload).ciphertext);
},
/**
* Setter for getCleartext(), but lets you adjust the modified timestamp too.
* Returns this ServerWBO object.
*/
setCleartext(cleartext, modifiedTimestamp = this.modified) {
this.payload = JSON.stringify(encryptPayload(cleartext));
this.modified = modifiedTimestamp;
return this;
},
};
@ -234,9 +256,7 @@ ServerCollection.prototype = {
* @return an array of the payloads of each stored WBO.
*/
payloads() {
return this.wbos().map(function(wbo) {
return JSON.parse(JSON.parse(wbo.payload).ciphertext);
});
return this.wbos().map(wbo => wbo.getCleartext());
},
// Just for syntactic elegance.
@ -248,6 +268,10 @@ ServerCollection.prototype = {
return this.wbo(id).payload;
},
cleartext(id) {
return this.wbo(id).getCleartext();
},
/**
* Insert the provided WBO under its ID.
*
@ -258,6 +282,40 @@ ServerCollection.prototype = {
return this._wbos[wbo.id] = wbo;
},
/**
* Update an existing WBO's cleartext using a callback function that modifies
* the record in place, or returns a new record.
*/
updateRecord(id, updateCallback, optTimestamp) {
let wbo = this.wbo(id);
if (!wbo) {
throw new Error("No record with provided ID");
}
let curCleartext = wbo.getCleartext();
// Allow update callback to either return a new cleartext, or modify in place.
let newCleartext = updateCallback(curCleartext) || curCleartext;
wbo.setCleartext(newCleartext, optTimestamp);
// It is already inserted, but we might need to update our timestamp based
// on it's `modified` value, if `optTimestamp` was provided.
return this.insertWBO(wbo);
},
/**
* Insert a record, which may either an object with a cleartext property, or
* the cleartext property itself.
*/
insertRecord(record, timestamp = Date.now() / 1000) {
if (typeof timestamp != "number") {
throw new TypeError("insertRecord: Timestamp is not a number.");
}
if (!record.id) {
throw new Error("Attempt to insert record with no id");
}
// Allow providing either the cleartext directly, or the CryptoWrapper-like.
let cleartext = record.cleartext || record;
return this.insert(record.id, encryptPayload(cleartext), timestamp);
},
/**
* Insert the provided payload as part of a new ServerWBO with the provided
* ID.

View File

@ -66,9 +66,7 @@ async function createBookmark(parentId, url, title, index = bms.DEFAULT_INDEX) {
}
function getServerRecord(collection, id) {
let wbo = collection.get({ full: true, ids: [id] });
// Whew - lots of json strings inside strings.
return JSON.parse(JSON.parse(JSON.parse(JSON.parse(wbo)[0]).payload).ciphertext);
return collection.cleartext(id);
}
async function promiseNoLocalItem(guid) {
@ -166,13 +164,13 @@ add_task(async function test_dupe_bookmark() {
// We should have logically deleted the dupe record.
equal(collection.count(), 7);
ok(getServerRecord(collection, bmk1_guid).deleted);
ok(collection.cleartext(bmk1_guid).deleted);
// and physically removed from the local store.
await promiseNoLocalItem(bmk1_guid);
// Parent should still only have 1 item.
equal((await getFolderChildrenIDs(folder1_id)).length, 1);
// The parent record on the server should now reference the new GUID and not the old.
let serverRecord = getServerRecord(collection, folder1_guid);
let serverRecord = collection.cleartext(folder1_guid);
ok(!serverRecord.children.includes(bmk1_guid));
ok(serverRecord.children.includes(newGUID));
@ -227,7 +225,7 @@ add_task(async function test_dupe_reparented_bookmark() {
// We should have logically deleted the dupe record.
equal(collection.count(), 8);
ok(getServerRecord(collection, bmk1_guid).deleted);
ok(collection.cleartext(bmk1_guid).deleted);
// and physically removed from the local store.
await promiseNoLocalItem(bmk1_guid);
// The original folder no longer has the item
@ -236,12 +234,12 @@ add_task(async function test_dupe_reparented_bookmark() {
equal((await getFolderChildrenIDs(folder2_id)).length, 1);
// The record for folder1 on the server should reference neither old or new GUIDs.
let serverRecord1 = getServerRecord(collection, folder1_guid);
let serverRecord1 = collection.cleartext(folder1_guid);
ok(!serverRecord1.children.includes(bmk1_guid));
ok(!serverRecord1.children.includes(newGUID));
// The record for folder2 on the server should only reference the new new GUID.
let serverRecord2 = getServerRecord(collection, folder2_guid);
let serverRecord2 = collection.cleartext(folder2_guid);
ok(!serverRecord2.children.includes(bmk1_guid));
ok(serverRecord2.children.includes(newGUID));
@ -308,7 +306,7 @@ add_task(async function test_dupe_reparented_locally_changed_bookmark() {
// We should have logically deleted the dupe record.
equal(collection.count(), 8);
ok(getServerRecord(collection, bmk1_guid).deleted);
ok(collection.cleartext(bmk1_guid).deleted);
// and physically removed from the local store.
await promiseNoLocalItem(bmk1_guid);
// The original folder still has the item
@ -317,12 +315,12 @@ add_task(async function test_dupe_reparented_locally_changed_bookmark() {
equal((await getFolderChildrenIDs(folder2_id)).length, 0);
// The record for folder1 on the server should reference only the GUID.
let serverRecord1 = getServerRecord(collection, folder1_guid);
let serverRecord1 = collection.cleartext(folder1_guid);
ok(!serverRecord1.children.includes(bmk1_guid));
ok(serverRecord1.children.includes(newGUID));
// The record for folder2 on the server should reference nothing.
let serverRecord2 = getServerRecord(collection, folder2_guid);
let serverRecord2 = collection.cleartext(folder2_guid);
ok(!serverRecord2.children.includes(bmk1_guid));
ok(!serverRecord2.children.includes(newGUID));
@ -531,14 +529,14 @@ add_task(async function test_dupe_reparented_to_future_arriving_parent_bookmark(
// We should have logically deleted the dupe record.
equal(collection.count(), 8);
ok(getServerRecord(collection, bmk1_guid).deleted);
ok(collection.cleartext(bmk1_guid).deleted);
// and physically removed from the local store.
await promiseNoLocalItem(bmk1_guid);
// The intended parent doesn't exist, so it remains in the original folder
equal((await getFolderChildrenIDs(folder1_id)).length, 1);
// The record for folder1 on the server should reference the new GUID.
let serverRecord1 = getServerRecord(collection, folder1_guid);
let serverRecord1 = collection.cleartext(folder1_guid);
ok(!serverRecord1.children.includes(bmk1_guid));
ok(serverRecord1.children.includes(newGUID));
@ -649,7 +647,7 @@ add_task(async function test_dupe_empty_folder() {
// Collection now has one additional record - the logically deleted dupe.
equal(collection.count(), 6);
// original folder should be logically deleted.
ok(getServerRecord(collection, folder1_guid).deleted);
ok(collection.cleartext(folder1_guid).deleted);
await promiseNoLocalItem(folder1_guid);
} finally {
await cleanup(engine, server);

View File

@ -797,7 +797,7 @@ add_bookmark_test(async function test_sync_dateAdded(engine) {
let newRecord2 = await store.createRecord(item2GUID);
equal(newRecord2.dateAdded, item2.dateAdded, "dateAdded update should work for earlier date");
let bzWBO = JSON.parse(JSON.parse(collection._wbos[bz.guid].payload).ciphertext);
let bzWBO = collection.cleartext(bz.guid);
ok(bzWBO.dateAdded, "Locally added dateAdded lost");
let localRecord = await store.createRecord(bz.guid);
@ -867,8 +867,7 @@ add_task(async function test_sync_imap_URLs() {
"invalidazPrahy.jpg",
"Remote bookmark A with IMAP URL should exist locally");
let bPayload = JSON.parse(JSON.parse(
collection.payload("bookmarkBBBB")).ciphertext);
let bPayload = collection.cleartext("bookmarkBBBB");
equal(bPayload.bmkUri, "imap://eleven.vs.solnicky.cz:993/" +
"fetch%3EUID%3E/CURRENT%3E2433?part=1.2&type=text/html&filename=" +
"TomEdwards.html",

View File

@ -107,7 +107,7 @@ add_task(async function test_annotation_uploaded() {
Assert.equal(serverGUID, guid);
let serverWBO = collection.wbo(serverGUID);
Assert.ok(!!serverWBO);
let body = JSON.parse(JSON.parse(serverWBO.payload).ciphertext);
let body = serverWBO.getCleartext();
Assert.equal(body.queryId, "MostVisited");
_("We still have the right count.");

View File

@ -18,7 +18,7 @@ let engine;
* we should be putting into records.
*/
async function check_record_version(user, id) {
let payload = JSON.parse(user.collection("clients").wbo(id).payload);
let payload = user.collection("clients").wbo(id).data;
let rec = new CryptoWrapper();
rec.id = id;
@ -224,24 +224,24 @@ add_task(async function test_full_sync() {
await generateNewKeys(Service.collectionKeys);
let activeID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
user.collection("clients").insertRecord({
id: activeID,
name: "Active client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
let deletedID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(deletedID, encryptPayload({
user.collection("clients").insertRecord({
id: deletedID,
name: "Client to delete",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
try {
let store = engine._store;
@ -373,14 +373,14 @@ add_task(async function test_last_modified() {
await generateNewKeys(Service.collectionKeys);
let activeID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
user.collection("clients").insertRecord({
id: activeID,
name: "Active client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
try {
let collection = user.collection("clients");
@ -403,7 +403,7 @@ add_task(async function test_last_modified() {
ok(engine._store._remoteClients[activeID].serverLastModified >= now);
_("Record on the server should have new name but not serverLastModified");
let payload = JSON.parse(JSON.parse(collection.payload(activeID)).ciphertext);
let payload = collection.cleartext(activeID);
equal(payload.name, "New name");
equal(payload.serverLastModified, undefined);
@ -609,36 +609,36 @@ add_task(async function test_filter_duplicate_names() {
// Synced recently.
let recentID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(recentID, encryptPayload({
user.collection("clients").insertRecord({
id: recentID,
name: "My Phone",
type: "mobile",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
// Dupe of our client, synced more than 1 week ago.
let dupeID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(dupeID, encryptPayload({
user.collection("clients").insertRecord({
id: dupeID,
name: engine.localName,
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 604810));
}, now - 604820);
// Synced more than 1 week ago, but not a dupe.
let oldID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(oldID, encryptPayload({
user.collection("clients").insertRecord({
id: oldID,
name: "My old desktop",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 604820));
}, now - 604820);
try {
let store = engine._store;
@ -692,27 +692,27 @@ add_task(async function test_filter_duplicate_names() {
await syncClientsEngine(server);
let collection = server.getCollection("foo", "clients");
let recentPayload = JSON.parse(JSON.parse(collection.payload(recentID)).ciphertext);
let recentPayload = collection.cleartext(recentID);
compareCommands(recentPayload.commands, [{ command: "logout", args: [] }],
"Should send commands to the recent client");
let oldPayload = JSON.parse(JSON.parse(collection.payload(oldID)).ciphertext);
let oldPayload = collection.cleartext(oldID);
compareCommands(oldPayload.commands, [{ command: "logout", args: [] }],
"Should send commands to the week-old client");
let dupePayload = JSON.parse(JSON.parse(collection.payload(dupeID)).ciphertext);
let dupePayload = collection.cleartext(dupeID);
deepEqual(dupePayload.commands, [],
"Should not send commands to the dupe client");
_("Update the dupe client's modified time");
server.insertWBO("foo", "clients", new ServerWBO(dupeID, encryptPayload({
collection.insertRecord({
id: dupeID,
name: engine.localName,
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
_("Second sync.");
await syncClientsEngine(server);
@ -765,14 +765,14 @@ add_task(async function test_command_sync() {
}
_("Create remote client record");
server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
user.collection("clients").insertRecord({
id: remoteId,
name: "Remote client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), Date.now() / 1000));
});
try {
_("Syncing.");
@ -830,9 +830,10 @@ add_task(async function test_clients_not_in_fxa_list() {
let remoteId = Utils.makeGUID();
let remoteId2 = Utils.makeGUID();
let collection = server.getCollection("foo", "clients");
_("Create remote client records");
server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
collection.insertRecord({
id: remoteId,
name: "Remote client",
type: "desktop",
@ -840,8 +841,9 @@ add_task(async function test_clients_not_in_fxa_list() {
version: "48",
fxaDeviceId: remoteId,
protocols: ["1.5"],
}), Date.now() / 1000));
server.insertWBO("foo", "clients", new ServerWBO(remoteId2, encryptPayload({
});
collection.insertRecord({
id: remoteId2,
name: "Remote client 2",
type: "desktop",
@ -849,7 +851,7 @@ add_task(async function test_clients_not_in_fxa_list() {
version: "48",
fxaDeviceId: remoteId2,
protocols: ["1.5"],
}), Date.now() / 1000));
});
let fxAccounts = engine.fxAccounts;
engine.fxAccounts = {
@ -870,7 +872,6 @@ add_task(async function test_clients_not_in_fxa_list() {
await cleanup();
try {
let collection = server.getCollection("foo", "clients");
collection.remove(remoteId);
} finally {
await promiseStopServer(server);
@ -892,8 +893,10 @@ add_task(async function test_dupe_device_ids() {
let remoteId2 = Utils.makeGUID();
let remoteDeviceId = Utils.makeGUID();
let collection = server.getCollection("foo", "clients");
_("Create remote client records");
server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
collection.insertRecord({
id: remoteId,
name: "Remote client",
type: "desktop",
@ -901,8 +904,8 @@ add_task(async function test_dupe_device_ids() {
version: "48",
fxaDeviceId: remoteDeviceId,
protocols: ["1.5"],
}), Date.now() / 1000 - 30000));
server.insertWBO("foo", "clients", new ServerWBO(remoteId2, encryptPayload({
}, Date.now() / 1000 - 30000);
collection.insertRecord({
id: remoteId2,
name: "Remote client",
type: "desktop",
@ -910,7 +913,7 @@ add_task(async function test_dupe_device_ids() {
version: "48",
fxaDeviceId: remoteDeviceId,
protocols: ["1.5"],
}), Date.now() / 1000));
});
let fxAccounts = engine.fxAccounts;
engine.fxAccounts = {
@ -931,7 +934,6 @@ add_task(async function test_dupe_device_ids() {
await cleanup();
try {
let collection = server.getCollection("foo", "clients");
collection.remove(remoteId);
} finally {
await promiseStopServer(server);
@ -1064,12 +1066,13 @@ add_task(async function test_merge_commands() {
let now = Date.now() / 1000;
let server = await serverForFoo(engine);
await SyncTestingInfrastructure(server);
await generateNewKeys(Service.collectionKeys);
let collection = server.getCollection("foo", "clients");
let desktopID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
collection.insertRecord({
id: desktopID,
name: "Desktop client",
type: "desktop",
@ -1080,10 +1083,10 @@ add_task(async function test_merge_commands() {
}],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
let mobileID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(mobileID, encryptPayload({
collection.insertRecord({
id: mobileID,
name: "Mobile client",
type: "mobile",
@ -1094,7 +1097,7 @@ add_task(async function test_merge_commands() {
}],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
try {
_("First sync. 2 records downloaded.");
@ -1105,8 +1108,7 @@ add_task(async function test_merge_commands() {
await engine.sendCommand("logout", []);
await syncClientsEngine(server);
let collection = server.getCollection("foo", "clients");
let desktopPayload = JSON.parse(JSON.parse(collection.payload(desktopID)).ciphertext);
let desktopPayload = collection.cleartext(desktopID);
compareCommands(desktopPayload.commands, [{
command: "displayURI",
args: ["https://example.com", engine.localID, "Yak Herders Anonymous"],
@ -1115,7 +1117,7 @@ add_task(async function test_merge_commands() {
args: [],
}], "Should send the logout command to the desktop client");
let mobilePayload = JSON.parse(JSON.parse(collection.payload(mobileID)).ciphertext);
let mobilePayload = collection.cleartext(mobileID);
compareCommands(mobilePayload.commands, [{ command: "logout", args: [] }],
"Should not send a duplicate logout to the mobile client");
} finally {
@ -1138,15 +1140,17 @@ add_task(async function test_duplicate_remote_commands() {
await SyncTestingInfrastructure(server);
await generateNewKeys(Service.collectionKeys);
let collection = server.getCollection("foo", "clients");
let desktopID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
collection.insertRecord({
id: desktopID,
name: "Desktop client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
try {
_("First sync. 1 record downloaded.");
@ -1158,21 +1162,20 @@ add_task(async function test_duplicate_remote_commands() {
await syncClientsEngine(server);
_("Simulate the desktop client consuming the command and syncing to the server");
server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
collection.insertRecord({
id: desktopID,
name: "Desktop client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
_("Send another tab to the desktop client");
await engine.sendCommand("displayURI", ["https://foobar.com", engine.localID, "Foo bar!"], desktopID);
await syncClientsEngine(server);
let collection = server.getCollection("foo", "clients");
let desktopPayload = JSON.parse(JSON.parse(collection.payload(desktopID)).ciphertext);
let desktopPayload = collection.cleartext(desktopID);
compareCommands(desktopPayload.commands, [{
command: "displayURI",
args: ["https://foobar.com", engine.localID, "Foo bar!"],
@ -1197,9 +1200,11 @@ add_task(async function test_upload_after_reboot() {
await SyncTestingInfrastructure(server);
await generateNewKeys(Service.collectionKeys);
let collection = server.getCollection("foo", "clients");
let deviceBID = Utils.makeGUID();
let deviceCID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(deviceBID, encryptPayload({
collection.insertRecord({
id: deviceBID,
name: "Device B",
type: "desktop",
@ -1210,15 +1215,15 @@ add_task(async function test_upload_after_reboot() {
}],
version: "48",
protocols: ["1.5"],
}), now - 10));
server.insertWBO("foo", "clients", new ServerWBO(deviceCID, encryptPayload({
}, now - 10);
collection.insertRecord({
id: deviceCID,
name: "Device C",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
try {
_("First sync. 2 records downloaded.");
@ -1232,21 +1237,20 @@ add_task(async function test_upload_after_reboot() {
SyncEngine.prototype._uploadOutgoing = async () => engine._onRecordsWritten([], [deviceBID]);
await syncClientsEngine(server);
let collection = server.getCollection("foo", "clients");
let deviceBPayload = JSON.parse(JSON.parse(collection.payload(deviceBID)).ciphertext);
let deviceBPayload = collection.cleartext(deviceBID);
compareCommands(deviceBPayload.commands, [{
command: "displayURI", args: ["https://deviceclink.com", deviceCID, "Device C link"]
}], "Should be the same because the upload failed");
_("Simulate the client B consuming the command and syncing to the server");
server.insertWBO("foo", "clients", new ServerWBO(deviceBID, encryptPayload({
collection.insertRecord({
id: deviceBID,
name: "Device B",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
// Simulate reboot
SyncEngine.prototype._uploadOutgoing = oldUploadOutgoing;
@ -1255,7 +1259,7 @@ add_task(async function test_upload_after_reboot() {
await syncClientsEngine(server);
deviceBPayload = JSON.parse(JSON.parse(collection.payload(deviceBID)).ciphertext);
deviceBPayload = collection.cleartext(deviceBID);
compareCommands(deviceBPayload.commands, [{
command: "displayURI",
args: ["https://example.com", engine.localID, "Yak Herders Anonymous"],
@ -1280,9 +1284,11 @@ add_task(async function test_keep_cleared_commands_after_reboot() {
await SyncTestingInfrastructure(server);
await generateNewKeys(Service.collectionKeys);
let collection = server.getCollection("foo", "clients");
let deviceBID = Utils.makeGUID();
let deviceCID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(engine.localID, encryptPayload({
collection.insertRecord({
id: engine.localID,
name: "Device A",
type: "desktop",
@ -1298,29 +1304,28 @@ add_task(async function test_keep_cleared_commands_after_reboot() {
}],
version: "48",
protocols: ["1.5"],
}), now - 10));
server.insertWBO("foo", "clients", new ServerWBO(deviceBID, encryptPayload({
}, now - 10);
collection.insertRecord({
id: deviceBID,
name: "Device B",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
server.insertWBO("foo", "clients", new ServerWBO(deviceCID, encryptPayload({
}, now - 10);
collection.insertRecord({
id: deviceCID,
name: "Device C",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
try {
_("First sync. Download remote and our record.");
strictEqual(engine.lastRecordUpload, 0);
let collection = server.getCollection("foo", "clients");
const oldUploadOutgoing = SyncEngine.prototype._uploadOutgoing;
SyncEngine.prototype._uploadOutgoing = async () => engine._onRecordsWritten([], [deviceBID]);
let commandsProcessed = 0;
@ -1330,7 +1335,7 @@ add_task(async function test_keep_cleared_commands_after_reboot() {
await engine.processIncomingCommands(); // Not called by the engine.sync(), gotta call it ourselves
equal(commandsProcessed, 2, "We processed 2 commands");
let localRemoteRecord = JSON.parse(JSON.parse(collection.payload(engine.localID)).ciphertext);
let localRemoteRecord = collection.cleartext(engine.localID);
compareCommands(localRemoteRecord.commands, [{
command: "displayURI", args: ["https://deviceblink.com", deviceBID, "Device B link"]
},
@ -1339,7 +1344,7 @@ add_task(async function test_keep_cleared_commands_after_reboot() {
}], "Should be the same because the upload failed");
// Another client sends another link
server.insertWBO("foo", "clients", new ServerWBO(engine.localID, encryptPayload({
collection.insertRecord({
id: engine.localID,
name: "Device A",
type: "desktop",
@ -1360,7 +1365,7 @@ add_task(async function test_keep_cleared_commands_after_reboot() {
}],
version: "48",
protocols: ["1.5"],
}), now - 5));
}, now - 5);
// Simulate reboot
SyncEngine.prototype._uploadOutgoing = oldUploadOutgoing;
@ -1373,7 +1378,7 @@ add_task(async function test_keep_cleared_commands_after_reboot() {
await engine.processIncomingCommands();
equal(commandsProcessed, 1, "We processed one command (the other were cleared)");
localRemoteRecord = JSON.parse(JSON.parse(collection.payload(deviceBID)).ciphertext);
localRemoteRecord = collection.cleartext(deviceBID);
deepEqual(localRemoteRecord.commands, [], "Should be empty");
} finally {
await cleanup();
@ -1400,32 +1405,33 @@ add_task(async function test_deleted_commands() {
await SyncTestingInfrastructure(server);
await generateNewKeys(Service.collectionKeys);
let collection = server.getCollection("foo", "clients");
let activeID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
collection.insertRecord({
id: activeID,
name: "Active client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
let deletedID = Utils.makeGUID();
server.insertWBO("foo", "clients", new ServerWBO(deletedID, encryptPayload({
collection.insertRecord({
id: deletedID,
name: "Client to delete",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"],
}), now - 10));
}, now - 10);
try {
_("First sync. 2 records downloaded.");
await syncClientsEngine(server);
_("Delete a record on the server.");
let collection = server.getCollection("foo", "clients");
collection.remove(deletedID);
_("Broadcast a command to all clients");
@ -1435,7 +1441,7 @@ add_task(async function test_deleted_commands() {
deepEqual(collection.keys().sort(), [activeID, engine.localID].sort(),
"Should not reupload deleted clients");
let activePayload = JSON.parse(JSON.parse(collection.payload(activeID)).ciphertext);
let activePayload = collection.cleartext(activeID);
compareCommands(activePayload.commands, [{ command: "logout", args: [] }],
"Should send the command to the active client");
} finally {
@ -1464,19 +1470,19 @@ add_task(async function test_send_uri_ack() {
_("Initial sync for empty clients collection");
await syncClientsEngine(server);
let collection = server.getCollection("foo", "clients");
let ourPayload = JSON.parse(JSON.parse(collection.payload(engine.localID)).ciphertext);
ok(ourPayload, "Should upload our client record");
_("Send a URL to the device on the server");
ourPayload.commands = [{
command: "displayURI",
args: ["https://example.com", fakeSenderID, "Yak Herders Anonymous"],
flowID: Utils.makeGUID(),
}];
server.insertWBO("foo", "clients", new ServerWBO(engine.localID, encryptPayload(ourPayload), now));
collection.updateRecord(engine.localID, payload => {
_("Send a URL to the device on the server");
payload.commands = [{
command: "displayURI",
args: ["https://example.com", fakeSenderID, "Yak Herders Anonymous"],
flowID: Utils.makeGUID(),
}];
}, now - 10);
_("Sync again");
await syncClientsEngine(server);
compareCommands(engine.localCommands, [{
command: "displayURI",
args: ["https://example.com", fakeSenderID, "Yak Herders Anonymous"],
@ -1490,7 +1496,7 @@ add_task(async function test_send_uri_ack() {
_("Check that the command was removed on the server");
await syncClientsEngine(server);
ourPayload = JSON.parse(JSON.parse(collection.payload(engine.localID)).ciphertext);
let ourPayload = collection.cleartext(engine.localID);
ok(ourPayload, "Should upload the synced client record");
deepEqual(ourPayload.commands, [], "Should not reupload cleared commands");
} finally {
@ -1518,24 +1524,24 @@ add_task(async function test_command_sync() {
let remoteId2 = Utils.makeGUID();
_("Create remote client record 1");
server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
collection.insertRecord({
id: remoteId,
name: "Remote client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"]
}), Date.now() / 1000));
});
_("Create remote client record 2");
server.insertWBO("foo", "clients", new ServerWBO(remoteId2, encryptPayload({
collection.insertRecord({
id: remoteId2,
name: "Remote client 2",
type: "mobile",
commands: [],
version: "48",
protocols: ["1.5"]
}), Date.now() / 1000));
});
try {
equal(collection.count(), 2, "2 remote records written");
@ -1578,29 +1584,30 @@ add_task(async function ensureSameFlowIDs() {
// Setup 2 clients, send them a command, and ensure we get to events
// written, both with the same flowID.
await SyncTestingInfrastructure(server);
let collection = server.getCollection("foo", "clients");
let remoteId = Utils.makeGUID();
let remoteId2 = Utils.makeGUID();
_("Create remote client record 1");
server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
collection.insertRecord({
id: remoteId,
name: "Remote client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"]
}), Date.now() / 1000));
});
_("Create remote client record 2");
server.insertWBO("foo", "clients", new ServerWBO(remoteId2, encryptPayload({
collection.insertRecord({
id: remoteId2,
name: "Remote client 2",
type: "mobile",
commands: [],
version: "48",
protocols: ["1.5"]
}), Date.now() / 1000));
});
await syncClientsEngine(server);
await engine.sendCommand("wipeAll", []);
@ -1670,29 +1677,30 @@ add_task(async function test_duplicate_commands_telemetry() {
let server = await serverForFoo(engine);
try {
await SyncTestingInfrastructure(server);
let collection = server.getCollection("foo", "clients");
let remoteId = Utils.makeGUID();
let remoteId2 = Utils.makeGUID();
_("Create remote client record 1");
server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
collection.insertRecord({
id: remoteId,
name: "Remote client",
type: "desktop",
commands: [],
version: "48",
protocols: ["1.5"]
}), Date.now() / 1000));
});
_("Create remote client record 2");
server.insertWBO("foo", "clients", new ServerWBO(remoteId2, encryptPayload({
collection.insertRecord({
id: remoteId2,
name: "Remote client 2",
type: "mobile",
commands: [],
version: "48",
protocols: ["1.5"]
}), Date.now() / 1000));
});
await syncClientsEngine(server);
// Make sure deduping works before syncing
@ -1836,14 +1844,14 @@ add_task(async function test_create_record_command_limit() {
let remoteId = Utils.makeGUID();
_("Create remote client record");
server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
user.collection("clients").insertRecord({
id: remoteId,
name: "Remote client",
type: "desktop",
commands: [],
version: "57",
protocols: ["1.5"],
}), Date.now() / 1000));
});
try {
_("Initial sync.");
@ -1859,8 +1867,7 @@ add_task(async function test_create_record_command_limit() {
await syncClientsEngine(server);
_("Make sure they all fit and weren't dropped.");
let parsedServerRecord = JSON.parse(JSON.parse(
user.collection("clients").payload(remoteId)).ciphertext);
let parsedServerRecord = user.collection("clients").cleartext(remoteId);
equal(parsedServerRecord.commands.length, 5);
@ -1876,11 +1883,11 @@ add_task(async function test_create_record_command_limit() {
await syncClientsEngine(server);
_("Ensure we didn't overflow the server limit.");
let payload = user.collection("clients").payload(remoteId);
less(payload.length, fakeLimit);
let wbo = user.collection("clients").wbo(remoteId);
less(wbo.payload.length, fakeLimit);
_("And that the data we uploaded is both sane json and containing some commands.");
let remoteCommands = JSON.parse(JSON.parse(payload).ciphertext).commands;
let remoteCommands = wbo.getCleartext().commands;
greater(remoteCommands.length, 2);
let firstCommand = remoteCommands[0];
_("The first command should still be present, since it had a high priority");

View File

@ -161,20 +161,19 @@ add_task(async function test_history_visit_roundtrip() {
// Sync the visit up to the server.
await sync_engine_and_validate_telem(engine, false);
let wbo = collection.wbo(id);
let data = JSON.parse(JSON.parse(wbo.payload).ciphertext);
// Double-check that we didn't round the visit's timestamp to the nearest
// millisecond when uploading.
equal(data.visits[0].date, time);
// Add a remote visit so that we get past the deepEquals check in reconcile
// (otherwise the history engine will skip applying this record). The contents
// of this visit don't matter, beyond the fact that it needs to exist.
data.visits.push({
date: (Date.now() - oneHourMS / 2) * 1000,
type: PlacesUtils.history.TRANSITIONS.LINK
});
collection.insertWBO(new ServerWBO(id, encryptPayload(data), Date.now() / 1000 + 10));
collection.updateRecord(id, cleartext => {
// Double-check that we didn't round the visit's timestamp to the nearest
// millisecond when uploading.
equal(cleartext.visits[0].date, time);
// Add a remote visit so that we get past the deepEquals check in reconcile
// (otherwise the history engine will skip applying this record). The
// contents of this visit don't matter, beyond the fact that it needs to
// exist.
cleartext.visits.push({
date: (Date.now() - oneHourMS / 2) * 1000,
type: PlacesUtils.history.TRANSITIONS.LINK
});
}, Date.now() / 1000 + 10);
// Force a remote sync.
engine.lastSync = Date.now() / 1000 - 30;
@ -220,29 +219,27 @@ add_task(async function test_history_visit_dedupe_old() {
await sync_engine_and_validate_telem(engine, false);
let wbo = collection.wbo(guid);
let data = JSON.parse(JSON.parse(wbo.payload).ciphertext);
collection.updateRecord(guid, data => {
data.visits.push(
// Add a couple remote visit equivalent to some old visits we have already
{
date: Date.UTC(2017, 10, 1) * 1000, // Nov 1, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
}, {
date: Date.UTC(2017, 10, 2) * 1000, // Nov 2, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
},
// Add a couple new visits to make sure we are still applying them.
{
date: Date.UTC(2017, 11, 4) * 1000, // Dec 4, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
}, {
date: Date.UTC(2017, 11, 5) * 1000, // Dec 5, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
}
);
}, Date.now() / 1000 + 10);
data.visits.push(
// Add a couple remote visit equivalent to some old visits we have already
{
date: Date.UTC(2017, 10, 1) * 1000, // Nov 1, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
}, {
date: Date.UTC(2017, 10, 2) * 1000, // Nov 2, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
},
// Add a couple new visits to make sure we are still applying them.
{
date: Date.UTC(2017, 11, 4) * 1000, // Dec 4, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
}, {
date: Date.UTC(2017, 11, 5) * 1000, // Dec 5, 2017
type: PlacesUtils.history.TRANSITIONS.LINK
}
);
collection.insertWBO(new ServerWBO(guid, encryptPayload(data), Date.now() / 1000 + 10));
engine.lastSync = Date.now() / 1000 - 30;
await sync_engine_and_validate_telem(engine, false);

View File

@ -160,8 +160,7 @@ add_task(async function test_password_engine() {
try {
await sync_engine_and_validate_telem(engine, false);
let newRec = JSON.parse(JSON.parse(
collection.payload(newLogin.guid)).ciphertext);
let newRec = collection.cleartext(newLogin.guid);
equal(newRec.password, "password",
"Should update remote password for newer login");

View File

@ -479,7 +479,7 @@ add_task(async function test_processIncoming_reconcile_locally_deleted_dupe_new(
Assert.equal(1, collection.count());
wbo = collection.wbo("DUPE_INCOMING");
Assert.notEqual(null, wbo);
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
let payload = wbo.getCleartext();
Assert.ok(payload.deleted);
await cleanAndGo(engine, server);
@ -518,7 +518,7 @@ add_task(async function test_processIncoming_reconcile_locally_deleted_dupe_old(
let collection = server.getCollection(user, "rotary");
Assert.equal(1, collection.count());
wbo = collection.wbo("DUPE_INCOMING");
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
let payload = wbo.getCleartext();
Assert.equal("incoming", payload.denomination);
await cleanAndGo(engine, server);
@ -556,7 +556,7 @@ add_task(async function test_processIncoming_reconcile_changed_dupe() {
Assert.equal(1, collection.count());
wbo = collection.wbo("DUPE_INCOMING");
Assert.notEqual(undefined, wbo);
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
let payload = wbo.getCleartext();
Assert.equal("local", payload.denomination);
await cleanAndGo(engine, server);
@ -595,7 +595,7 @@ add_task(async function test_processIncoming_reconcile_changed_dupe_new() {
Assert.equal(1, collection.count());
wbo = collection.wbo("DUPE_INCOMING");
Assert.notEqual(undefined, wbo);
let payload = JSON.parse(JSON.parse(wbo.payload).ciphertext);
let payload = wbo.getCleartext();
Assert.equal("incoming", payload.denomination);
await cleanAndGo(engine, server);
});
@ -1084,8 +1084,7 @@ add_task(async function test_uploadOutgoing_toEmptyServer() {
// no longer marked.
Assert.equal(collection.payload("flying"), undefined);
Assert.ok(!!collection.payload("scotsman"));
Assert.equal(JSON.parse(collection.wbo("scotsman").data.ciphertext).id,
"scotsman");
Assert.equal(collection.cleartext("scotsman").id, "scotsman");
const changes = await engine._tracker.getChangedIDs();
Assert.equal(changes.scotsman, undefined);