Bug 773114 - Permission UI events for apps r=sicking r=anygregor

This commit is contained in:
David Dahl 2012-10-24 15:19:01 -05:00
parent bfe82dd676
commit 034cdc9123
9 changed files with 227 additions and 18 deletions

View File

@ -2,6 +2,15 @@
* 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/. */
let DEBUG = 0;
let debug;
if (DEBUG) {
debug = function (s) { dump("-*- ContentPermissionPrompt: " + s + "\n"); };
}
else {
debug = function (s) {};
}
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
@ -11,6 +20,40 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Webapps.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
XPCOMUtils.defineLazyServiceGetter(this,
"PermSettings",
"@mozilla.org/permissionSettings;1",
"nsIDOMPermissionSettings");
function rememberPermission(aPermission, aPrincipal)
{
function convertPermToAllow(aPerm, aPrincipal)
{
let type =
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
if (type == Ci.nsIPermissionManager.PROMPT_ACTION) {
permissionManager.addFromPrincipal(aPrincipal,
aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION);
}
}
// Expand the permission to see if we have multiple access properties to convert
let access = PermissionsTable[aPermission].access;
if (access) {
for (let idx in access) {
convertPermToAllow(aPermission + "-" + access[idx], aPrincipal);
}
}
else {
convertPermToAllow(aPermission, aPrincipal);
}
}
function ContentPermissionPrompt() {}
@ -47,8 +90,8 @@ ContentPermissionPrompt.prototype = {
evt.target.removeEventListener(evt.type, contentEvent);
if (evt.detail.type == "permission-allow") {
if (evt.detail.remember) {
rememberPermission(request.type, request.principal);
Services.perms.addFromPrincipal(request.principal, request.type,
Ci.nsIPermissionManager.ALLOW_ACTION);
}
@ -73,9 +116,14 @@ ContentPermissionPrompt.prototype = {
permission: request.type,
id: requestId,
origin: principal.origin,
isApp: isApp
isApp: isApp,
remember: request.remember
};
this._permission = request.type;
this._uri = request.principal.URI.spec;
this._origin = request.principal.origin;
if (!isApp) {
browser.shell.sendChromeEvent(details);
return;

View File

@ -335,6 +335,8 @@
@BINPATH@/components/ContactManager.manifest
@BINPATH@/components/PermissionSettings.js
@BINPATH@/components/PermissionSettings.manifest
@BINPATH@/components/PermissionPromptService.js
@BINPATH@/components/PermissionPromptService.manifest
@BINPATH@/components/AlarmsManager.js
@BINPATH@/components/AlarmsManager.manifest
@BINPATH@/components/FeedProcessor.manifest

View File

@ -11,8 +11,10 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/PermissionSettings.jsm");
var EXPORTED_SYMBOLS = ["PermissionsInstaller"];
var EXPORTED_SYMBOLS = ["PermissionsInstaller",
"expandPermissions",
"PermissionsTable",
];
const UNKNOWN_ACTION = Ci.nsIPermissionManager.UNKNOWN_ACTION;
const ALLOW_ACTION = Ci.nsIPermissionManager.ALLOW_ACTION;
const DENY_ACTION = Ci.nsIPermissionManager.DENY_ACTION;

View File

@ -15,6 +15,7 @@ GRE_MODULE = 1
XPIDLSRCS = \
nsIDOMPermissionSettings.idl \
nsIPermissionPromptService.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,20 @@
/* 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 "nsISupports.idl"
interface nsIContentPermissionRequest;
/**
* Generic permission service for access to WebAPIs, hardware, capabilities.
*/
[scriptable, uuid(e5f953b3-a6ca-444e-a88d-cdc81383741c)]
interface nsIPermissionPromptService : nsISupports
{
/**
* Checks if the capability requires a permission, fires the corresponding cancel()
* or allow() method in aRequest after consulting nsIDOMPermissionSettings, etc.
*/
void getPermission(in nsIContentPermissionRequest aRequest);
};

View File

@ -18,6 +18,8 @@ GRE_MODULE = 1
EXTRA_COMPONENTS = \
PermissionSettings.js \
PermissionSettings.manifest \
PermissionPromptService.js \
PermissionPromptService.manifest \
$(NULL)
EXTRA_JS_MODULES = \

View File

@ -25,7 +25,7 @@ if (DEBUG)
else
debug = function (s) {}
const Cu = Components.utils;
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -33,11 +33,16 @@ let EXPORTED_SYMBOLS = ["PermissionPromptHelper"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageListenerManager");
XPCOMUtils.defineLazyServiceGetter(this, "permissionPromptService",
"@mozilla.org/permission-prompt-service;1",
"nsIPermissionPromptService");
var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
var appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService);
@ -51,22 +56,59 @@ let PermissionPromptHelper = {
askPermission: function(aMessage, aCallbacks) {
let msg = aMessage.json;
debug("askPerm: " + JSON.stringify(aMessage.json));
let uri = Services.io.newURI(msg.origin, null, null);
let principal = secMan.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag);
let perm = permissionManager.testExactPermissionFromPrincipal(principal, msg.type);
switch(perm) {
case Ci.nsIPermissionManager.ALLOW_ACTION:
aCallbacks.allow();
return;
case Ci.nsIPermissionManager.DENY_ACTION:
aCallbacks.cancel();
return;
let access;
if (PermissionsTable[msg.type].access) {
access = "readwrite"; // XXXddahl: Not sure if this should be set to READWRITE
}
// expand Permissions:
var expandedPerms = expandPermissions(msg.type, access);
let installedPerms = [];
let principal;
for (let idx in expandedPerms) {
let uri = Services.io.newURI(msg.origin, null, null);
principal =
secMan.getAppCodebasePrincipal(uri, msg.appID, msg.browserFlag);
let perm =
permissionManager.testExactPermissionFromPrincipal(principal, msg.type);
installedPerms.push(perm);
}
// FIXXMEE PROMPT MAGIC! Bug 773114.
// We have to diplay the prompt here.
// TODO: see bug 804623, We are preventing "read" operations
// even if just "write" has been set to DENY_ACTION
for (let idx in installedPerms) {
// if any of the installedPerms are deny, run aCallbacks.cancel
if (installedPerms[idx] == Ci.nsIPermissionManager.DENY_ACTION ||
installedPerms[idx] == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
aCallbacks.cancel();
return;
}
}
for (let idx in installedPerms) {
if (installedPerms[idx] == Ci.nsIPermissionManager.PROMPT_ACTION) {
// create a nsIContentPermissionRequest
let request = {
type: msg.type,
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 installedPerms) {
if (installedPerms[idx] == Ci.nsIPermissionManager.ALLOW_ACTION) {
aCallbacks.allow();
return;
}
}
},
observe: function(aSubject, aTopic, aData) {

View File

@ -0,0 +1,90 @@
/* 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/. */
"use strict";
/* static functions */
let DEBUG = 0;
let debug;
if (DEBUG) {
debug = function (s) { dump("-*- PermissionPromptService: " + s + "\n"); };
}
else {
debug = function (s) {};
}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
const PERMISSIONPROMPTSERVICE_CONTRACTID = "@mozilla.org/permission-prompt-service;1";
const PERMISSIONPROMPTSERVICE_CID = Components.ID("{e5f953b3-a6ca-444e-a88d-cdc81383741c}");
const permissionPromptService = Ci.nsIPermissionPromptService;
XPCOMUtils.defineLazyServiceGetter(this,
"PermSettings",
"@mozilla.org/permissionSettings;1",
"nsIDOMPermissionSettings");
var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
function makePrompt()
{
return Cc["@mozilla.org/content-permission/prompt;1"].createInstance(Ci.nsIContentPermissionPrompt);
}
function PermissionPromptService()
{
debug("Constructor");
}
PermissionPromptService.prototype = {
classID : PERMISSIONPROMPTSERVICE_CID,
QueryInterface : XPCOMUtils.generateQI([permissionPromptService, Ci.nsIObserver]),
classInfo : XPCOMUtils.generateCI({classID: PERMISSIONPROMPTSERVICE_CID,
contractID: PERMISSIONPROMPTSERVICE_CONTRACTID,
classDescription: "PermissionPromptService",
interfaces: [permissionPromptService]
}),
/**
* getPermission
* Ask for permission for an API, device, etc.
* @param nsIContentPermissionRequest aRequest
* @returns void
**/
getPermission: function PS_getPermission(aRequest)
{
if (!(aRequest instanceof Ci.nsIContentPermissionRequest)) {
throw new Error("PermissionService.getPermission: "
+ "2nd argument must be type 'nsIContentPermissionRequest'");
}
let perm =
permissionManager.testExactPermissionFromPrincipal(aRequest.principal,
aRequest.type);
switch (perm) {
case Ci.nsIPermissionManager.ALLOW_ACTION:
aRequest.allow();
break;
case Ci.nsIPermissionManager.PROMPT_ACTION:
makePrompt().prompt(aRequest);
break;
case Ci.nsIPermissionManager.DENY_ACTION:
case Ci.nsIPermissionManager.UNKNOWN_ACTION:
default:
aRequest.cancel();
break;
}
},
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([PermissionPromptService]);

View File

@ -0,0 +1,2 @@
component {e5f953b3-a6ca-444e-a88d-cdc81383741c} PermissionPromptService.js
contract @mozilla.org/permission-prompt-service;1 {e5f953b3-a6ca-444e-a88d-cdc81383741c}