Bug 1524862 - Enforce expected category prefs even if enterprise policy changes the defaults. r=johannh
authorErica Wright <ewright@mozilla.com>
Fri, 01 Mar 2019 15:11:11 +0000
changeset 519864 ad25e831bd26dae15f44c7224004749a13099032
parent 519863 bd930453714efe8f6aa756938c1c09a24ec79cd4
child 519865 413a18c16f0e08f8789a9bb61f5b894a95ea7a08
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1524862
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1524862 - Enforce expected category prefs even if enterprise policy changes the defaults. r=johannh Enforce expected category prefs even if enterprise policy changes the defaults. Lock user in custom if one of the relevant policy prefs are locked. Differential Revision: https://phabricator.services.mozilla.com/D21088
browser/components/BrowserGlue.jsm
browser/components/preferences/in-content/privacy.js
browser/components/preferences/in-content/tests/browser_contentblocking.js
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -3095,16 +3095,25 @@ var ContentBlockingCategoriesPrefs = {
     // a change of one of these prefs necessarily puts us in "custom".
     if (this.prefsMatch("standard")) {
       Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "standard");
     } else if (this.prefsMatch("strict")) {
       Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "strict");
     } else {
       Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "custom");
     }
+
+    // If there is a custom policy which changes a related pref, then put the user in custom so
+    // they still have access to other content blocking prefs, and to keep our default definitions
+    // from changing.
+    let policy = Services.policies.getActivePolicies();
+    if (policy && (policy.EnableTrackingProtection ||
+        policy.Cookies)) {
+      Services.prefs.setStringPref(this.PREF_CB_CATEGORY, "custom");
+    }
   },
 
   updateCBCategory() {
     if (this.switchingCategory || !Services.prefs.prefHasUserValue(this.PREF_CB_CATEGORY)) {
       return;
     }
     // Turn on switchingCategory flag, to ensure that when the individual prefs that change as a result
     // of the category change do not trigger yet another category change.
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -16,16 +16,22 @@ ChromeUtils.defineModuleGetter(this, "Si
 
 var {PrivateBrowsingUtils} = ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
 
 const TRACKING_PROTECTION_KEY = "websites.trackingProtectionMode";
 const TRACKING_PROTECTION_PREFS = ["privacy.trackingprotection.enabled",
                                    "privacy.trackingprotection.pbmode.enabled"];
+const CONTENT_BLOCKING_PREFS = ["privacy.trackingprotection.enabled",
+                                "privacy.trackingprotection.pbmode.enabled",
+                                "network.cookie.cookieBehavior",
+                                "privacy.trackingprotection.fingerprinting.enabled",
+                                "privacy.trackingprotection.cryptomining.enabled",
+                                "urlclassifier.trackingTable"];
 
 const PREF_OPT_OUT_STUDIES_ENABLED = "app.shield.optoutstudies.enabled";
 const PREF_NORMANDY_ENABLED = "app.normandy.enabled";
 
 const PREF_ADDON_RECOMMENDATIONS_ENABLED = "browser.discovery.enabled";
 
 XPCOMUtils.defineLazyGetter(this, "AlertsServiceDND", function() {
   try {
@@ -173,51 +179,59 @@ var gPrivacyPane = {
    * Whether the prompt to restart Firefox should appear when changing the autostart pref.
    */
   _shouldPromptForRestart: true,
 
   /**
    * Update the tracking protection UI to deal with extension control.
    */
   _updateTrackingProtectionUI() {
-    let isLocked = TRACKING_PROTECTION_PREFS.some(
+    let cBPrefisLocked = CONTENT_BLOCKING_PREFS.some(
+      pref => Services.prefs.prefIsLocked(pref));
+    let tPPrefisLocked = TRACKING_PROTECTION_PREFS.some(
       pref => Services.prefs.prefIsLocked(pref));
 
     function setInputsDisabledState(isControlled) {
-      let disabled = isLocked || isControlled;
+      let tpDisabled = tPPrefisLocked || isControlled;
+      let disabled = cBPrefisLocked || isControlled;
       let tpCheckbox =
         document.getElementById("contentBlockingTrackingProtectionCheckbox");
       // Only enable the TP menu if Detect All Trackers is enabled.
-      document.getElementById("trackingProtectionMenu").disabled = disabled ||
+      document.getElementById("trackingProtectionMenu").disabled = tpDisabled ||
         !tpCheckbox.checked;
-      tpCheckbox.disabled = disabled;
+      tpCheckbox.disabled = tpDisabled;
 
-      document.getElementById("standardRadio").disabled = isControlled;
-      document.getElementById("strictRadio").disabled = isControlled;
-      document.getElementById("contentBlockingOptionStrict").classList.toggle("disabled", isControlled);
-      document.getElementById("contentBlockingOptionStandard").classList.toggle("disabled", isControlled);
+      document.getElementById("standardRadio").disabled = disabled;
+      document.getElementById("strictRadio").disabled = disabled;
+      document.getElementById("contentBlockingOptionStrict").classList.toggle("disabled", disabled);
+      document.getElementById("contentBlockingOptionStandard").classList.toggle("disabled", disabled);
       let arrowButtons = document.querySelectorAll("button.arrowhead");
       for (let button of arrowButtons) {
-        button.disabled = isControlled;
+        button.disabled = disabled;
       }
 
       // Notify observers that the TP UI has been updated.
       // This is needed since our tests need to be notified about the
       // trackingProtectionMenu element getting disabled/enabled at the right time.
       Services.obs.notifyObservers(window, "privacy-pane-tp-ui-updated");
     }
 
     // We watch the network.cookie.cookieBehavior default value, if it is
     // BEHAVIOR_ACCEPT (0) then show the fallback UI. When we change
     // this default to BEHAVIOR_REJECT_TRACKER (4) show our default UI.
     let defaults = Services.prefs.getDefaultBranch("");
     document.getElementById("contentBlockingCategories").toggleAttribute("fallback-ui",
       defaults.getIntPref("network.cookie.cookieBehavior") === Ci.nsICookieService.BEHAVIOR_ACCEPT);
 
-    if (isLocked) {
+    let policy = Services.policies.getActivePolicies();
+    if (policy && ((policy.EnableTrackingProtection && policy.EnableTrackingProtection.Locked) ||
+        (policy.Cookies && policy.Cookies.Locked))) {
+      setInputsDisabledState(true);
+    }
+    if (tPPrefisLocked) {
       // An extension can't control this setting if either pref is locked.
       hideControllingExtension(TRACKING_PROTECTION_KEY);
       setInputsDisabledState(false);
     } else {
       handleControllingExtension(
         PREF_SETTING_TYPE,
         TRACKING_PROTECTION_KEY)
           .then(setInputsDisabledState);
--- a/browser/components/preferences/in-content/tests/browser_contentblocking.js
+++ b/browser/components/preferences/in-content/tests/browser_contentblocking.js
@@ -6,16 +6,31 @@ ChromeUtils.defineModuleGetter(this, "Pr
 const TP_PREF = "privacy.trackingprotection.enabled";
 const TP_PBM_PREF = "privacy.trackingprotection.pbmode.enabled";
 const TP_LIST_PREF = "urlclassifier.trackingTable";
 const NCB_PREF = "network.cookie.cookieBehavior";
 const CAT_PREF = "browser.contentblocking.category";
 const FP_PREF = "privacy.trackingprotection.fingerprinting.enabled";
 const CM_PREF = "privacy.trackingprotection.cryptomining.enabled";
 
+const {
+  EnterprisePolicyTesting,
+  PoliciesPrefTracker,
+} = ChromeUtils.import("resource://testing-common/EnterprisePolicyTesting.jsm", null);
+
+registerCleanupFunction(async function policies_headjs_finishWithCleanSlate() {
+  if (Services.policies.status != Ci.nsIEnterprisePolicies.INACTIVE) {
+    await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
+  }
+  is(Services.policies.status, Ci.nsIEnterprisePolicies.INACTIVE, "Engine is inactive at the end of the test");
+
+  EnterprisePolicyTesting.resetRunOnceState();
+  PoliciesPrefTracker.stop();
+});
+
 requestLongerTimeout(2);
 
 // Tests that the content blocking main category checkboxes have the correct default state.
 add_task(async function testContentBlockingMainCategory() {
   let prefs = [
     [TP_PREF, false],
     [TP_PBM_PREF, true],
     [NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
@@ -350,8 +365,52 @@ add_task(async function testCustomOption
   ok(!cryptominersOption.hidden, "Cryptomining is shown");
   ok(!fingerprintersOption.hidden, "Fingerprinting is shown");
 
   gBrowser.removeCurrentTab();
 
   Services.prefs.clearUserPref("browser.contentblocking.cryptomining.preferences.ui.enabled");
   Services.prefs.clearUserPref("browser.contentblocking.fingerprinting.preferences.ui.enabled");
 });
+
+// Checks that adding a custom enterprise policy will put the user in the custom category.
+// Other categories will be disabled.
+add_task(async function testPolicyCategorization() {
+  Services.prefs.setStringPref(CAT_PREF, "standard");
+  is(Services.prefs.getStringPref(CAT_PREF), "standard", `${CAT_PREF} starts on standard`);
+  is(Services.prefs.getBoolPref(TP_PREF), false, `${TP_PREF} starts on false`);
+  PoliciesPrefTracker.start();
+
+  await EnterprisePolicyTesting.setupPolicyEngineWithJson({
+    policies: {"EnableTrackingProtection": {
+        "Value": true,
+      },
+    },
+  });
+  EnterprisePolicyTesting.checkPolicyPref(TP_PREF, true, false);
+  is(Services.prefs.getStringPref(CAT_PREF), "custom", `${CAT_PREF} has been set to custom`);
+
+  Services.prefs.setStringPref(CAT_PREF, "standard");
+  is(Services.prefs.getStringPref(CAT_PREF), "standard", `${CAT_PREF} starts on standard`);
+  is(Services.prefs.getIntPref(NCB_PREF), 4, `${NCB_PREF} starts on 4`);
+
+  let uiUpdatedPromise = TestUtils.topicObserved("privacy-pane-tp-ui-updated");
+  await EnterprisePolicyTesting.setupPolicyEngineWithJson({
+    policies: {"Cookies": {
+        "AcceptThirdParty": "never",
+        "Locked": true,
+      },
+    },
+  });
+  await openPreferencesViaOpenPreferencesAPI("privacy", {leaveOpen: true});
+  await uiUpdatedPromise;
+
+  EnterprisePolicyTesting.checkPolicyPref(NCB_PREF, 1, true);
+  is(Services.prefs.getStringPref(CAT_PREF), "custom", `${CAT_PREF} has been set to custom`);
+
+  let doc = gBrowser.contentDocument;
+  let strictRadioOption = doc.getElementById("strictRadio");
+  let standardRadioOption = doc.getElementById("standardRadio");
+  is(strictRadioOption.disabled, true, "the strict option is disabled");
+  is(standardRadioOption.disabled, true, "the standard option is disabled");
+
+  gBrowser.removeCurrentTab();
+});