michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* PermissionPromptHelper checks the permissionDB for a given permission michael@0: * name and performs prompting if needed. michael@0: * Usage: send PermissionPromptHelper:AskPermission via the FrameMessageManager with: michael@0: * |origin|, |appID|, |browserFlag| -> used for getting the principal and michael@0: * |type| and |access| to call testExactPermissionFromPrincipal. michael@0: * Note that |access| isn't currently used. michael@0: * Other arugments are: michael@0: * requestID: ID that gets returned with the result message. michael@0: * michael@0: * Once the permission is checked, it returns with the message michael@0: * "PermissionPromptHelper:AskPermission:OK" michael@0: * The result contains the |result| e.g.Ci.nsIPermissionManager.ALLOW_ACTION michael@0: * and a requestID that michael@0: */ michael@0: michael@0: "use strict"; michael@0: michael@0: let DEBUG = 0; michael@0: let debug; michael@0: if (DEBUG) michael@0: debug = function (s) { dump("-*- Permission Prompt Helper component: " + s + "\n"); } michael@0: else michael@0: debug = function (s) {} michael@0: michael@0: const Cu = Components.utils; michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: michael@0: this.EXPORTED_SYMBOLS = ["PermissionPromptHelper"]; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyServiceGetter(this, "ppmm", michael@0: "@mozilla.org/parentprocessmessagemanager;1", michael@0: "nsIMessageListenerManager"); michael@0: michael@0: XPCOMUtils.defineLazyServiceGetter(this, "permissionPromptService", michael@0: "@mozilla.org/permission-prompt-service;1", michael@0: "nsIPermissionPromptService"); michael@0: michael@0: let appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService); michael@0: michael@0: this.PermissionPromptHelper = { michael@0: init: function init() { michael@0: debug("Init"); michael@0: ppmm.addMessageListener("PermissionPromptHelper:AskPermission", this); michael@0: Services.obs.addObserver(this, "profile-before-change", false); michael@0: }, michael@0: michael@0: askPermission: function askPermission(aMessage, aCallbacks) { michael@0: let msg = aMessage.json; michael@0: michael@0: let access = msg.type; michael@0: if (msg.access) { michael@0: access = access + "-" + msg.access; michael@0: } michael@0: michael@0: let uri = Services.io.newURI(msg.origin, null, null); michael@0: let principal = michael@0: Services.scriptSecurityManager.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag); michael@0: michael@0: let permValue = michael@0: Services.perms.testExactPermissionFromPrincipal(principal, access); michael@0: michael@0: if (permValue == Ci.nsIPermissionManager.DENY_ACTION || michael@0: permValue == Ci.nsIPermissionManager.UNKNOWN_ACTION) { michael@0: aCallbacks.cancel(); michael@0: return; michael@0: } michael@0: michael@0: if (permValue == Ci.nsIPermissionManager.PROMPT_ACTION) { michael@0: michael@0: // create the options from permission request. michael@0: let options = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); michael@0: if (msg.options) { michael@0: for (let option of options) { michael@0: options.appendElement(option); michael@0: } michael@0: } michael@0: michael@0: // create an array with a nsIContentPermissionType element michael@0: let type = { michael@0: type: msg.type, michael@0: access: msg.access ? msg.access : "unused", michael@0: options: options, michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType]) michael@0: }; michael@0: let typeArray = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); michael@0: typeArray.appendElement(type, false); michael@0: michael@0: // create a nsIContentPermissionRequest michael@0: let request = { michael@0: types: typeArray, michael@0: principal: principal, michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]), michael@0: allow: aCallbacks.allow, michael@0: cancel: aCallbacks.cancel, michael@0: window: Services.wm.getOuterWindowWithId(msg.windowID) michael@0: }; michael@0: michael@0: permissionPromptService.getPermission(request); michael@0: return; michael@0: } michael@0: michael@0: if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) { michael@0: aCallbacks.allow(); michael@0: return; michael@0: } michael@0: }, michael@0: michael@0: observe: function observe(aSubject, aTopic, aData) { michael@0: ppmm.removeMessageListener("PermissionPromptHelper:AskPermission", this); michael@0: Services.obs.removeObserver(this, "profile-before-change"); michael@0: ppmm = null; michael@0: }, michael@0: michael@0: receiveMessage: function receiveMessage(aMessage) { michael@0: debug("PermissionPromptHelper::receiveMessage " + aMessage.name); michael@0: let mm = aMessage.target; michael@0: let msg = aMessage.data; michael@0: michael@0: let result; michael@0: if (aMessage.name == "PermissionPromptHelper:AskPermission") { michael@0: this.askPermission(aMessage, { michael@0: cancel: function() { michael@0: mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK", michael@0: { result: Ci.nsIPermissionManager.DENY_ACTION, michael@0: requestID: msg.requestID }); michael@0: }, michael@0: allow: function(aChoice) { michael@0: mm.sendAsyncMessage("PermissionPromptHelper:AskPermission:OK", michael@0: { result: Ci.nsIPermissionManager.ALLOW_ACTION, michael@0: choice: aChoice, michael@0: requestID: msg.requestID }); michael@0: } michael@0: }); michael@0: } michael@0: } michael@0: } michael@0: michael@0: PermissionPromptHelper.init();