Bug 1673554 - Add an option to override the pioneer id. r=chutten

With this change, calling the submitExternalPing API
will not necessarily require the pioneer id value to be
stored in a pref. This added flexibility will allow the
Pioneer/Ion Core Addon to own the storage of the id,
communicating it to the legacy telemetry APIs as needed.

Differential Revision: https://phabricator.services.mozilla.com/D94811
This commit is contained in:
Alessio Placitelli 2020-10-28 10:09:24 +00:00
Родитель 5c534c3db9
Коммит 3f58b11a29
2 изменённых файлов: 89 добавлений и 5 удалений

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

@ -377,7 +377,8 @@ var Impl = {
* @param {String} [aOptions.schemaNamespace=null] the schema namespace to use if encryption is enabled.
* @param {String} [aOptions.schemaVersion=null] the schema version to use if encryption is enabled.
* @param {Boolean} [aOptions.addPioneerId=false] true if the ping should contain the Pioneer id, false otherwise.
*
* @param {Boolean} [aOptions.overridePioneerId=undefined] if set, override the
* pioneer id to the provided value. Only works if aOptions.addPioneerId=true.
* @returns {Object} An object that contains the assembled ping data.
*/
assemblePing: function assemblePing(aType, aPayload, aOptions = {}) {
@ -453,6 +454,8 @@ var Impl = {
* @param {String} [aOptions.schemaNamespace=null] the schema namespace to use if encryption is enabled.
* @param {String} [aOptions.schemaVersion=null] the schema version to use if encryption is enabled.
* @param {Boolean} [aOptions.addPioneerId=false] true if the ping should contain the Pioneer id, false otherwise.
* @param {Boolean} [aOptions.overridePioneerId=undefined] if set, override the
* pioneer id to the provided value. Only works if aOptions.addPioneerId=true.
* @param {String} [aOptions.overrideClientId=undefined] if set, override the
* client id to the provided value. Implies aOptions.addClientId=true.
* @returns {Promise} Test-only - a promise that is resolved with the ping id once the ping is stored or sent.
@ -505,10 +508,16 @@ var Impl = {
payload.encryptionKeyId = aOptions.encryptionKeyId;
if (aOptions.addPioneerId === true) {
// This will throw if there is no pioneer ID set.
payload.pioneerId = Services.prefs.getStringPref(
"toolkit.telemetry.pioneerId"
);
if (aOptions.overridePioneerId) {
// The caller provided a substitute id, let's use that
// instead of querying the pref.
payload.pioneerId = aOptions.overridePioneerId;
} else {
// This will throw if there is no pioneer ID set.
payload.pioneerId = Services.prefs.getStringPref(
"toolkit.telemetry.pioneerId"
);
}
payload.studyName = aOptions.studyName;
}
@ -561,6 +570,8 @@ var Impl = {
* @param {String} [aOptions.schemaNamespace=null] the schema namespace to use if encryption is enabled.
* @param {String} [aOptions.schemaVersion=null] the schema version to use if encryption is enabled.
* @param {Boolean} [aOptions.addPioneerId=false] true if the ping should contain the Pioneer id, false otherwise.
* @param {Boolean} [aOptions.overridePioneerId=undefined] if set, override the
* pioneer id to the provided value. Only works if aOptions.addPioneerId=true.
* @param {String} [aOptions.overrideClientId=undefined] if set, override the
* client id to the provided value. Implies aOptions.addClientId=true.
* @returns {Promise} Test-only - a promise that is resolved with the ping id once the ping is stored or sent.

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

@ -26,6 +26,10 @@ ChromeUtils.import("resource://testing-common/ContentTaskUtils.jsm", this);
const { TestUtils } = ChromeUtils.import(
"resource://testing-common/TestUtils.jsm"
);
ChromeUtils.import(
"resource://testing-common/TelemetryArchiveTesting.jsm",
this
);
ChromeUtils.defineModuleGetter(
this,
@ -1071,6 +1075,75 @@ add_task(async function test_encryptedPing() {
);
});
add_task(async function test_encryptedPing_overrideId() {
if (gIsAndroid) {
// The underlying jwcrypto module being used here is not currently available on Android.
return;
}
Cu.importGlobalProperties(["crypto"]);
const publicKey = {
crv: "P-256",
ext: true,
kty: "EC",
x: "h12feyTYBZ__wO_AnM1a5-KTDlko3-YyQ_en19jyrs0",
y: "6GSfzo14ehDyH5E-xCOedJDAYlN0AGPMCtIgFbheLko",
};
const prefPioneerId = "12345";
const overriddenPioneerId = "c0ffeeaa-bbbb-abab-baba-eeff0ceeff0c";
const schemaName = "abc";
const schemaNamespace = "def";
const schemaVersion = 2;
Services.prefs.setStringPref("toolkit.telemetry.pioneerId", prefPioneerId);
let archiveTester = new TelemetryArchiveTesting.Checker();
await archiveTester.promiseInit();
// Submit a ping with a custom payload, which will be encrypted.
let payload = { canary: "test" };
let pingPromise = TelemetryController.submitExternalPing(
"test-pioneer-study-override",
payload,
{
studyName: "pioneer-dev-1@allizom.org",
addPioneerId: true,
overridePioneerId: overriddenPioneerId,
useEncryption: true,
encryptionKeyId: "pioneer-dev-20200423",
publicKey,
schemaName,
schemaNamespace,
schemaVersion,
}
);
// Wait for the ping to be submitted, to have the ping id to scan the
// archive for.
const pingId = await pingPromise;
// And then wait for the ping to be available in the archive.
await TestUtils.waitForCondition(
() => archiveTester.promiseFindPing("test-pioneer-study-override", []),
"Failed to find the pioneer ping"
);
let archivedCopy = await TelemetryArchive.promiseArchivedPingById(pingId);
Assert.notEqual(
archivedCopy.payload.encryptedData,
payload,
"The encrypted payload must not match the plaintext."
);
Assert.equal(
archivedCopy.payload.pioneerId,
overriddenPioneerId,
"Pioneer ID in ping must match the provided override."
);
});
// Testing shutdown and checking that pings sent afterwards are rejected.
add_task(async function test_pingRejection() {
await TelemetryController.testReset();