Bug 1318948 - Fix WebExtension cookies API in private browsing draft
authorJesper Kristensen <mail@jesperkristensen.dk>
Sun, 20 Nov 2016 19:43:41 +0100
changeset 442155 0c25c7329106949a068b67c1ac973df6300caf28
parent 441645 b7f895c1dc2e91530240efbf50ac063a0f8a9cb5
child 537712 37f874499f7e564cd37f3c04b11daf702344e9f2
push id36601
push usermail@jesperkristensen.dk
push dateMon, 21 Nov 2016 21:19:50 +0000
bugs1318948
milestone53.0a1
Bug 1318948 - Fix WebExtension cookies API in private browsing MozReview-Commit-ID: 2rkLb5haeKr
toolkit/components/extensions/ext-cookies.js
toolkit/components/extensions/test/mochitest/test_ext_cookies.html
--- a/toolkit/components/extensions/ext-cookies.js
+++ b/toolkit/components/extensions/ext-cookies.js
@@ -223,25 +223,25 @@ function* query(detailsIn, props, contex
 
   // We can use getCookiesFromHost for faster searching.
   let enumerator;
   let uri;
   if ("url" in details) {
     try {
       uri = NetUtil.newURI(details.url).QueryInterface(Ci.nsIURL);
       Services.cookies.usePrivateMode(isPrivate, () => {
-        enumerator = Services.cookies.getCookiesFromHost(uri.host, {userContextId});
+        enumerator = Services.cookies.getCookiesFromHost(uri.host, {userContextId, privateBrowsingId: isPrivate ? 1 : 0});
       });
     } catch (ex) {
       // This often happens for about: URLs
       return;
     }
   } else if ("domain" in details) {
     Services.cookies.usePrivateMode(isPrivate, () => {
-      enumerator = Services.cookies.getCookiesFromHost(details.domain, {userContextId});
+      enumerator = Services.cookies.getCookiesFromHost(details.domain, {userContextId, privateBrowsingId: isPrivate ? 1 : 0});
     });
   } else {
     Services.cookies.usePrivateMode(isPrivate, () => {
       enumerator = Services.cookies.enumerator;
     });
   }
 
   // Based on nsCookieService::GetCookieStringInternal
@@ -387,17 +387,17 @@ extensions.registerSchemaAPI("cookies", 
         if (!checkSetCookiePermissions(extension, uri, cookieAttrs)) {
           return Promise.reject({message: `Permission denied to set cookie ${JSON.stringify(details)}`});
         }
 
         // The permission check may have modified the domain, so use
         // the new value instead.
         Services.cookies.usePrivateMode(isPrivate, () => {
           Services.cookies.add(cookieAttrs.host, path, name, value,
-                               secure, httpOnly, isSession, expiry, {userContextId});
+                               secure, httpOnly, isSession, expiry, {userContextId, privateBrowsingId: isPrivate ? 1 : 0});
         });
 
         return self.cookies.get(details);
       },
 
       remove: function(details) {
         for (let {cookie, isPrivate, storeId} of query(details, ["url", "name", "storeId"], context)) {
           Services.cookies.usePrivateMode(isPrivate, () => {
--- a/toolkit/components/extensions/test/mochitest/test_ext_cookies.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_cookies.html
@@ -18,16 +18,26 @@ add_task(function* test_cookies() {
     function assertExpected(expected, cookie) {
       for (let key of Object.keys(cookie)) {
         browser.test.assertTrue(key in expected, `found property ${key}`);
         browser.test.assertEq(expected[key], cookie[key], `property value for ${key} is correct`);
       }
       browser.test.assertEq(Object.keys(expected).length, Object.keys(cookie).length, "all expected properties found");
     }
 
+    async function getCookie(url, windowId) {
+      let tab = await browser.tabs.create({url: url + "tests/toolkit/components/extensions/test/mochitest/return_headers.sjs", windowId});
+      let cookie = JSON.parse(await browser.tabs.executeScript(tab.id, {code: "document.body.textContent"})).cookie;
+      await browser.tabs.remove(tab.id);
+      return cookie;
+    }
+
+    let defaultWindowId = (await browser.windows.getCurrent()).id;
+    browser.test.assertTrue(defaultWindowId != null);
+
     const TEST_URL = "http://example.org/";
     const TEST_SECURE_URL = "https://example.org/";
     const THE_FUTURE = Date.now() + 5 * 60;
     const TEST_PATH = "set_path";
     const TEST_URL_WITH_PATH = TEST_URL + TEST_PATH;
     const TEST_COOKIE_PATH = `/${TEST_PATH}`;
     const STORE_ID = "firefox-default";
     const PRIVATE_STORE_ID = "firefox-private";
@@ -43,16 +53,22 @@ add_task(function* test_cookies() {
       session: false,
       expirationDate: THE_FUTURE,
       storeId: STORE_ID,
     };
 
     let cookie = await browser.cookies.set({url: TEST_URL, name: "name1", value: "value1", expirationDate: THE_FUTURE});
     assertExpected(expected, cookie);
 
+    browser.test.assertEq("name1=value1", await getCookie(TEST_URL, defaultWindowId), "http website can see the cookie");
+
+    browser.test.assertEq("name1=value1", await getCookie(TEST_SECURE_URL, defaultWindowId), "https website can see the cookie");
+
+    browser.test.assertEq(undefined, await getCookie("http://test1.example.org/", defaultWindowId), "subdomain website can not see the cookie");
+
     cookie = await browser.cookies.get({url: TEST_URL, name: "name1"});
     assertExpected(expected, cookie);
 
     let cookies = await browser.cookies.getAll({name: "name1"});
     browser.test.assertEq(cookies.length, 1, "one cookie found for matching name");
     assertExpected(expected, cookies[0]);
 
     cookies = await browser.cookies.getAll({domain: "example.org"});
@@ -74,16 +90,20 @@ add_task(function* test_cookies() {
     assertExpected(expected, cookies[0]);
 
     cookies = await browser.cookies.getAll({storeId: "invalid_id"});
     browser.test.assertEq(cookies.length, 0, "no cookies found for invalid storeId");
 
     let details = await browser.cookies.remove({url: TEST_URL, name: "name1"});
     assertExpected({url: TEST_URL, name: "name1", storeId: STORE_ID}, details);
 
+    browser.test.assertEq(undefined, await getCookie(TEST_URL, defaultWindowId), "website can not see deleted cookie");
+
+    browser.test.assertEq(undefined, await getCookie(TEST_SECURE_URL, defaultWindowId), "website can not see deleted cookie");
+
     cookie = await browser.cookies.get({url: TEST_URL, name: "name1"});
     browser.test.assertEq(null, cookie, "removed cookie not found");
 
     let stores = await browser.cookies.getAllCookieStores();
     browser.test.assertEq(1, stores.length, "expected number of stores returned");
     browser.test.assertEq(STORE_ID, stores[0].id, "expected store id returned");
     browser.test.assertEq(1, stores[0].tabIds.length, "one tab returned for store");
 
@@ -193,16 +213,22 @@ add_task(function* test_cookies() {
       cookie = await browser.cookies.get({url: TEST_URL, name: "store", storeId: PRIVATE_STORE_ID});
       browser.test.assertEq("private", cookie.value, "get the private cookie");
       browser.test.assertEq(PRIVATE_STORE_ID, cookie.storeId, "get the private cookie storeId");
 
       cookie = await browser.cookies.get({url: TEST_URL, name: "store", storeId: STORE_ID});
       browser.test.assertEq("default", cookie.value, "get the default cookie");
       browser.test.assertEq(STORE_ID, cookie.storeId, "get the default cookie storeId");
 
+      browser.test.assertEq("store=private", await getCookie(TEST_URL, privateWindow.id), "http website can see the cookie");
+
+      browser.test.assertEq("store=private", await getCookie(TEST_SECURE_URL, privateWindow.id), "https website can see the cookie");
+
+      browser.test.assertEq(undefined, await getCookie("http://test1.example.org/", privateWindow.id), "subdomain website can not see the cookie");
+
       let details = await browser.cookies.remove({url: TEST_URL, name: "store", storeId: STORE_ID});
       assertExpected({url: TEST_URL, name: "store", storeId: STORE_ID}, details);
 
       cookie = await browser.cookies.get({url: TEST_URL, name: "store", storeId: STORE_ID});
       browser.test.assertEq(null, cookie, "deleted the default cookie");
 
       details = await browser.cookies.remove({url: TEST_URL, name: "store", storeId: PRIVATE_STORE_ID});
       assertExpected({url: TEST_URL, name: "store", storeId: PRIVATE_STORE_ID}, details);
@@ -214,17 +240,17 @@ add_task(function* test_cookies() {
     }
 
     browser.test.notifyPass("cookies");
   }
 
   let extension = ExtensionTestUtils.loadExtension({
     background,
     manifest: {
-      permissions: ["cookies", "*://example.org/"],
+      permissions: ["cookies", "*://*.example.org/"],
     },
   });
 
   yield extension.startup();
   yield extension.awaitFinish("cookies");
   yield extension.unload();
 });