1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
8 //dump("-*- PermissionSettings Module: " + s + "\n");
11 const Cu = Components.utils;
12 const Cc = Components.classes;
13 const Ci = Components.interfaces;
15 this.EXPORTED_SYMBOLS = ["PermissionSettingsModule"];
17 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
18 Cu.import("resource://gre/modules/Services.jsm");
19 Cu.import("resource://gre/modules/PermissionsTable.jsm");
21 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
22 "@mozilla.org/parentprocessmessagemanager;1",
23 "nsIMessageListenerManager");
25 XPCOMUtils.defineLazyServiceGetter(this,
27 "@mozilla.org/permissionmanager;1",
28 "nsIPermissionManager");
30 XPCOMUtils.defineLazyServiceGetter(this,
32 "@mozilla.org/scriptsecuritymanager;1",
33 "nsIScriptSecurityManager");
35 XPCOMUtils.defineLazyServiceGetter(this,
37 "@mozilla.org/AppsService;1",
40 this.PermissionSettingsModule = {
41 init: function init() {
43 ppmm.addMessageListener("PermissionSettings:AddPermission", this);
44 Services.obs.addObserver(this, "profile-before-change", false);
48 _isChangeAllowed: function(aPrincipal, aPermName, aAction) {
50 // Change is allowed from a child process when all of the following
51 // conditions stand true:
52 // * the action isn't "unknown" (so the change isn't a delete) if the app
54 // * the permission already exists on the database
55 // * the permission is marked as explicit on the permissions table
56 // Note that we *have* to check the first two conditions here because
57 // permissionManager doesn't know if it's being called as a result of
58 // a parent process or child process request. We could check
59 // if the permission is actually explicit (and thus modifiable) or not
60 // on permissionManager also but we currently don't.
62 permissionManager.testExactPermissionFromPrincipal(aPrincipal,aPermName);
63 let isExplicit = isExplicitInPermissionsTable(aPermName, aPrincipal.appStatus);
65 return (aAction === "unknown" &&
66 aPrincipal.appStatus === Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) ||
67 (aAction !== "unknown" &&
68 (perm !== Ci.nsIPermissionManager.UNKNOWN_ACTION) &&
72 addPermission: function addPermission(aData, aCallbacks) {
74 this._internalAddPermission(aData, true, aCallbacks);
79 _internalAddPermission: function _internalAddPermission(aData, aAllowAllChanges, aCallbacks) {
80 let uri = Services.io.newURI(aData.origin, null, null);
81 let appID = appsService.getAppLocalIdByManifestURL(aData.manifestURL);
82 let principal = secMan.getAppCodebasePrincipal(uri, appID, aData.browserFlag);
88 action = Ci.nsIPermissionManager.UNKNOWN_ACTION;
91 action = Ci.nsIPermissionManager.ALLOW_ACTION;
94 action = Ci.nsIPermissionManager.DENY_ACTION;
97 action = Ci.nsIPermissionManager.PROMPT_ACTION;
100 dump("Unsupported PermisionSettings Action: " + aData.value +"\n");
101 action = Ci.nsIPermissionManager.UNKNOWN_ACTION;
104 if (aAllowAllChanges ||
105 this._isChangeAllowed(principal, aData.type, aData.value)) {
106 debug("add: " + aData.origin + " " + appID + " " + action);
107 permissionManager.addFromPrincipal(principal, aData.type, action);
110 debug("add Failure: " + aData.origin + " " + appID + " " + action);
111 return false; // This isn't currently used, see comment on setPermission
115 getPermission: function getPermission(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
116 debug("getPermission: " + aPermName + ", " + aManifestURL + ", " + aOrigin);
117 let uri = Services.io.newURI(aOrigin, null, null);
118 let appID = appsService.getAppLocalIdByManifestURL(aManifestURL);
119 let principal = secMan.getAppCodebasePrincipal(uri, appID, aBrowserFlag);
120 let result = permissionManager.testExactPermissionFromPrincipal(principal, aPermName);
124 case Ci.nsIPermissionManager.UNKNOWN_ACTION:
126 case Ci.nsIPermissionManager.ALLOW_ACTION:
128 case Ci.nsIPermissionManager.DENY_ACTION:
130 case Ci.nsIPermissionManager.PROMPT_ACTION:
133 dump("Unsupported PermissionSettings Action!\n");
138 removePermission: function removePermission(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
142 manifestURL: aManifestURL,
144 browserFlag: aBrowserFlag
146 this._internalAddPermission(data, true);
149 observe: function observe(aSubject, aTopic, aData) {
150 ppmm.removeMessageListener("PermissionSettings:AddPermission", this);
151 Services.obs.removeObserver(this, "profile-before-change");
155 receiveMessage: function receiveMessage(aMessage) {
156 debug("PermissionSettings::receiveMessage " + aMessage.name);
157 let mm = aMessage.target;
158 let msg = aMessage.data;
161 switch (aMessage.name) {
162 case "PermissionSettings:AddPermission":
165 " from a content process with no 'permissions' privileges.";
166 if (mm.assertPermission("permissions")) {
167 success = this._internalAddPermission(msg, false);
169 // Just kill the calling process
170 mm.assertPermission("permissions-modify-implicit");
171 errorMsg = " had an implicit permission change. Child process killed.";
176 Cu.reportError("PermissionSettings message " + msg.type + errorMsg);
184 PermissionSettingsModule.init();