зеркало из https://github.com/mozilla/gecko-dev.git
147 строки
5.4 KiB
JavaScript
147 строки
5.4 KiB
JavaScript
/* 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/. */
|
|
|
|
/* PermissionPromptHelper checks the permissionDB for a given permission
|
|
* name and performs prompting if needed.
|
|
* Usage: send PermissionPromptHelper:AskPermission via the FrameMessageManager with:
|
|
* |origin|, |appID|, |browserFlag| -> used for getting the principal and
|
|
* |type| and |access| to call testExactPermissionFromPrincipal.
|
|
* Note that |access| isn't currently used.
|
|
* Other arugments are:
|
|
* requestID: ID that gets returned with the result message.
|
|
*
|
|
* Once the permission is checked, it returns with the message
|
|
* "PermissionPromptHelper:AskPermission:OK"
|
|
* The result contains the |result| e.g.Ci.nsIPermissionManager.ALLOW_ACTION
|
|
* and a requestID that
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
let DEBUG = 0;
|
|
let debug;
|
|
if (DEBUG)
|
|
debug = function (s) { dump("-*- Permission Prompt Helper component: " + s + "\n"); }
|
|
else
|
|
debug = function (s) {}
|
|
|
|
const Cu = Components.utils;
|
|
const Cc = Components.classes;
|
|
const Ci = Components.interfaces;
|
|
|
|
this.EXPORTED_SYMBOLS = ["PermissionPromptHelper"];
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
|
|
Cu.import("resource://gre/modules/PermissionsTable.jsm");
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|
"@mozilla.org/parentprocessmessagemanager;1",
|
|
"nsIMessageListenerManager");
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "permissionPromptService",
|
|
"@mozilla.org/permission-prompt-service;1",
|
|
"nsIPermissionPromptService");
|
|
|
|
let permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
|
|
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
|
let appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService);
|
|
|
|
this.PermissionPromptHelper = {
|
|
init: function init() {
|
|
debug("Init");
|
|
ppmm.addMessageListener("PermissionPromptHelper:AskPermission", this);
|
|
Services.obs.addObserver(this, "profile-before-change", false);
|
|
},
|
|
|
|
askPermission: function askPermission(aMessage, aCallbacks) {
|
|
let msg = aMessage.json;
|
|
|
|
let access;
|
|
if (PermissionsTable[msg.type].access) {
|
|
access = "readwrite"; // XXXddahl: Not sure if this should be set to READWRITE
|
|
}
|
|
// Expand permission names.
|
|
let expandedPermNames = expandPermissions(msg.type, access);
|
|
let installedPermValues = [];
|
|
let uri = Services.io.newURI(msg.origin, null, null);
|
|
let principal =
|
|
secMan.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag);
|
|
|
|
for (let idx in expandedPermNames) {
|
|
let access = msg.access ? expandedPermNames[idx] : msg.type;
|
|
let permValue =
|
|
permissionManager.testExactPermissionFromPrincipal(principal, access);
|
|
installedPermValues.push(permValue);
|
|
}
|
|
|
|
// TODO: see bug 804623, We are preventing "read" operations
|
|
// even if just "write" has been set to DENY_ACTION
|
|
for (let idx in installedPermValues) {
|
|
// if any of the installedPermValues are deny, run aCallbacks.cancel
|
|
if (installedPermValues[idx] == Ci.nsIPermissionManager.DENY_ACTION ||
|
|
installedPermValues[idx] == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
|
|
aCallbacks.cancel();
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (let idx in installedPermValues) {
|
|
if (installedPermValues[idx] == Ci.nsIPermissionManager.PROMPT_ACTION) {
|
|
// create a nsIContentPermissionRequest
|
|
let request = {
|
|
type: msg.type,
|
|
access: msg.access ? msg.access : "unused",
|
|
principal: principal,
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
|
|
allow: aCallbacks.allow,
|
|
cancel: aCallbacks.cancel,
|
|
window: Services.wm.getMostRecentWindow("navigator:browser")
|
|
};
|
|
|
|
permissionPromptService.getPermission(request);
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (let idx in installedPermValues) {
|
|
if (installedPermValues[idx] == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
|
aCallbacks.allow();
|
|
return;
|
|
}
|
|
}
|
|
},
|
|
|
|
observe: function observe(aSubject, aTopic, aData) {
|
|
ppmm.removeMessageListener("PermissionPromptHelper:AskPermission", this);
|
|
Services.obs.removeObserver(this, "profile-before-change");
|
|
ppmm = null;
|
|
},
|
|
|
|
receiveMessage: function receiveMessage(aMessage) {
|
|
debug("PermissionPromptHelper::receiveMessage " + aMessage.name);
|
|
let mm = aMessage.target;
|
|
let msg = aMessage.data;
|
|
|
|
let result;
|
|
if (aMessage.name == "PermissionPromptHelper:AskPermission") {
|
|
this.askPermission(aMessage, {
|
|
cancel: function() {
|
|
mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK",
|
|
{ result: Ci.nsIPermissionManager.DENY_ACTION,
|
|
requestID: msg.requestID });
|
|
},
|
|
allow: function() {
|
|
mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK",
|
|
{ result: Ci.nsIPermissionManager.ALLOW_ACTION,
|
|
requestID: msg.requestID });
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
PermissionPromptHelper.init();
|