Bug 1428923 - Implement setDefaultPrefAndLock helper function needed to implement several policies. r=mkaply draft
authorFelipe Gomes <felipc@gmail.com>
Mon, 15 Jan 2018 18:41:15 -0200
changeset 720604 d2df36727a53af189dfe432e7648685348f7cd68
parent 719904 7f68f584ba72eee9ae2de36db602e7dcd7bc9bd4
child 746101 ccfb81f241f81ac2e23f2cb767b9aff2496d940c
push id95582
push userfelipc@gmail.com
push dateMon, 15 Jan 2018 20:41:42 +0000
reviewersmkaply
bugs1428923
milestone59.0a1
Bug 1428923 - Implement setDefaultPrefAndLock helper function needed to implement several policies. r=mkaply MozReview-Commit-ID: Aq4qRQ2D3LG
browser/components/enterprisepolicies/Policies.jsm
browser/components/enterprisepolicies/tests/browser/browser.ini
browser/components/enterprisepolicies/tests/browser/browser_policies_setAndLockPref_API.js
browser/components/enterprisepolicies/tests/browser/config_setAndLockPref.json
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -84,16 +84,44 @@ this.Policies = {
 
   "cookies": {
     onBeforeUIStartup(manager, param) {
       PermissionPolicies.addAllowDenyPermissions("cookie", param.allow, param.block);
     }
   },
 };
 
+function setAndLockPref(prefName, prefValue) {
+  if (Services.prefs.prefIsLocked(prefName)) {
+    Services.prefs.unlockPref(prefName);
+  }
+
+  let defaults = Services.prefs.getDefaultBranch("");
+
+  switch (typeof(prefValue)) {
+    case "boolean":
+      defaults.setBoolPref(prefName, prefValue);
+      break;
+
+    case "number":
+      if (!Number.isInteger(prefValue)) {
+        throw new Error(`Non-integer value for ${prefName}`);
+      }
+
+      defaults.setIntPref(prefName, prefValue);
+      break;
+
+    case "string":
+      defaults.setStringPref(prefName, prefValue);
+      break;
+  }
+
+  Services.prefs.lockPref(prefName);
+}
+
 function validateAndParseParamRecursive(param, properties) {
   if (properties.enum) {
     if (properties.enum.includes(param)) {
       return [true, param];
     }
     return [false, null];
   }
 
--- a/browser/components/enterprisepolicies/tests/browser/browser.ini
+++ b/browser/components/enterprisepolicies/tests/browser/browser.ini
@@ -1,13 +1,15 @@
 [DEFAULT]
 prefs =
   browser.policies.enabled=true
 support-files =
   head.js
   config_popups_cookies_addons_flash.json
+  config_setAndLockPref.json
   config_simple_policies.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]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policies_setAndLockPref_API.js
@@ -0,0 +1,127 @@
+/* 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/. */
+
+"use strict";
+
+add_task(async function test_clean_slate() {
+  await startWithCleanSlate();
+});
+
+let { Policies, setAndLockPref } = Cu.import("resource:///modules/policies/Policies.jsm", {});
+
+function checkPref(prefName, expectedValue) {
+  let prefType, prefValue;
+  switch (typeof(expectedValue)) {
+    case "boolean":
+      prefType = Services.prefs.PREF_BOOL;
+      prefValue = Services.prefs.getBoolPref(prefName);
+      break;
+
+    case "number":
+      prefType = Services.prefs.PREF_INT;
+      prefValue = Services.prefs.getIntPref(prefName);
+      break;
+
+    case "string":
+      prefType = Services.prefs.PREF_STRING;
+      prefValue = Services.prefs.getStringPref(prefName);
+      break;
+  }
+
+  ok(Services.prefs.prefIsLocked(prefName), `Pref ${prefName} is correctly locked`);
+  is(Services.prefs.getPrefType(prefName), prefType, `Pref ${prefName} has the correct type`);
+  is(prefValue, expectedValue, `Pref ${prefName} has the correct value`);
+}
+
+add_task(async function test_API_directly() {
+  setAndLockPref("policies.test.boolPref", true);
+  checkPref("policies.test.boolPref", true);
+
+  // Check that a previously-locked pref can be changed
+  // (it will be unlocked first).
+  setAndLockPref("policies.test.boolPref", false);
+  checkPref("policies.test.boolPref", false);
+
+  setAndLockPref("policies.test.intPref", 0);
+  checkPref("policies.test.intPref", 0);
+
+  setAndLockPref("policies.test.stringPref", "policies test");
+  checkPref("policies.test.stringPref", "policies test");
+
+  // Test that user values do not override the prefs, and the get*Pref call
+  // still return the value set through setAndLockPref
+  Services.prefs.setBoolPref("policies.test.boolPref", true);
+  checkPref("policies.test.boolPref", false);
+
+  Services.prefs.setIntPref("policies.test.intPref", 10);
+  checkPref("policies.test.intPref", 0);
+
+  Services.prefs.setStringPref("policies.test.stringPref", "policies test");
+  checkPref("policies.test.stringPref", "policies test");
+
+  try {
+    // Test that a non-integer value is correctly rejected, even though
+    // typeof(val) == "number"
+    setAndLockPref("policies.test.intPref", 1.5);
+    ok(false, "Integer value should be rejected");
+  } catch (ex) {
+    ok(true, "Integer value was rejected");
+  }
+});
+
+add_task(async function test_API_through_policies() {
+  // Ensure that the values received by the policies have the correct
+  // type to make sure things are properly working.
+
+  // Implement functions to handle the three simple policies
+  // that will be added to the schema.
+  Policies.bool_policy = {
+    onBeforeUIStartup(manager, param) {
+      setAndLockPref("policies.test2.boolPref", param);
+    }
+  };
+
+  Policies.int_policy = {
+    onBeforeUIStartup(manager, param) {
+      setAndLockPref("policies.test2.intPref", param);
+    }
+  };
+
+  Policies.string_policy = {
+    onBeforeUIStartup(manager, param) {
+      setAndLockPref("policies.test2.stringPref", param);
+    }
+  };
+
+  await setupPolicyEngineWithJson(
+    "config_setAndLockPref.json",
+    /* custom schema */
+    {
+      properties: {
+        "bool_policy": {
+          "type": "boolean"
+        },
+
+        "int_policy": {
+          "type": "integer"
+        },
+
+        "string_policy": {
+          "type": "string"
+        }
+      }
+    }
+  );
+
+  is(Services.policies.status, Ci.nsIEnterprisePolicies.ACTIVE, "Engine is active");
+
+  // The expected values come from config_setAndLockPref.json
+  checkPref("policies.test2.boolPref", true);
+  checkPref("policies.test2.intPref", 42);
+  checkPref("policies.test2.stringPref", "policies test 2");
+
+  delete Policies.bool_policy;
+  delete Policies.int_policy;
+  delete Policies.string_policy;
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/config_setAndLockPref.json
@@ -0,0 +1,7 @@
+{
+  "policies": {
+    "bool_policy": true,
+    "int_policy": 42,
+    "string_policy": "policies test 2"
+  }
+}