Bug 793204 - Add remove() API to PermissionSettings. r=sicking
authorReuben Morais <reuben.morais@gmail.com>
Tue, 22 Jan 2013 23:34:26 -0800
changeset 130252 2027e3e07448db149d05dc6777e1b3f2038ec441
parent 130251 333d198ec6bc8c9cc81e79546aab12626838ff45
child 130253 7890512ebda6b036c3271672ada96200c4e9f8ee
push id317
push userbbajaj@mozilla.com
push dateTue, 07 May 2013 01:20:33 +0000
treeherdermozilla-release@159a10910249 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs793204
milestone21.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 793204 - Add remove() API to PermissionSettings. r=sicking
dom/apps/src/PermissionsInstaller.jsm
dom/interfaces/permission/nsIDOMPermissionSettings.idl
dom/permission/PermissionSettings.js
dom/permission/PermissionSettings.jsm
dom/permission/PermissionSettings.manifest
dom/permission/tests/test_permission_basics.html
--- a/dom/apps/src/PermissionsInstaller.jsm
+++ b/dom/apps/src/PermissionsInstaller.jsm
@@ -85,18 +85,20 @@ this.PermissionsInstaller = {
                                                        aApp.manifestURL,
                                                        aApp.origin,
                                                        false);
               if (permValue == "unknown" || permValue == "deny") {
                 // All 'deny' permissions should be preserved
                 continue;
               }
               // Remove the deprecated permission
