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/AppsService;1",
30 this.PermissionSettingsModule = {
31 init: function init() {
33 ppmm.addMessageListener("PermissionSettings:AddPermission", this);
34 Services.obs.addObserver(this, "profile-before-change", false);
38 _isChangeAllowed: function(aPrincipal, aPermName, aAction, aAppKind) {
40 // Change is allowed from a child process when all of the following
41 // conditions stand true:
42 // * the action isn't "unknown" (so the change isn't a delete) if the app
44 // * the permission already exists on the database
45 // * the permission is marked as explicit on the permissions table
46 // Note that we *have* to check the first two conditions here because
47 // permissionManager doesn't know if it's being called as a result of
48 // a parent process or child process request. We could check
49 // if the permission is actually explicit (and thus modifiable) or not
50 // on permissionManager also but we currently don't.
52 Services.perms.testExactPermissionFromPrincipal(aPrincipal,aPermName);
53 let isExplicit = isExplicitInPermissionsTable(aPermName, aPrincipal.appStatus, aAppKind);
55 return (aAction === "unknown" &&
56 aPrincipal.appStatus === Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED) ||
57 (aAction !== "unknown" &&
58 (perm !== Ci.nsIPermissionManager.UNKNOWN_ACTION) &&
62 addPermission: function addPermission(aData, aCallbacks) {
64 this._internalAddPermission(aData, true, aCallbacks);
69 _internalAddPermission: function _internalAddPermission(aData, aAllowAllChanges, aCallbacks) {
70 let uri = Services.io.newURI(aData.origin, null, null);
71 let app = appsService.getAppByManifestURL(aData.manifestURL);
72 let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(uri, app.localId, aData.browserFlag);
78 action = Ci.nsIPermissionManager.UNKNOWN_ACTION;
81 action = Ci.nsIPermissionManager.ALLOW_ACTION;
84 action = Ci.nsIPermissionManager.DENY_ACTION;
87 action = Ci.nsIPermissionManager.PROMPT_ACTION;
90 dump("Unsupported PermisionSettings Action: " + aData.value +"\n");
91 action = Ci.nsIPermissionManager.UNKNOWN_ACTION;
94 if (aAllowAllChanges ||
95 this._isChangeAllowed(principal, aData.type, aData.value, app.kind)) {
96 debug("add: " + aData.origin + " " + app.localId + " " + action);
97 Services.perms.addFromPrincipal(principal, aData.type, action);
100 debug("add Failure: " + aData.origin + " " + app.localId + " " + action);
101 return false; // This isn't currently used, see comment on setPermission
105 getPermission: function getPermission(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
106 debug("getPermission: " + aPermName + ", " + aManifestURL + ", " + aOrigin);
107 let uri = Services.io.newURI(aOrigin, null, null);
108 let appID = appsService.getAppLocalIdByManifestURL(aManifestURL);
109 let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(uri, appID, aBrowserFlag);
110 let result = Services.perms.testExactPermissionFromPrincipal(principal, aPermName);
114 case Ci.nsIPermissionManager.UNKNOWN_ACTION:
116 case Ci.nsIPermissionManager.ALLOW_ACTION:
118 case Ci.nsIPermissionManager.DENY_ACTION:
120 case Ci.nsIPermissionManager.PROMPT_ACTION:
123 dump("Unsupported PermissionSettings Action!\n");
128 removePermission: function removePermission(aPermName, aManifestURL, aOrigin, aBrowserFlag) {
132 manifestURL: aManifestURL,
134 browserFlag: aBrowserFlag
136 this._internalAddPermission(data, true);
139 observe: function observe(aSubject, aTopic, aData) {
140 ppmm.removeMessageListener("PermissionSettings:AddPermission", this);
141 Services.obs.removeObserver(this, "profile-before-change");
145 receiveMessage: function receiveMessage(aMessage) {
146 debug("PermissionSettings::receiveMessage " + aMessage.name);
147 let mm = aMessage.target;
148 let msg = aMessage.data;
151 switch (aMessage.name) {
152 case "PermissionSettings:AddPermission":
155 " from a content process with no 'permissions' privileges.";
156 if (mm.assertPermission("permissions")) {
157 success = this._internalAddPermission(msg, false);
159 // Just kill the calling process
160 mm.assertPermission("permissions-modify-implicit");
161 errorMsg = " had an implicit permission change. Child process killed.";
166 Cu.reportError("PermissionSettings message " + msg.type + errorMsg);
174 PermissionSettingsModule.init();