Bug 1436840 - Policy engine: Add support for enterprise-only policies. r=mkaply
authorFelipe Gomes <felipc@gmail.com>
Mon, 05 Mar 2018 20:46:54 -0300
changeset 461648 28a1060ab28344af513fa9169ad9f6f8a06f49d6
parent 461647 e0a165295ef81483c10ae295769d6a5980b52225
child 461649 142d7e0ffe7eb71729c904353d04a76c30ff90eb
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkaply
bugs1436840
milestone60.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 1436840 - Policy engine: Add support for enterprise-only policies. r=mkaply Policies annotated with enterprise_only in the schema will only be allowed to run on ESR or on pre-release channels (for testing) MozReview-Commit-ID: 4tF8t1ozyVp
browser/components/enterprisepolicies/EnterprisePolicies.js
browser/components/enterprisepolicies/tests/browser/browser.ini
browser/components/enterprisepolicies/tests/browser/browser_policies_enterprise_only.js
--- a/browser/components/enterprisepolicies/EnterprisePolicies.js
+++ b/browser/components/enterprisepolicies/EnterprisePolicies.js
@@ -28,16 +28,19 @@ const MAGIC_TEST_ROOT_PREFIX  = "<test-r
 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";
 
+// To force disallowing enterprise-only policies during tests
+const PREF_DISALLOW_ENTERPRISE = "browser.policies.testing.disallowEnterprise";
+
 XPCOMUtils.defineLazyGetter(this, "log", () => {
   let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
   return new ConsoleAPI({
     prefix: "Enterprise Policies",
     // tip: set maxLogLevel to "debug" and use log.debug() to create detailed
     // messages during development. See LOG_LEVELS in Console.jsm for details.
     maxLogLevel: "error",
     maxLogLevelPref: PREF_LOGLEVEL,
@@ -122,16 +125,21 @@ EnterprisePoliciesManager.prototype = {
       let policySchema = schema.properties[policyName];
       let policyParameters = unparsedPolicies[policyName];
 
       if (!policySchema) {
         log.error(`Unknown policy: ${policyName}`);
         continue;
       }
 
+      if (policySchema.enterprise_only && !areEnterpriseOnlyPoliciesAllowed()) {
+        log.error(`Policy ${policyName} is only allowed on ESR`);
+        continue;
+      }
+
       let [parametersAreValid, parsedParameters] =
         PoliciesValidator.validateAndParseParameters(policyParameters,
                                                      policySchema);
 
       if (!parametersAreValid) {
         log.error(`Invalid parameters specified for ${policyName}.`);
         continue;
       }
@@ -300,16 +308,43 @@ EnterprisePoliciesManager.prototype = {
 
   isAllowed: function BG_sanitize(feature) {
     return !(feature in DisallowedFeatures);
   },
 };
 
 let DisallowedFeatures = {};
 
+/**
+ * areEnterpriseOnlyPoliciesAllowed
+ *
+ * Checks whether the policies marked as enterprise_only in the
+ * schema are allowed to run on this browser.
+ *
+ * This is meant to only allow policies to run on ESR, but in practice
+ * we allow it to run on channels different than release, to allow
+ * these policies to be tested on pre-release channels.
+ *
+ * @returns {Bool} Whether the policy can run.
+ */
+function areEnterpriseOnlyPoliciesAllowed() {
+  if (Services.prefs.getBoolPref(PREF_DISALLOW_ENTERPRISE, false)) {
+    // This is used as an override to test the "enterprise_only"
+    // functionality itself on tests, which would always return
+    // true due to the Cu.isInAutomation check below.
+    return false;
+  }
+
+  if (AppConstants.MOZ_UPDATE_CHANNEL != "release" ||
+      Cu.isInAutomation) {
+    return true;
+  }
+
+  return false;
+}
 
 /*
  * JSON PROVIDER OF POLICIES
  *
  * This is a platform-agnostic provider which looks for
  * policies specified through a policies.json file stored
  * in the installation's distribution folder.
  */
--- a/browser/components/enterprisepolicies/tests/browser/browser.ini
+++ b/browser/components/enterprisepolicies/tests/browser/browser.ini
@@ -2,16 +2,17 @@
 prefs =
   browser.policies.enabled=true
 support-files =
   head.js
   config_popups_cookies_addons_flash.json
   config_broken_json.json
 
 [browser_policies_broken_json.js]
+[browser_policies_enterprise_only.js]
 [browser_policies_notice_in_aboutpreferences.js]
 [browser_policies_popups_cookies_addons_flash.js]
 [browser_policies_runOnce_helper.js]
 [browser_policies_setAndLockPref_API.js]
 [browser_policies_simple_policies.js]
 [browser_policies_sorted_alphabetically.js]
 [browser_policies_validate_and_parse_API.js]
 [browser_policy_app_update.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policies_enterprise_only.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const PREF_DISALLOW_ENTERPRISE = "browser.policies.testing.disallowEnterprise";
+
+add_task(async function test_enterprise_only_policies() {
+  let { Policies } = ChromeUtils.import("resource:///modules/policies/Policies.jsm", {});
+
+  let normalPolicyRan = false, enterprisePolicyRan = false;
+
+  Policies.NormalPolicy = {
+    onProfileAfterChange(manager, param) {
+      normalPolicyRan = true;
+    }
+  };
+
+  Policies.EnterpriseOnlyPolicy = {
+    onProfileAfterChange(manager, param) {
+      enterprisePolicyRan = true;
+    }
+  };
+
+  Services.prefs.setBoolPref(PREF_DISALLOW_ENTERPRISE, true);
+
+  await setupPolicyEngineWithJson(
+    // policies.json
+    {
+      "policies": {
+        "NormalPolicy": true,
+        "EnterpriseOnlyPolicy": true
+      }
+    },
+
+    // custom schema
+    {
+      properties: {
+        "NormalPolicy": {
+          "type": "boolean"
+        },
+
+        "EnterpriseOnlyPolicy": {
+          "type": "boolean",
+          "enterprise_only": true
+        },
+      }
+    }
+  );
+
+  is(Services.policies.status, Ci.nsIEnterprisePolicies.ACTIVE, "Engine is active");
+  is(normalPolicyRan, true, "Normal policy ran as expected");
+  is(enterprisePolicyRan, false, "Enterprise-only policy was prevented from running");
+
+  // Clean-up
+  delete Policies.NormalPolicy;
+  delete Policies.EnterpriseOnlyPolicy;
+  Services.prefs.clearUserPref(PREF_DISALLOW_ENTERPRISE);
+});