-              // TODO: use PermSettings.remove, see bug 793204
-              this._setPermission(permName, "unknown", aApp);
+              PermissionSettingsModule.removePermission(permName,
+                                                        aApp.manifestURL,
+                                                        aApp.origin,
+                                                        false);
             }
           }
         }
       }
 
       // Check to see if the 'webapp' is app/privileged/certified.
       let appStatus;
       switch (AppsUtils.getAppManifestStatus(aApp.manifest)) {
--- a/dom/interfaces/permission/nsIDOMPermissionSettings.idl
+++ b/dom/interfaces/permission/nsIDOMPermissionSettings.idl
@@ -1,17 +1,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 
 interface nsIDOMDOMRequest;
 
-[scriptable, uuid(b3e3894e-b24e-4174-9c80-08115709615b)]
+[scriptable, uuid(18390770-02ab-11e2-a21f-0800200c9a66)]
 interface nsIDOMPermissionSettings : nsISupports
 {
   DOMString get(in DOMString permission, in DOMString manifestURI, in DOMString origin, in bool browserFlag);
 
   void set(in DOMString permission, in DOMString value, in DOMString manifestURI, in DOMString origin, in bool browserFlag);
 
   bool isExplicit(in DOMString permission, in DOMString manifestURI, in DOMString origin, in bool browserFlag);
+
+  void remove(in DOMString permission, in DOMString manifestURI, in DOMString origin, in bool browserFlag);
 };
--- a/dom/permission/PermissionSettings.js
+++ b/dom/permission/PermissionSettings.js
@@ -16,17 +16,17 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PermissionsTable.jsm");
 
 var cpm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
 
 // PermissionSettings
 
 const PERMISSIONSETTINGS_CONTRACTID = "@mozilla.org/permissionSettings;1";
-const PERMISSIONSETTINGS_CID        = Components.ID("{18390770-02ab-11e2-a21f-0800200c9a66}");
+const PERMISSIONSETTINGS_CID        = Components.ID("{cd2cf7a1-f4c1-487b-8c1b-1a71c7097431}");
 const nsIDOMPermissionSettings      = Ci.nsIDOMPermissionSettings;
 
 function PermissionSettings()
 {
   debug("Constructor");
 }
 
 XPCOMUtils.defineLazyServiceGetter(this,
@@ -76,23 +76,23 @@ PermissionSettings.prototype = {
     let principal = secMan.getAppCodebasePrincipal(uri, appID, aBrowserFlag);
 
     return isExplicitInPermissionsTable(aPermName, principal.appStatus);
   },
 
   set: function set(aPermName, aPermValue, aManifestURL, aOrigin,
                     aBrowserFlag) {
     debug("Set called with: " + aPermName + ", " + aManifestURL + ", " +
-          aOrigin + ",  " + aPermValue + ", " + aBrowserFlag); 
-    let currentPermValue = this.get(aPermName, aManifestURL, aOrigin, 
+          aOrigin + ",  " + aPermValue + ", " + aBrowserFlag);
+    let currentPermValue = this.get(aPermName, aManifestURL, aOrigin,
                                     aBrowserFlag);
     let action;
     // Check for invalid calls so that we throw an exception rather than get
     // killed by parent process
-    if (currentPermValue === "unknown" || 
+    if (currentPermValue === "unknown" ||
         aPermValue === "unknown" ||
         !this.isExplicit(aPermName, aManifestURL, aOrigin, aBrowserFlag)) {
       let errorMsg = "PermissionSettings.js: '" + aPermName + "'" +
                      " is an implicit permission for '" + aManifestURL +
                      "' or the permission isn't set";
       Cu.reportError(errorMsg);
       throw new Components.Exception(errorMsg);
     }
@@ -101,16 +101,38 @@ PermissionSettings.prototype = {
       type: aPermName,
       origin: aOrigin,
       manifestURL: aManifestURL,
       value: aPermValue,
       browserFlag: aBrowserFlag
     });
   },
 
+  remove: function remove(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
+    let uri = Services.io.newURI(aOrigin, null, null);
+    let appID = appsService.getAppLocalIdByManifestURL(aManifestURL);
+    let principal = secMan.getAppCodebasePrincipal(uri, appID, aBrowserFlag);
+
+    if (principal.appStatus !== Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) {
+      let errorMsg = "PermissionSettings.js: '" + aOrigin + "'" +
+                     " is installed, cannot remove permission '"+aPermName+"'.";
+      Cu.reportError(errorMsg);
+      throw new Components.Exception(errorMsg);
+    }
+
+    // PermissionSettings.jsm handles delete when value is "unknown"
+    cpm.sendSyncMessage("PermissionSettings:AddPermission", {
+      type: aPermName,
+      origin: aOrigin,
+      manifestURL: aManifestURL,
+      value: "unknown",
+      browserFlag: aBrowserFlag
+    });
+  },
+
   init: function init(aWindow) {
     debug("init");
 
     // Set navigator.mozPermissionSettings to null.
     let perm = Services.perms.testExactPermissionFromPrincipal(aWindow.document.nodePrincipal, "permissions");
     if (!Services.prefs.getBoolPref("dom.mozPermissionSettings.enabled")
         || perm != Ci.nsIPermissionManager.ALLOW_ACTION) {
       return null;
--- a/dom/permission/PermissionSettings.jsm
+++ b/dom/permission/PermissionSettings.jsm
@@ -44,29 +44,34 @@ this.PermissionSettingsModule = {
     Services.obs.addObserver(this, "profile-before-change", false);
   },
 
 
   _isChangeAllowed: function(aPrincipal, aPermName, aAction) {
     // Bug 812289:
     // Change is allowed from a child process when all of the following
     // conditions stand true:
-    //   * the action isn't "unknown" (so the change isn't a delete)
+    //   * the action isn't "unknown" (so the change isn't a delete) if the app
+    //     is installed
     //   * the permission already exists on the database
     //   * the permission is marked as explicit on the permissions table
     // Note that we *have* to check the first two conditions ere because
     // permissionManager doesn't know if it's being called as a result of
     // a parent process or child process request. We could check
     // if the permission is actually explicit (and thus modifiable) or not
     // on permissionManager also but we currently don't.
     let perm =
       permissionManager.testExactPermissionFromPrincipal(aPrincipal,aPermName);
     let isExplicit = isExplicitInPermissionsTable(aPermName, aPrincipal.appStatus);
-    
-    return (aAction !== "unknown") &&
+
+    let deleteAllowed = true;
+    if (aAction === "unknown")
+      deleteAllowed = (aPrincipal.appStatus === Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED);
+
+    return deleteAllowed &&
            (perm !== Ci.nsIPermissionManager.UNKNOWN_ACTION) &&
            isExplicit;
   },
 
   addPermission: function addPermission(aData, aCallbacks) {
 
     this._internalAddPermission(aData, true, aCallbacks);
 
@@ -127,36 +132,47 @@ this.PermissionSettingsModule = {
       case Ci.nsIPermissionManager.PROMPT_ACTION:
         return "prompt";
       default:
         dump("Unsupported PermissionSettings Action!\n");
         return "unknown";
     }
   },
 
+  removePermission: function removePermission(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
+    let data = {
+      type: aPermName,
+      origin: aOrigin,
+      manifestURL: aManifestURL,
+      value: "unknown",
+      browserFlag: aBrowserFlag
+    };
+    this._internalAddPermission(data, false);
+  },
+
   observe: function observe(aSubject, aTopic, aData) {
     ppmm.removeMessageListener("PermissionSettings:AddPermission", this);
     Services.obs.removeObserver(this, "profile-before-change");
     ppmm = null;
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     debug("PermissionSettings::receiveMessage " + aMessage.name);
     let mm = aMessage.target;
     let msg = aMessage.data;
 
     let result;
     switch (aMessage.name) {
       case "PermissionSettings:AddPermission":
         let success = false;
-        let errorMsg = 
+        let errorMsg =
               " from a content process with no 'permissions' privileges.";
         if (mm.assertPermission("permissions")) {
           success = this._internalAddPermission(msg, false);
-          if (!success) { 
+          if (!success) {
             // Just kill the calling process
             mm.assertPermission("permissions-modify-implicit");
             errorMsg = " had an implicit permission change. Child process killed.";
           }
         }
 
         if (!success) {
           Cu.reportError("PermissionSettings message " + msg.type + errorMsg);
--- a/dom/permission/PermissionSettings.manifest
+++ b/dom/permission/PermissionSettings.manifest
@@ -1,3 +1,3 @@
-component {18390770-02ab-11e2-a21f-0800200c9a66} PermissionSettings.js
-contract @mozilla.org/permissionSettings;1 {18390770-02ab-11e2-a21f-0800200c9a66}
+component {cd2cf7a1-f4c1-487b-8c1b-1a71c7097431} PermissionSettings.js
+contract @mozilla.org/permissionSettings;1 {cd2cf7a1-f4c1-487b-8c1b-1a71c7097431}
 category JavaScript-navigator-property mozPermissionSettings @mozilla.org/permissionSettings;1
--- a/dom/permission/tests/test_permission_basics.html
+++ b/dom/permission/tests/test_permission_basics.html
@@ -26,17 +26,17 @@ var testPrivApp = {
 };
 
 var testCertApp = {
   'manifestURL' : 'https://acertified.com/manifest.webapp'
 };
 
 SpecialPowers.addPermission("permissions", true, document);
 var comp = SpecialPowers.wrap(Components);
-SpecialPowers.pushPrefEnv({ "set": [["dom.mozPermissionSettings.enabled", true]] }, 
+SpecialPowers.pushPrefEnv({ "set": [["dom.mozPermissionSettings.enabled", true]] },
                           function() {
                             SpecialPowers.removePermission("permissions", document);
                           });
 
 comp.utils.import("resource://gre/modules/PermissionSettings.jsm");
 var mozPermissions = window.navigator.mozPermissionSettings;
 
 function permissionTest() {
@@ -61,17 +61,17 @@ function permissionTest() {
       ok(true, "Change implicit permission");
     }
 
     var result=mozPermissions.get(testPerm, certAppManifest, originCert, false);
     is(result, "allow", "same result");
 
     // Erasing a permission, even an explicit one, is not allowed
     try {
-      mozPermissions.set(testPerm, "unknown", privAppManifest, originPriv, false);
+      mozPermissions.remove(testPerm, privAppManifest, originPriv, false);
       ok(false, "Erase explicit permission");
     } catch (e) {
       ok(true, "Erase explicit permission");
     }
 
     mozPermissions.set(testPerm, "allow", privAppManifest, originPriv, false);
     result = mozPermissions.get(testPerm, privAppManifest, originPriv, false);
     is(result, "allow", "Set to allow");