mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1549730 - Add guardrails for Remote Settings preferences r=glasserc
Differential Revision: https://phabricator.services.mozilla.com/D31043 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
ff22bbc199
commit
64e548abb4
@ -2725,9 +2725,7 @@ pref("security.strict_security_checks.enabled", false);
|
||||
// Remote settings preferences
|
||||
pref("services.settings.poll_interval", 86400); // 24H
|
||||
pref("services.settings.server", "https://firefox.settings.services.mozilla.com/v1");
|
||||
pref("services.settings.changes.path", "/buckets/monitor/collections/changes/records");
|
||||
pref("services.settings.default_bucket", "main");
|
||||
pref("services.settings.default_signer", "remote-settings.content-signature.mozilla.org");
|
||||
|
||||
// The percentage of clients who will report uptake telemetry as
|
||||
// events instead of just a histogram. This only applies on Release;
|
||||
|
@ -35,8 +35,6 @@ const TELEMETRY_COMPONENT = "remotesettings";
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "gServerURL",
|
||||
"services.settings.server");
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "gChangesPath",
|
||||
"services.settings.changes.path");
|
||||
|
||||
/**
|
||||
* cacheProxy returns an object Proxy that will memoize properties of the target.
|
||||
@ -255,7 +253,7 @@ class RemoteSettingsClient extends EventEmitter {
|
||||
async sync(options) {
|
||||
// We want to know which timestamp we are expected to obtain in order to leverage
|
||||
// cache busting. We don't provide ETag because we don't want a 304.
|
||||
const { changes } = await Utils.fetchLatestChanges(gServerURL + gChangesPath, {
|
||||
const { changes } = await Utils.fetchLatestChanges(gServerURL, {
|
||||
filters: {
|
||||
collection: this.collectionName,
|
||||
bucket: this.bucketName,
|
||||
|
@ -12,6 +12,7 @@ const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]);
|
||||
|
||||
var Utils = {
|
||||
CHANGES_PATH: "/buckets/monitor/collections/changes/records",
|
||||
|
||||
/**
|
||||
* Check if local data exist for the specified client.
|
||||
@ -43,7 +44,7 @@ var Utils = {
|
||||
|
||||
/**
|
||||
* Fetch the list of remote collections and their timestamp.
|
||||
* @param {String} url The poll URL (eg. `http://${server}{pollingEndpoint}`)
|
||||
* @param {String} serverUrl The server URL (eg. `https://server.org/v1`)
|
||||
* @param {int} expectedTimestamp The timestamp that the server is supposed to return.
|
||||
* We obtained it from the Megaphone notification payload,
|
||||
* and we use it only for cache busting (Bug 1497159).
|
||||
@ -51,8 +52,9 @@ var Utils = {
|
||||
* by the server (eg. `"123456789"`).
|
||||
* @param {Object} filters
|
||||
*/
|
||||
async fetchLatestChanges(url, options = {}) {
|
||||
async fetchLatestChanges(serverUrl, options = {}) {
|
||||
const { expectedTimestamp, lastEtag = "", filters = {} } = options;
|
||||
|
||||
//
|
||||
// Fetch the list of changes objects from the server that looks like:
|
||||
// {"data":[
|
||||
@ -63,6 +65,8 @@ var Utils = {
|
||||
// "collection":"certificates"
|
||||
// }]}
|
||||
|
||||
let url = serverUrl + Utils.CHANGES_PATH;
|
||||
|
||||
// Use ETag to obtain a `304 Not modified` when no change occurred,
|
||||
// and `?_since` parameter to only keep entries that weren't processed yet.
|
||||
const headers = {};
|
||||
|
@ -33,13 +33,11 @@ const PREF_SETTINGS_BRANCH = "services.settings.";
|
||||
const PREF_SETTINGS_SERVER = "server";
|
||||
const PREF_SETTINGS_DEFAULT_SIGNER = "default_signer";
|
||||
const PREF_SETTINGS_SERVER_BACKOFF = "server.backoff";
|
||||
const PREF_SETTINGS_CHANGES_PATH = "changes.path";
|
||||
const PREF_SETTINGS_LAST_UPDATE = "last_update_seconds";
|
||||
const PREF_SETTINGS_LAST_ETAG = "last_etag";
|
||||
const PREF_SETTINGS_CLOCK_SKEW_SECONDS = "clock_skew_seconds";
|
||||
const PREF_SETTINGS_LOAD_DUMP = "load_dump";
|
||||
|
||||
|
||||
// Telemetry identifiers.
|
||||
const TELEMETRY_COMPONENT = "remotesettings";
|
||||
const TELEMETRY_SOURCE_POLL = "settings-changes-monitoring";
|
||||
@ -48,11 +46,13 @@ const TELEMETRY_SOURCE_SYNC = "settings-sync";
|
||||
// Push broadcast id.
|
||||
const BROADCAST_ID = "remote-settings/monitor_changes";
|
||||
|
||||
// Signer to be used when not specified (see Ci.nsIContentSignatureVerifier).
|
||||
const DEFAULT_SIGNER = "remote-settings.content-signature.mozilla.org";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gPrefs", () => {
|
||||
return Services.prefs.getBranch(PREF_SETTINGS_BRANCH);
|
||||
});
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "gServerURL", PREF_SETTINGS_BRANCH + PREF_SETTINGS_SERVER);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "gChangesPath", PREF_SETTINGS_BRANCH + PREF_SETTINGS_CHANGES_PATH);
|
||||
|
||||
/**
|
||||
* Default entry filtering function, in charge of excluding remote settings entries
|
||||
@ -84,10 +84,9 @@ function remoteSettingsFunction() {
|
||||
let _invalidatePolling = false;
|
||||
|
||||
// If not explicitly specified, use the default signer.
|
||||
const defaultSigner = gPrefs.getCharPref(PREF_SETTINGS_DEFAULT_SIGNER);
|
||||
const defaultOptions = {
|
||||
bucketNamePref: PREF_SETTINGS_DEFAULT_BUCKET,
|
||||
signerName: defaultSigner,
|
||||
signerName: DEFAULT_SIGNER,
|
||||
filterFunc: jexlFilterFunc,
|
||||
};
|
||||
|
||||
@ -112,12 +111,6 @@ function remoteSettingsFunction() {
|
||||
return _clients.get(collectionName);
|
||||
};
|
||||
|
||||
Object.defineProperty(remoteSettings, "pollingEndpoint", {
|
||||
get() {
|
||||
return gServerURL + gChangesPath;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Internal helper to retrieve existing instances of clients or new instances
|
||||
* with default options if possible, or `null` if bucket/collection are unknown.
|
||||
@ -186,7 +179,7 @@ function remoteSettingsFunction() {
|
||||
|
||||
let pollResult;
|
||||
try {
|
||||
pollResult = await Utils.fetchLatestChanges(remoteSettings.pollingEndpoint, { expectedTimestamp, lastEtag });
|
||||
pollResult = await Utils.fetchLatestChanges(gServerURL, { expectedTimestamp, lastEtag });
|
||||
} catch (e) {
|
||||
// Report polling error to Uptake Telemetry.
|
||||
let reportStatus;
|
||||
@ -291,7 +284,7 @@ function remoteSettingsFunction() {
|
||||
* known remote settings collections.
|
||||
*/
|
||||
remoteSettings.inspect = async () => {
|
||||
const { changes, currentEtag: serverTimestamp } = await Utils.fetchLatestChanges(remoteSettings.pollingEndpoint);
|
||||
const { changes, currentEtag: serverTimestamp } = await Utils.fetchLatestChanges(gServerURL);
|
||||
|
||||
const collections = await Promise.all(changes.map(async (change) => {
|
||||
const { bucket, collection, last_modified: serverTimestamp } = change;
|
||||
@ -314,11 +307,12 @@ function remoteSettingsFunction() {
|
||||
|
||||
return {
|
||||
serverURL: gServerURL,
|
||||
pollingEndpoint: gServerURL + Utils.CHANGES_PATH,
|
||||
serverTimestamp,
|
||||
localTimestamp: gPrefs.getCharPref(PREF_SETTINGS_LAST_ETAG, null),
|
||||
lastCheck: gPrefs.getIntPref(PREF_SETTINGS_LAST_UPDATE, 0),
|
||||
mainBucket: Services.prefs.getCharPref(PREF_SETTINGS_DEFAULT_BUCKET),
|
||||
defaultSigner,
|
||||
defaultSigner: DEFAULT_SIGNER,
|
||||
collections: collections.filter(c => !!c),
|
||||
};
|
||||
};
|
||||
|
@ -2,4 +2,6 @@
|
||||
resource services-settings resource://gre/modules/services-settings/
|
||||
|
||||
# Schedule polling of remote settings changes
|
||||
category update-timer RemoteSettingsComponents @mozilla.org/services/settings;1,getService,services-settings-poll-changes,services.settings.poll_interval,86400
|
||||
# (default 24H, max 72H)
|
||||
# see syntax https://searchfox.org/mozilla-central/rev/cc280c4be94ff8cf64a27cc9b3d6831ffa49fa45/toolkit/components/timermanager/UpdateTimerManager.jsm#155
|
||||
category update-timer RemoteSettingsComponents @mozilla.org/services/settings;1,getService,services-settings-poll-changes,services.settings.poll_interval,86400,259200
|
||||
|
@ -104,10 +104,10 @@ add_task(async function test_support_of_preferences_filters() {
|
||||
filter_expression: '"services.settings.last_etag"|preferenceValue == 42',
|
||||
}, {
|
||||
willMatch: true,
|
||||
filter_expression: '"services.settings.changes.path"|preferenceExists == true',
|
||||
filter_expression: '"services.settings.default_bucket"|preferenceExists == true',
|
||||
}, {
|
||||
willMatch: true,
|
||||
filter_expression: '"services.settings.changes.path"|preferenceIsUserSet == false',
|
||||
filter_expression: '"services.settings.default_bucket"|preferenceIsUserSet == false',
|
||||
}, {
|
||||
willMatch: true,
|
||||
filter_expression: '"services.settings.last_etag"|preferenceIsUserSet == true',
|
||||
|
@ -12,6 +12,7 @@ const {
|
||||
remoteSettingsBroadcastHandler,
|
||||
BROADCAST_ID,
|
||||
} = ChromeUtils.import("resource://services-settings/remote-settings.js");
|
||||
const { Utils } = ChromeUtils.import("resource://services-settings/Utils.jsm");
|
||||
const { TelemetryTestUtils } = ChromeUtils.import("resource://testing-common/TelemetryTestUtils.jsm");
|
||||
|
||||
|
||||
@ -27,7 +28,7 @@ const DB_NAME = "remote-settings";
|
||||
// Telemetry report result.
|
||||
const TELEMETRY_HISTOGRAM_POLL_KEY = "settings-changes-monitoring";
|
||||
const TELEMETRY_HISTOGRAM_SYNC_KEY = "settings-sync";
|
||||
const CHANGES_PATH = "/v1/buckets/monitor/collections/changes/records";
|
||||
const CHANGES_PATH = "/v1" + Utils.CHANGES_PATH;
|
||||
|
||||
var server;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user