Bug 1502238 - When clearing site data, clear storage permissions assigned to a tracker, r=ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Sat, 27 Oct 2018 08:55:07 +0200
changeset 443244 e9f2f0ad93b3b16fd9e4bc9ed6c1c4596886615d
parent 443243 da8a1b9096cb5bc4df19aa005e21d5c92315c19a
child 443245 ab03a5f493975fe3403bbcdbcab4d1075f1a9a42
push id34945
push userncsoregi@mozilla.com
push dateSat, 27 Oct 2018 09:51:30 +0000
treeherdermozilla-central@7007206a3cd4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1502238
milestone65.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 1502238 - When clearing site data, clear storage permissions assigned to a tracker, r=ehsan
netwerk/base/nsIPermissionManager.idl
toolkit/components/cleardata/ClearDataService.js
toolkit/components/cleardata/tests/unit/test_permissions.js
toolkit/components/cleardata/tests/unit/xpcshell.ini
--- a/netwerk/base/nsIPermissionManager.idl
+++ b/netwerk/base/nsIPermissionManager.idl
@@ -127,17 +127,17 @@ interface nsIPermissionManager : nsISupp
 
   /**
    * Add permission information for a given principal.
    * It is internally calling the other add() method using the nsIURI from the
    * principal.
    * Passing a system principal will be a no-op because they will always be
    * granted permissions.
    */
