Bug 1429122 - Policy: Override or disable post-update (what's new) page. r=mhowell draft
authorFelipe Gomes <felipc@gmail.com>
Tue, 03 Apr 2018 12:48:34 -0300
changeset 776694 c08b17a58360df27c298c90cbda0b4dcc7943fe9
parent 775467 7329dd6d372ab3472f5b746f49f88d6d845214b3
push id104956
push userfelipc@gmail.com
push dateTue, 03 Apr 2018 15:49:01 +0000
reviewersmhowell
bugs1429122
milestone61.0a1
Bug 1429122 - Policy: Override or disable post-update (what's new) page. r=mhowell MozReview-Commit-ID: LcSLXZrN8ur
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_override_postupdatepage.js
browser/components/nsBrowserContentHandler.js
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -416,16 +416,27 @@ var Policies = {
 
   "OverrideFirstRunPage": {
     onProfileAfterChange(manager, param) {
       let url = param ? param.spec : "";
       setAndLockPref("startup.homepage_welcome_url", url);
     }
   },
 
+  "OverridePostUpdatePage": {
+    onProfileAfterChange(manager, param) {
+      let url = param ? param.spec : "";
+      setAndLockPref("startup.homepage_override_url", url);
+      // The pref startup.homepage_override_url is only used
+      // as a fallback when the update.xml file hasn't provided
+      // a specific post-update URL.
+      manager.disallowFeature("postUpdateCustomPage");
+    }
+  },
+
   "Popups": {
     onBeforeUIStartup(manager, param) {
       addAllowDenyPermissions("popup", param.Allow, null);
     }
   },
 
   "Proxy": {
     onBeforeAddons(manager, param) {
--- a/browser/components/enterprisepolicies/schemas/policies-schema.json
+++ b/browser/components/enterprisepolicies/schemas/policies-schema.json
@@ -328,16 +328,24 @@
     "OverrideFirstRunPage": {
       "description": "Override the first run page. Set this policy to blank if you want to disable the first run page.",
       "first_available": "60.0",
       "enterprise_only": true,
 
       "type": "URLorEmpty"
     },
 
+    "OverridePostUpdatePage": {
+      "description": "Override the post-update \"What's New\" page. Set this policy to blank if you want to disable the post-update page.",
+      "first_available": "60.0",
+      "enterprise_only": true,
+
+      "type": "URLorEmpty"
+    },
+
     "Popups": {
       "description": "Allow or deny popup usage.",
       "first_available": "60.0",
 
       "type": "object",
       "properties": {
         "Allow": {
           "type": "array",
--- a/browser/components/enterprisepolicies/tests/browser/browser.ini
+++ b/browser/components/enterprisepolicies/tests/browser/browser.ini
@@ -38,13 +38,14 @@ support-files =
 [browser_policy_disable_popup_blocker.js]
 [browser_policy_disable_privatebrowsing.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_override_postupdatepage.js]
 [browser_policy_proxy.js]
 [browser_policy_search_engine.js]
 [browser_policy_searchbar.js]
 [browser_policy_set_homepage.js]
 [browser_policy_websitefilter.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policy_override_postupdatepage.js
@@ -0,0 +1,99 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test was based on the test browser_bug538331.js
+
+const UPDATE_PROVIDED_PAGE = "https://default.example.com/";
+const POLICY_PROVIDED_PAGE = "https://policy.example.com/";
+
+const PREF_MSTONE = "browser.startup.homepage_override.mstone";
+const PREF_POSTUPDATE = "app.update.postupdate";
+
+/*
+ * The important parts for this test are:
+ *  - actions="showURL"
+ *  - openURL="${UPDATE_PROVIDED_PAGE}"
+ */
+const XML_UPDATE = `<?xml version="1.0"?>
+<updates xmlns="http://www.mozilla.org/2005/app-update">
+  <update appVersion="1.0" buildID="20080811053724" channel="nightly"
+          displayVersion="Version 1.0" installDate="1238441400314"
+          isCompleteUpdate="true" name="Update Test 1.0" type="minor"
+          detailsURL="http://example.com/" previousAppVersion="1.0"
+          serviceURL="https://example.com/" statusText="The Update was successfully installed"
+          foregroundDownload="true"
+          actions="showURL"
+          openURL="${UPDATE_PROVIDED_PAGE}">
+    <patch type="complete" URL="http://example.com/" size="775" selected="true" state="succeeded"/>
+  </update>
+</updates>`;
+
+const XML_EMPTY = `<?xml version="1.0"?>
+<updates xmlns="http://www.mozilla.org/2005/app-update">
+</updates>`;
+
+let gOriginalMStone = null;
+
+add_task(async function test_override_postupdate_page() {
+  // Remember this to clean-up afterwards
+  if (Services.prefs.prefHasUserValue(PREF_MSTONE)) {
+    gOriginalMStone = Services.prefs.getCharPref(PREF_MSTONE);
+  }
+  Services.prefs.setBoolPref(PREF_POSTUPDATE, true);
+
+  writeUpdatesToXMLFile(XML_UPDATE);
+  reloadUpdateManagerData();
+
+  is(getPostUpdatePage(), UPDATE_PROVIDED_PAGE, "Post-update page was provided by update.xml.");
+
+  // Now perform the same action but set the policy to override this page
+  await setupPolicyEngineWithJson({
+    "policies": {
+      "OverridePostUpdatePage": POLICY_PROVIDED_PAGE
+    }
+  });
+
+  is(getPostUpdatePage(), POLICY_PROVIDED_PAGE, "Post-update page was provided by policy.");
+
+  // Clean-up
+  writeUpdatesToXMLFile(XML_EMPTY);
+  if (gOriginalMStone) {
+    Services.prefs.setCharPref(PREF_MSTONE, gOriginalMStone);
+  }
+  Services.prefs.clearUserPref(PREF_POSTUPDATE);
+  reloadUpdateManagerData();
+});
+
+
+function getPostUpdatePage() {
+  Services.prefs.setCharPref(PREF_MSTONE, "PreviousMilestone");
+  return Cc["@mozilla.org/browser/clh;1"]
+           .getService(Ci.nsIBrowserHandler)
+           .defaultArgs;
+}
+
+function reloadUpdateManagerData() {
+  // Reloads the update metadata from disk
+  Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager).
+  QueryInterface(Ci.nsIObserver).observe(null, "um-reload-update-data", "");
+}
+
+
+function writeUpdatesToXMLFile(aText) {
+  const PERMS_FILE = 0o644;
+
+  const MODE_WRONLY   = 0x02;
+  const MODE_CREATE   = 0x08;
+  const MODE_TRUNCATE = 0x20;
+
+  let file = Services.dirsvc.get("UpdRootD", Ci.nsIFile);
+  file.append("updates.xml");
+  let fos = Cc["@mozilla.org/network/file-output-stream;1"].
+            createInstance(Ci.nsIFileOutputStream);
+  if (!file.exists()) {
+    file.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
+  }
+  fos.init(file, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, PERMS_FILE, 0);
+  fos.write(aText, aText.length);
+  fos.close();
+}
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -165,16 +165,23 @@ function getPostUpdateOverridePage(defau
   if (!actions)
     return defaultOverridePage;
 
   // The existence of silent or the non-existence of showURL in the actions both
   // mean that an override page should not be displayed.
   if (actions.includes("silent") || !actions.includes("showURL"))
     return "";
 
+  // If a policy was set to not allow the update.xml-provided
+  // URL to be used, use the default fallback (which will also
+  // be provided by the policy).
+  if (!Services.policies.isAllowed("postUpdateCustomPage")) {
+    return defaultOverridePage;
+  }
+
   return update.getProperty("openURL") || defaultOverridePage;
 }
 
 /**
  * Open a browser window. If this is the initial launch, this function will
  * attempt to use the navigator:blank window opened by nsBrowserGlue.js during
  * early startup.
  *