Bug 1429150 - Create an enterprise policy to prevent the application from checking for app updates draft
authorKirk Steuber <ksteuber@mozilla.com>
Wed, 07 Feb 2018 09:49:37 -0800
changeset 753192 d6f66495524c10d3e409ca0744bc7b8b3fc02714
parent 753191 2083298bf813206f209c250053cc7e921cbe32b6
push id98509
push userksteuber@mozilla.com
push dateFri, 09 Feb 2018 19:18:56 +0000
bugs1429150
milestone60.0a1
Bug 1429150 - Create an enterprise policy to prevent the application from checking for app updates MozReview-Commit-ID: 4K4U4AJw7V1
browser/components/enterprisepolicies/EnterprisePolicies.js
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_app_update.js
browser/components/enterprisepolicies/tests/browser/disable_app_update/browser.ini
browser/components/enterprisepolicies/tests/browser/disable_app_update/browser_policy_disable_app_update.js
browser/components/enterprisepolicies/tests/browser/disable_app_update/config_disable_app_update.json
browser/components/enterprisepolicies/tests/moz.build
toolkit/modules/Services.jsm
--- a/browser/components/enterprisepolicies/EnterprisePolicies.js
+++ b/browser/components/enterprisepolicies/EnterprisePolicies.js
@@ -15,16 +15,22 @@ XPCOMUtils.defineLazyModuleGetters(this,
 // This is the file that will be searched for in the
 // ${InstallDir}/distribution folder.
 const POLICIES_FILENAME = "policies.json";
 
 // For easy testing, modify the helpers/sample.json file,
 // and set PREF_ALTERNATE_PATH in firefox.js as:
 // /your/repo/browser/components/enterprisepolicies/helpers/sample.json
 const PREF_ALTERNATE_PATH     = "browser.policies.alternatePath";
+// For testing, we may want to set PREF_ALTERNATE_PATH to point to a file
+// relative to the test root directory. In order to enable this, the string
+// below may be placed at the beginning of that preference value and it will
+// be replaced with the path to the test root directory.
+const MAGIC_TEST_ROOT_PREFIX  = "<test-root>";
+const PREF_TEST_ROOT          = "mochitest.testRoot";
 
 // This pref is meant to be temporary: it will only be used while we're
 // testing this feature without rolling it out officially. When the
 // policy engine is released, this pref should be removed.
 const PREF_ENABLED            = "browser.policies.enabled";
 const PREF_LOGLEVEL           = "browser.policies.loglevel";
 
 XPCOMUtils.defineLazyGetter(this, "log", () => {
@@ -314,16 +320,28 @@ class JSONPoliciesProvider {
     let alternatePath = Services.prefs.getStringPref(PREF_ALTERNATE_PATH, "");
 
     if (alternatePath && !configFile.exists()) {
       // We only want to use the alternate file path if the file on the install
       // folder doesn't exist. Otherwise it'd be possible for a user to override
       // the admin-provided policies by changing the user-controlled prefs.
       // This pref is only meant for tests, so it's fine to use this extra
       // synchronous configFile.exists() above.
+      if (alternatePath.startsWith(MAGIC_TEST_ROOT_PREFIX)) {
+        // Intentionally not using a default value on this pref lookup. If no
+        // test root is set, we are not currently testing and this function
+        // should throw rather than returning something.
+        let testRoot = Services.prefs.getStringPref(PREF_TEST_ROOT);
+        let relativePath = alternatePath.substring(MAGIC_TEST_ROOT_PREFIX.length);
+        if (AppConstants.platform == "win") {
+          relativePath = relativePath.replace(/\//g, "\\");
+        }
+        alternatePath = testRoot + relativePath;
+      }
+
       configFile = Cc["@mozilla.org/file/local;1"]
                      .createInstance(Ci.nsIFile);
       configFile.initWithPath(alternatePath);
     }
 
     return configFile;
   }
 
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -32,16 +32,24 @@ this.Policies = {
   "block_about_config": {
     onBeforeUIStartup(manager, param) {
       if (param == true) {
         manager.disallowFeature("about:config", true);
       }
     }
   },
 
+  "DisableAppUpdate": {
+    onBeforeAddons(manager, param) {
+      if (param == true) {
+        manager.disallowFeature("appUpdate");
+      }
+    }
+  },
+
   "display_menu_bar": {
     onBeforeUIStartup(manager, param) {
       if (param == true) {
         // This policy is meant to change the default behavior, not to force it.
         // If this policy was alreay applied and the user chose to re-hide the
         // menu bar, do not show it again.
         if (!Services.prefs.getBoolPref(PREF_MENU_ALREADY_DISPLAYED, false)) {
           log.debug("Showing the menu bar");
--- a/browser/components/enterprisepolicies/schemas/policies-schema.json
+++ b/browser/components/enterprisepolicies/schemas/policies-schema.json
@@ -5,16 +5,25 @@
     "block_about_config": {
       "description": "Blocks access to the about:config page.",
       "first_available": "60.0",
 
       "type": "boolean",
       "enum": [true]
     },
 
+    "DisableAppUpdate": {
+      "description": "Prevent the browser from updating.",
+      "first_available": "60.0",
+      "enterprise_only": true,
+
+      "type": "boolean",
+      "enum": [true]
+    },
+
     "display_menu_bar": {
       "description": "Causes the menu bar to be displayed by default.",
       "first_available": "60.0",
 
       "type": "boolean",
       "enum": [true]
     },
 
--- a/browser/components/enterprisepolicies/tests/browser/browser.ini
+++ b/browser/components/enterprisepolicies/tests/browser/browser.ini
@@ -6,15 +6,16 @@ support-files =
   config_popups_cookies_addons_flash.json
   config_broken_json.json
 
 [browser_policies_broken_json.js]
 [browser_policies_popups_cookies_addons_flash.js]
 [browser_policies_setAndLockPref_API.js]
 [browser_policies_simple_policies.js]
 [browser_policies_validate_and_parse_API.js]
+[browser_policy_app_update.js]
 [browser_policy_block_set_desktop_background.js]
 [browser_policy_default_browser_check.js]
 [browser_policy_disable_fxscreenshots.js]
 [browser_policy_display_bookmarks.js]
 [browser_policy_display_menu.js]
 [browser_policy_disable_shield.js]
 
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policy_app_update.js
@@ -0,0 +1,19 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+var updateService = Cc["@mozilla.org/updates/update-service;1"].
+                    getService(Ci.nsIApplicationUpdateService);
+
+// This test is intended to ensure that nsIUpdateService::canCheckForUpdates
+// is true before the "DisableAppUpdate" policy is applied. Testing that
+// nsIUpdateService::canCheckForUpdates is false after the "DisableAppUpdate"
+// policy is applied needs to occur in a different test since the policy does
+// not properly take effect unless it is applied during application startup.
+add_task(async function test_updates_pre_policy() {
+  is(Services.policies.isAllowed("appUpdate"), true,
+     "Since no policies have been set, appUpdate should be allowed by default");
+
+  is(updateService.canCheckForUpdates, true,
+     "Should be able to check for updates before any policies are in effect.");
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/disable_app_update/browser.ini
@@ -0,0 +1,8 @@
+[DEFAULT]
+prefs =
+  browser.policies.enabled=true
+  browser.policies.alternatePath='<test-root>/browser/components/enterprisepolicies/tests/browser/disable_app_update/config_disable_app_update.json'
+support-files =
+  config_disable_app_update.json
+
+[browser_policy_disable_app_update.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/disable_app_update/browser_policy_disable_app_update.js
@@ -0,0 +1,14 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+var updateService = Cc["@mozilla.org/updates/update-service;1"].
+                    getService(Ci.nsIApplicationUpdateService);
+
+add_task(async function test_updates_post_policy() {
+  is(Services.policies.isAllowed("appUpdate"), false,
+     "appUpdate should be disabled by policy.");
+
+  is(updateService.canCheckForUpdates, false,
+     "Should not be able to check for updates with DisableAppUpdate enabled.");
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/disable_app_update/config_disable_app_update.json
@@ -0,0 +1,5 @@
+{
+  "policies": {
+    "DisableAppUpdate": true
+  }
+}
--- a/browser/components/enterprisepolicies/tests/moz.build
+++ b/browser/components/enterprisepolicies/tests/moz.build
@@ -3,10 +3,11 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 with Files("**"):
     BUG_COMPONENT = ("Firefox", "General")
 
 BROWSER_CHROME_MANIFESTS += [
-    'browser/browser.ini'
+    'browser/browser.ini',
+    'browser/disable_app_update/browser.ini'
 ]
--- a/toolkit/modules/Services.jsm
+++ b/toolkit/modules/Services.jsm
@@ -113,15 +113,15 @@ if (AppConstants.platform == "android") 
   initTable.androidBridge = ["@mozilla.org/android/bridge;1", "nsIAndroidBridge"];
 }
 if (AppConstants.MOZ_GECKO_PROFILER) {
   initTable.profiler = ["@mozilla.org/tools/profiler;1", "nsIProfiler"];
 }
 if (AppConstants.MOZ_TOOLKIT_SEARCH) {
   initTable.search = ["@mozilla.org/browser/search-service;1", "nsIBrowserSearchService"];
 }
-if (AppConstants.MOZ_BUILD_APP == "browser") {
+if ("@mozilla.org/browser/enterprisepolicies;1" in Cc) {
   initTable.policies = ["@mozilla.org/browser/enterprisepolicies;1", "nsIEnterprisePolicies"];
 }
 
 XPCOMUtils.defineLazyServiceGetters(Services, initTable);
 
 initTable = undefined;