-  void addFromPrincipal(in nsIPrincipal principal, in string typed,
+  void addFromPrincipal(in nsIPrincipal principal, in string type,
                         in uint32_t permission,
                         [optional] in uint32_t expireType,
                         [optional] in int64_t expireTime);
 
   /**
    * Remove permission information for a given URI and permission type. This will
    * remove the permission for the entire host described by the uri, acting as the
    * opposite operation to the add() method.
--- a/toolkit/components/cleardata/ClearDataService.js
+++ b/toolkit/components/cleardata/ClearDataService.js
@@ -509,20 +509,47 @@ const AuthCacheCleaner = {
     });
   },
 };
 
 const PermissionsCleaner = {
   deleteByHost(aHost, aOriginAttributes) {
     return new Promise(aResolve => {
       for (let perm of Services.perms.enumerator) {
+        let toBeRemoved;
         try {
-          if (eTLDService.hasRootDomain(perm.principal.URI.host, aHost)) {
-            Services.perms.removePermission(perm);
+          toBeRemoved = eTLDService.hasRootDomain(perm.principal.URI.host,
+                                                  aHost);
+        } catch (ex) {
+          continue;
+        }
+
+        if (!toBeRemoved && perm.type.startsWith("3rdPartyStorage^")) {
+          let parts = perm.type.split("^");
+          for (let i = 1; i < parts.length; ++i) {
+            let uri;
+            try {
+              uri = Services.io.newURI(parts[i]);
+            } catch (ex) {
+              continue;
+            }
+
+            toBeRemoved = eTLDService.hasRootDomain(uri.host, aHost);
+            if (toBeRemoved) {
+              break;
+            }
           }
+        }
+
+        if (!toBeRemoved) {
+          continue;
+        }
+
+        try {
+          Services.perms.removePermission(perm);
         } catch (ex) {
           // Ignore entry
         }
       }
 
       aResolve();
     });
   },
new file mode 100644
--- /dev/null
+++ b/toolkit/components/cleardata/tests/unit/test_permissions.js
@@ -0,0 +1,98 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests for permissions
+ */
+
+"use strict";
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+add_task(async function test_all_permissions() {
+  const uri = Services.io.newURI("https://example.net");
+  const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
+
+  Services.perms.addFromPrincipal(principal, "cookie", Services.perms.ALLOW_ACTION);
+  Assert.ok(Services.perms.getPermissionObject(principal, "cookie", true) != null);
+
+  await new Promise(aResolve => {
+    Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
+      Assert.equal(value, 0);
+      aResolve();
+    });
+  });
+
+  Assert.ok(Services.perms.getPermissionObject(principal, "cookie", true) == null);
+});
+
+add_task(async function test_principal_permissions() {
+  const uri = Services.io.newURI("https://example.net");
+  const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
+
+  const anotherUri = Services.io.newURI("https://example.com");
+  const anotherPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(anotherUri, {});
+
+  Services.perms.addFromPrincipal(principal, "cookie", Services.perms.ALLOW_ACTION);
+  Services.perms.addFromPrincipal(anotherPrincipal, "cookie", Services.perms.ALLOW_ACTION);
+  Assert.ok(Services.perms.getPermissionObject(principal, "cookie", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(anotherPrincipal, "cookie", true) != null);
+
+  await new Promise(aResolve => {
+    Services.clearData.deleteDataFromPrincipal(principal, true /* user request */,
+                                               Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
+      Assert.equal(value, 0);
+      aResolve();
+    });
+  });
+
+  Assert.ok(Services.perms.getPermissionObject(principal, "cookie", true) == null);
+  Assert.ok(Services.perms.getPermissionObject(anotherPrincipal, "cookie", true) != null);
+
+  await new Promise(aResolve => {
+    Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => aResolve());
+  });
+});
+
+add_task(async function test_3rdpartystorage_permissions() {
+  const uri = Services.io.newURI("https://example.net");
+  const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
+  Services.perms.addFromPrincipal(principal, "cookie", Services.perms.ALLOW_ACTION);
+
+  const anotherUri = Services.io.newURI("https://example.com");
+  const anotherPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(anotherUri, {});
+  Services.perms.addFromPrincipal(anotherPrincipal, "cookie", Services.perms.ALLOW_ACTION);
+  Services.perms.addFromPrincipal(anotherPrincipal, "3rdPartyStorage^https://example.net", Services.perms.ALLOW_ACTION);
+
+  const oneMoreUri = Services.io.newURI("https://example.org");
+  const oneMorePrincipal = Services.scriptSecurityManager.createCodebasePrincipal(oneMoreUri, {});
+  Services.perms.addFromPrincipal(oneMorePrincipal, "cookie", Services.perms.ALLOW_ACTION);
+  Services.perms.addFromPrincipal(oneMorePrincipal, "3rdPartyStorage^https://example.net^https://example.org", Services.perms.ALLOW_ACTION);
+  Services.perms.addFromPrincipal(oneMorePrincipal, "3rdPartyStorage^https://example.org^https://example.net", Services.perms.ALLOW_ACTION);
+
+  Assert.ok(Services.perms.getPermissionObject(principal, "cookie", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(anotherPrincipal, "cookie", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(anotherPrincipal, "3rdPartyStorage^https://example.net", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(oneMorePrincipal, "cookie", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(oneMorePrincipal, "3rdPartyStorage^https://example.net^https://example.org", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(oneMorePrincipal, "3rdPartyStorage^https://example.org^https://example.net", true) != null);
+
+  await new Promise(aResolve => {
+    Services.clearData.deleteDataFromPrincipal(principal, true /* user request */,
+                                               Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
+      Assert.equal(value, 0);
+      aResolve();
+    });
+  });
+
+  Assert.ok(Services.perms.getPermissionObject(principal, "cookie", true) == null);
+  Assert.ok(Services.perms.getPermissionObject(anotherPrincipal, "cookie", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(anotherPrincipal, "3rdPartyStorage^https://example.net", true) == null);
+  Assert.ok(Services.perms.getPermissionObject(oneMorePrincipal, "cookie", true) != null);
+  Assert.ok(Services.perms.getPermissionObject(oneMorePrincipal, "3rdPartyStorage^https://example.net^https://example.org", true) == null);
+  Assert.ok(Services.perms.getPermissionObject(oneMorePrincipal, "3rdPartyStorage^https://example.org^https://example.net", true) == null);
+
+  await new Promise(aResolve => {
+    Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => aResolve());
+  });
+});
--- a/toolkit/components/cleardata/tests/unit/xpcshell.ini
+++ b/toolkit/components/cleardata/tests/unit/xpcshell.ini
@@ -2,8 +2,9 @@
 head = head.js
 skip-if = toolkit == 'android'
 support-files =
 
 [test_basic.js]
 [test_cookies.js]
 [test_downloads.js]
 [test_passwords.js]
+[test_permissions.js]