Bug 1406675 - Add new WebExtensions test for cookieBehavior and lifetimePolicy prefs. draft
authorLuca Greco <lgreco@mozilla.com>
Fri, 27 Oct 2017 13:50:40 +0200
changeset 697300 9a91b88fbfee567f442c331ce992e31ba0bd30e0
parent 696263 66e6825f3a06c54e70a5623a7fbd441427e515e7
child 740090 4a83daf0b2153a3f55a9b51f64649f3b400f084e
push id88966
push userluca.greco@alcacoop.it
push dateMon, 13 Nov 2017 21:25:09 +0000
bugs1406675
milestone58.0a1
Bug 1406675 - Add new WebExtensions test for cookieBehavior and lifetimePolicy prefs. MozReview-Commit-ID: 5fgW29K8oEG
toolkit/components/extensions/test/xpcshell/test_ext_cookieBehaviors.js
toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_cookieBehaviors.js
@@ -0,0 +1,204 @@
+"use strict";
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/ExtensionParent.jsm");
+
+const COOKIE_BEHAVIOR_REJECT_FOREIGN = 1;
+const COOKIE_BEHAVIOR_REJECT = 2;
+const COOKIE_BEHAVIOR_LIMIT_FOREIGN = 3;
+
+const server = createHttpServer();
+server.registerDirectory("/data/", do_get_file("data"));
+
+const BASE_URL = `http://localhost:${server.identity.primaryPort}/data`;
+
+async function test_bg_page_allowed_storage() {
+  function background() {
+    try {
+      void indexedDB;
+      void localStorage;
+
+      const worker = new Worker("worker.js");
+      worker.onmessage = (event) => {
+        if (event.data.pass) {
+          browser.test.notifyPass("bg_allowed_storage");
+        } else {
+          browser.test.notifyFail("bg_allowed_storage");
+        }
+      };
+
+      worker.postMessage({});
+    } catch (err) {
+      browser.test.notifyFail("bg_allowed_storage");
+      throw err;
+    }
+  }
+
+  let extension = ExtensionTestUtils.loadExtension({
+    background,
+    files: {
+      "worker.js": function worker() {
+        this.onmessage = () => {
+          try {
+            void indexedDB;
+            postMessage({pass: true});
+          } catch (err) {
+            postMessage({pass: false});
+            throw err;
+          }
+        };
+      },
+    },
+  });
+
+  await extension.startup();
+  await extension.awaitFinish("bg_allowed_storage");
+  await extension.unload();
+}
+
+add_task(async function test_ext_page_allowed_storage_on_cookieBehaviors() {
+  do_print("Test background page indexedDB with COOKIE_BEHAVIOR_LIMIT_FOREIGN");
+  Services.prefs.setIntPref("network.cookie.cookieBehavior", COOKIE_BEHAVIOR_LIMIT_FOREIGN);
+  await test_bg_page_allowed_storage();
+
+  do_print("Test background page indexedDB with COOKIE_BEHAVIOR_REJECT_FOREIGN");
+  Services.prefs.setIntPref("network.cookie.cookieBehavior", COOKIE_BEHAVIOR_REJECT_FOREIGN);
+  await test_bg_page_allowed_storage();
+
+  do_print("Test background page indexedDB with COOKIE_BEHAVIOR_REJECT");
+  Services.prefs.setIntPref("network.cookie.cookieBehavior", COOKIE_BEHAVIOR_REJECT);
+  await test_bg_page_allowed_storage();
+});
+
+add_task(async function test_content_script_on_cookieBehaviorReject() {
+  Services.prefs.setIntPref("network.cookie.cookieBehavior", COOKIE_BEHAVIOR_REJECT);
+
+  function contentScript() {
+    // Ensure that when the current cookieBehavior doesn't allow a webpage to use indexedDB
+    // or localStorage, then a WebExtension content script is not allowed to use it as well.
+    browser.test.assertThrows(
+      () => indexedDB,
+      /The operation is insecure/,
+      "a content script can't use indexedDB from a page where it is disallowed"
+    );
+
+    browser.test.assertThrows(
+      () => localStorage,
+        /The operation is insecure/,
+      "a content script can't use localStorage from a page where it is disallowed"
+    );
+
+    browser.test.notifyPass("cs_disallowed_storage");
+  }
+
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      content_scripts: [{
+        matches: ["http://*/*/file_sample.html"],
+        js: ["content_script.js"],
+      }],
+    },
+    files: {
+      "content_script.js": contentScript,
+    },
+  });
+
+  await extension.startup();
+
+  let contentPage = await ExtensionTestUtils.loadContentPage(`${BASE_URL}/file_sample.html`);
+
+  await extension.awaitFinish("cs_disallowed_storage");
+
+  await contentPage.close();
+  await extension.unload();
+});
+
+add_task(function clear_cookieBehavior_pref() {
+  Services.prefs.clearUserPref("network.cookie.cookieBehavior");
+});
+
+add_task(async function test_localStorage_on_session_lifetimePolicy() {
+  // localStorage in session-only mode.
+  Services.prefs.setIntPref("network.cookie.lifetimePolicy", Ci.nsICookieService.ACCEPT_SESSION);
+
+  function background() {
+    localStorage.setItem("test-key", "test-value");
+
+    browser.test.sendMessage("bg_localStorage_set", {uuid: window.location.hostname});
+  }
+
+  let extension = ExtensionTestUtils.loadExtension({
+    background,
+  });
+
+  await extension.startup();
+  const {uuid} = await extension.awaitMessage("bg_localStorage_set");
+
+  const fakeAddonActor = {addonId: extension.id};
+  const addonBrowser = await ExtensionParent.DebugUtils.getExtensionProcessBrowser(fakeAddonActor);
+  const {isRemoteBrowser} = addonBrowser;
+
+  const {
+    isSessionOnly,
+    domStorageLength,
+    domStorageStoredValue,
+  } = await ContentTask.spawn(addonBrowser, {uuid, isRemoteBrowser}, (params) => {
+    const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+    let windowEnumerator = Services.ww.getWindowEnumerator();
+
+    let bgPageWindow;
+
+    // Search the background page window in the process where the extension is running.
+    while (windowEnumerator.hasMoreElements()) {
+      let win = windowEnumerator.getNext();
+
+      // When running in remote-webextension mode the window enumerator
+      // will only include top level windows related to the extension process
+      // (the background page and the "about:blank" related to the addonBrowser
+      // used to connect to the right process).
+
+      if (!params.isRemoteBrowser) {
+        if (win.location.href !== "chrome://extensions/content/dummy.xul") {
+          // When running in single process mode, all the top level windows
+          // will be enumerated, we ignore any window that is not an
+          // extension windowlessBrowser.
+          continue;
+        } else {
+          // from an extension windowlessBrowser, retrieve the background page window
+          // (which has been loaded inside a XUL browser element).
+          win = win.document.querySelector("browser").contentWindow;
+        }
+      }
+
+      if (win.location.hostname === params.uuid &&
+          win.location.pathname === "/_generated_background_page.html") {
+        // Once we have found the background page window related to the target extension
+        // we can exit the while loop.
+        bgPageWindow = win;
+        break;
+      }
+    }
+
+    if (!bgPageWindow) {
+      throw new Error("Unable to find the extension background page");
+    }
+
+    return {
+      isSessionOnly: bgPageWindow.localStorage.isSessionOnly,
+      domStorageLength: bgPageWindow.localStorage.length,
+      domStorageStoredValue: bgPageWindow.localStorage.getItem("test-key"),
+    };
+  });
+
+  await ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(fakeAddonActor);
+
+  equal(isSessionOnly, false, "the extension localStorage is not set in session-only mode");
+  equal(domStorageLength, 1, "the extension storage contains the expected number of keys");
+  equal(domStorageStoredValue, "test-value", "the extension storage contains the expected data");
+
+  await extension.unload();
+});
+
+add_task(function clear_lifetimePolicy_pref() {
+  Services.prefs.clearUserPref("network.cookie.lifetimePolicy");
+});
--- a/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
@@ -11,16 +11,17 @@ skip-if = os == "android" # Android does
 [test_ext_background_runtime_connect_params.js]
 [test_ext_background_sub_windows.js]
 [test_ext_background_telemetry.js]
 [test_ext_background_window_properties.js]
 skip-if = os == "android"
 [test_ext_browserSettings.js]
 [test_ext_browserSettings_homepage.js]
 skip-if = os == "android"
+[test_ext_cookieBehaviors.js]
 [test_ext_contextual_identities.js]
 skip-if = os == "android" # Containers are not exposed to android.
 [test_ext_debugging_utils.js]
 [test_ext_downloads.js]
 [test_ext_downloads_download.js]
 skip-if = os == "android"
 [test_ext_downloads_misc.js]
 skip-if = os == "android" || (os=='linux' && bits==32) # linux32: bug 1324870