Bug 1395659 - Rejecting contextual identity APIs when containers are disabled. r=kmag
authorJonathan Kingston <jkt@mozilla.com>
Thu, 31 Aug 2017 11:46:31 -0700
changeset 429333 cc8544557f9f5ebd1964a9cbf5f20b4ff7f3fb4d
parent 429332 5093b6067a2014ffadef2b3f70fdd3c7d71e6b1a
child 429334 728c1c579a4c6bc7e83f593618e4d16472207cf4
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1395659
milestone57.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 1395659 - Rejecting contextual identity APIs when containers are disabled. r=kmag MozReview-Commit-ID: LCiI74SN12y
toolkit/components/extensions/ext-contextualIdentities.js
toolkit/components/extensions/test/xpcshell/test_ext_contextual_identities.js
--- a/toolkit/components/extensions/ext-contextualIdentities.js
+++ b/toolkit/components/extensions/ext-contextualIdentities.js
@@ -71,16 +71,22 @@ const convertIdentity = identity => {
     color: identity.color,
     colorCode: getContainerColor(identity.color),
     cookieStoreId: getCookieStoreIdForContainer(identity.userContextId),
   };
 
   return result;
 };
 
+const checkAPIEnabled = () => {
+  if (!containersEnabled) {
+    throw new ExtensionError("Contextual identities are currently disabled");
+  }
+};
+
 const convertIdentityFromObserver = wrappedIdentity => {
   let identity = wrappedIdentity.wrappedJSObject;
   let iconUrl, colorCode;
   try {
     iconUrl = getContainerIcon(identity.icon);
     colorCode = getContainerColor(identity.color);
   } catch (e) {
     return null;
@@ -122,28 +128,28 @@ this.contextualIdentities = class extend
       ExtensionPreferencesManager.setSetting(extension, CONTAINERS_ENABLED_SETTING_NAME, true);
     }
   }
 
   getAPI(context) {
     let self = {
       contextualIdentities: {
         async get(cookieStoreId) {
+          checkAPIEnabled();
           let containerId = getContainerForCookieStoreId(cookieStoreId);
           if (!containerId) {
-            return Promise.reject({
-              message: `Invalid contextual identitiy: ${cookieStoreId}`,
-            });
+            throw new ExtensionError(`Invalid contextual identitiy: ${cookieStoreId}`);
           }
 
           let identity = ContextualIdentityService.getPublicIdentityFromId(containerId);
           return convertIdentity(identity);
         },
 
         async query(details) {
+          checkAPIEnabled();
           let identities = [];
           ContextualIdentityService.getPublicIdentities().forEach(identity => {
             if (details.name &&
                 ContextualIdentityService.getUserContextLabel(identity.userContextId) != details.name) {
               return;
             }
 
             identities.push(convertIdentity(identity));
@@ -158,29 +164,26 @@ this.contextualIdentities = class extend
           getContainerColor(details.color);
 
           let identity = ContextualIdentityService.create(details.name,
                                                           details.icon,
                                                           details.color);
           return convertIdentity(identity);
         },
 
-        update(cookieStoreId, details) {
+        async update(cookieStoreId, details) {
+          checkAPIEnabled();
           let containerId = getContainerForCookieStoreId(cookieStoreId);
           if (!containerId) {
-            return Promise.reject({
-              message: `Invalid contextual identitiy: ${cookieStoreId}`,
-            });
+            throw new ExtensionError(`Invalid contextual identitiy: ${cookieStoreId}`);
           }
 
           let identity = ContextualIdentityService.getPublicIdentityFromId(containerId);
           if (!identity) {
-            return Promise.reject({
-              message: `Invalid contextual identitiy: ${cookieStoreId}`,
-            });
+            throw new ExtensionError(`Invalid contextual identitiy: ${cookieStoreId}`);
           }
 
           if (details.name !== null) {
             identity.name = details.name;
           }
 
           if (details.color !== null) {
             identity.color = details.color;
@@ -188,46 +191,39 @@ this.contextualIdentities = class extend
 
           if (details.icon !== null) {
             identity.icon = details.icon;
           }
 
           if (!ContextualIdentityService.update(identity.userContextId,
                                                 identity.name, identity.icon,
                                                 identity.color)) {
-            return Promise.reject({
-              message: `Contextual identitiy failed to update: ${cookieStoreId}`,
-            });
+            throw new ExtensionError(`Contextual identitiy failed to update: ${cookieStoreId}`);
           }
 
           return convertIdentity(identity);
         },
 
         async remove(cookieStoreId) {
+          checkAPIEnabled();
           let containerId = getContainerForCookieStoreId(cookieStoreId);
           if (!containerId) {
-            return Promise.reject({
-              message: `Invalid contextual identitiy: ${cookieStoreId}`,
-            });
+            throw new ExtensionError(`Invalid contextual identitiy: ${cookieStoreId}`);
           }
 
           let identity = ContextualIdentityService.getPublicIdentityFromId(containerId);
           if (!identity) {
-            return Promise.reject({
-              message: `Invalid contextual identitiy: ${cookieStoreId}`,
-            });
+            throw new ExtensionError(`Invalid contextual identitiy: ${cookieStoreId}`);
           }
 
           // We have to create the identity object before removing it.
           let convertedIdentity = convertIdentity(identity);
 
           if (!ContextualIdentityService.remove(identity.userContextId)) {
-            return Promise.reject({
-              message: `Contextual identitiy failed to remove: ${cookieStoreId}`,
-            });
+            throw new ExtensionError(`Contextual identitiy failed to remove: ${cookieStoreId}`);
           }
 
           return convertedIdentity;
         },
 
         onCreated: new EventManager(context, "contextualIdentities.onCreated", fire => {
           let observer = (subject, topic) => {
             let convertedIdentity = convertIdentityFromObserver(subject);
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contextual_identities.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contextual_identities.js
@@ -134,16 +134,40 @@ add_task(async function test_contextualI
     ci = await browser.contextualIdentities.get("firefox-container-1");
     browser.test.assertTrue(!!ci, "We have an identity");
     browser.test.assertTrue("name" in ci, "We have an identity.name");
     browser.test.assertTrue("color" in ci, "We have an identity.color");
     browser.test.assertTrue("icon" in ci, "We have an identity.icon");
     browser.test.assertEq("Personal", ci.name, "identity.name is correct");
     browser.test.assertEq("firefox-container-1", ci.cookieStoreId, "identity.cookieStoreId is correct");
 
+    function listenForMessage(messageName, stateChangeBool) {
+      return new Promise((resolve) => {
+        browser.test.onMessage.addListener(function listener(msg) {
+          browser.test.log(`Got message from background: ${msg}`);
+          if (msg === messageName + "-response") {
+            browser.test.onMessage.removeListener(listener);
+            resolve();
+          }
+        });
+        browser.test.log(`Sending message to background: ${messageName} ${stateChangeBool}`);
+        browser.test.sendMessage(messageName, stateChangeBool);
+      });
+    }
+
+    await listenForMessage("containers-state-change", false);
+
+    browser.test.assertRejects(
+      browser.contextualIdentities.query({}),
+      "Contextual identities are currently disabled",
+      "Throws when containers are disabled"
+    );
+
+    await listenForMessage("containers-state-change", true);
+
     let cis = await browser.contextualIdentities.query({});
     browser.test.assertEq(4, cis.length, "by default we should have 4 containers");
 
     cis = await browser.contextualIdentities.query({name: "Personal"});
     browser.test.assertEq(1, cis.length, "by default we should have 1 container called Personal");
 
     cis = await browser.contextualIdentities.query({name: "foobar"});
     browser.test.assertEq(0, cis.length, "by default we should have 0 container called foobar");
@@ -197,30 +221,39 @@ add_task(async function test_contextualI
     browser.test.assertEq("blue", ci.color, "identity.color is correct");
     browser.test.assertEq("cart", ci.icon, "identity.icon is correct");
 
     cis = await browser.contextualIdentities.query({});
     browser.test.assertEq(4, cis.length, "we are back to 4 identities");
 
     browser.test.notifyPass("contextualIdentities");
   }
+
   function makeExtension(id) {
     return ExtensionTestUtils.loadExtension({
       useAddonManager: "temporary",
       background,
       manifest: {
         applications: {
           gecko: {id},
         },
         permissions: ["contextualIdentities"],
       },
     });
   }
 
   let extension = makeExtension("containers-test@mozilla.org");
+
+  extension.onMessage("containers-state-change", (stateBool) => {
+    Components.utils.reportError(`Got message "containers-state-change", ${stateBool}`);
+    Services.prefs.setBoolPref(CONTAINERS_PREF, stateBool);
+    Components.utils.reportError("Changed pref");
+    extension.sendMessage("containers-state-change-response");
+  });
+
   await extension.startup();
   await extension.awaitFinish("contextualIdentities");
   equal(Services.prefs.getBoolPref(CONTAINERS_PREF), true, "Pref should now be enabled, whatever it's initial state");
   const prefChange = waitForPrefChange(CONTAINERS_PREF);
   await extension.unload();
   if (initial === false) {
     await prefChange;
   }