Bug 1429157 - Create an enterprise policy to prevent profile refreshes draft
authorKirk Steuber <ksteuber@mozilla.com>
Wed, 28 Mar 2018 09:44:07 -0700
changeset 777319 a3aeb9c3eb9432cc571cec40219ff382e8a45175
parent 776876 bb753b191f83d14f65650724d8cf1adf6d51a154
child 777372 d284c22496c9d1940cde8939948c76af1cb4027b
child 777392 a54a55b317cc580425edbd3b62419018dda6bc82
push id105169
push userksteuber@mozilla.com
push dateWed, 04 Apr 2018 16:43:01 +0000
bugs1429157
milestone61.0a1
Bug 1429157 - Create an enterprise policy to prevent profile refreshes MozReview-Commit-ID: K7yxDm0H7eH
browser/components/enterprisepolicies/Policies.jsm
browser/components/enterprisepolicies/schemas/policies-schema.json
browser/components/enterprisepolicies/tests/browser/browser.ini
browser/components/enterprisepolicies/tests/browser/browser_policy_disable_profile_reset.js
toolkit/modules/ResetProfile.jsm
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -278,16 +278,25 @@ var Policies = {
       if (param) {
         manager.disallowFeature("privatebrowsing");
         manager.disallowFeature("about:privatebrowsing", true);
         setAndLockPref("browser.privatebrowsing.autostart", false);
       }
     }
   },
 
+  "DisableProfileRefresh": {
+    onBeforeUIStartup(manager, param) {
+      if (param) {
+        manager.disallowFeature("profileRefresh");
+        setAndLockPref("browser.disableResetPrompt", true);
+      }
+    }
+  },
+
   "DisableSafeMode": {
     onBeforeUIStartup(manager, param) {
       if (param) {
         manager.disallowFeature("safeMode");
       }
     }
   },
 
--- a/browser/components/enterprisepolicies/schemas/policies-schema.json
+++ b/browser/components/enterprisepolicies/schemas/policies-schema.json
@@ -222,16 +222,23 @@
 
     "DisablePrivateBrowsing": {
       "description": "Disables private browsing.",
       "first_available": "60.0",
 
       "type": "boolean"
     },
 
+    "DisableProfileRefresh": {
+      "description": "Disables the \"Refresh Firefox\" button in about:support",
+      "first_available": "60.0",
+
+      "type": "boolean"
+    },
+
     "DisableSafeMode": {
       "description": "Prevents ability to restart in safe mode.",
       "first_available": "60.0",
 
       "type": "boolean"
     },
 
     "DisableSysAddonUpdate": {
--- a/browser/components/enterprisepolicies/tests/browser/browser.ini
+++ b/browser/components/enterprisepolicies/tests/browser/browser.ini
@@ -32,16 +32,17 @@ support-files =
 [browser_policy_disable_feedback_commands.js]
 [browser_policy_disable_flash_plugin.js]
 [browser_policy_disable_fxaccounts.js]
 [browser_policy_disable_masterpassword.js]
 [browser_policy_disable_pdfjs.js]
 [browser_policy_disable_pocket.js]
 [browser_policy_disable_popup_blocker.js]
 [browser_policy_disable_privatebrowsing.js]
+[browser_policy_disable_profile_reset.js]
 [browser_policy_disable_safemode.js]
 [browser_policy_disable_shield.js]
 [browser_policy_disable_telemetry.js]
 [browser_policy_display_bookmarks.js]
 [browser_policy_display_menu.js]
 [browser_policy_extensions.js]
 [browser_policy_proxy.js]
 [browser_policy_search_engine.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policy_disable_profile_reset.js
@@ -0,0 +1,53 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+let {ResetProfile} = ChromeUtils.import("resource://gre/modules/ResetProfile.jsm", {});
+
+// For this test to work properly, this profile actually needs to be
+// "reset-able", which requires that it be recognized by the profile service
+add_task(async function setup() {
+  let profileDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile);
+  let profileName = profileDirectory.leafName;
+  let profileService = Cc["@mozilla.org/toolkit/profile-service;1"].
+                       getService(Ci.nsIToolkitProfileService);
+  let createdProfile = profileService.createProfile(profileDirectory, profileName);
+  profileService.flush();
+  registerCleanupFunction(async function cleanup() {
+    // Pass false to remove it from the profile service without deleting files.
+    createdProfile.remove(false);
+  });
+});
+
+async function test_reset_disabled({disabled}) {
+  is(ResetProfile.resetSupported(), !disabled,
+     "Reset should only be supported if policy has not been applied");
+  is(Services.prefs.getBoolPref("browser.disableResetPrompt", undefined),
+     disabled, "Reset prompt should only be shown if policy has not been applied");
+  is(Services.prefs.prefIsLocked("browser.disableResetPrompt"), disabled,
+     "Reset prompt pref should be locked if the policy has been applied");
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:support");
+  // eslint-disable-next-line no-shadow
+  await ContentTask.spawn(tab.linkedBrowser, {disabled}, async function({disabled}) {
+    let resetBox = content.document.getElementById("reset-box");
+    let elementStyle = content.window.getComputedStyle(resetBox);
+    let expectedDisplayValue = disabled ? "none" : "block";
+    is(elementStyle.display, expectedDisplayValue,
+       "about:support Reset button box should be hidden");
+  });
+  await BrowserTestUtils.removeTab(tab);
+}
+
+add_task(async function test_initial_conditions() {
+  await test_reset_disabled({disabled: false});
+});
+
+add_task(async function test_policy_disable_reset() {
+  await setupPolicyEngineWithJson({
+    "policies": {
+      "DisableProfileRefresh": true
+    }
+  });
+  await test_reset_disabled({disabled: true});
+});
--- a/toolkit/modules/ResetProfile.jsm
+++ b/toolkit/modules/ResetProfile.jsm
@@ -14,16 +14,19 @@ const MOZ_BUILD_APP = AppConstants.MOZ_B
 
 var ResetProfile = {
   /**
    * Check if reset is supported for the currently running profile.
    *
    * @return boolean whether reset is supported.
    */
   resetSupported() {
+    if (Services.policies && !Services.policies.isAllowed("profileRefresh")) {
+      return false;
+    }
     // Reset is only supported if the self-migrator used for reset exists.
     let migrator = "@mozilla.org/profile/migrator;1?app=" + MOZ_BUILD_APP +
                    "&type=" + MOZ_APP_NAME;
     if (!(migrator in Cc)) {
       return false;
     }
     // We also need to be using a profile the profile manager knows about.
     let profileService = Cc["@mozilla.org/toolkit/profile-service;1"].