mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 758269 - Install permissions from manifest to Permission Manager r=fabrice
This commit is contained in:
parent
048397253f
commit
3873a0bfd0
@ -25,4 +25,8 @@ EXTRA_PP_JS_MODULES += \
|
||||
AppsUtils.jsm \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES += \
|
||||
PermissionsTable.jsm \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
175
dom/apps/src/PermissionsTable.jsm
Normal file
175
dom/apps/src/PermissionsTable.jsm
Normal file
@ -0,0 +1,175 @@
|
||||
/* 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";
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
var EXPORTED_SYMBOLS = ["PermissionsTable",
|
||||
"UNKNOWN_ACTION",
|
||||
"ALLOW_ACTION",
|
||||
"DENY_ACTION",
|
||||
"PROMPT_ACTION",
|
||||
"AllPossiblePermissions",
|
||||
"mapSuffixes",
|
||||
];
|
||||
|
||||
const UNKNOWN_ACTION = Ci.nsIPermissionManager.UNKNOWN_ACTION;
|
||||
const ALLOW_ACTION = Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||
const DENY_ACTION = Ci.nsIPermissionManager.DENY_ACTION;
|
||||
const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
|
||||
|
||||
/**
|
||||
* Converts ['read', 'write'] to ['contacts-read', 'contacts-write'], etc...
|
||||
* @param string aPermName
|
||||
* @param Array aSuffixes
|
||||
* @returns Array
|
||||
**/
|
||||
function mapSuffixes(aPermName, aSuffixes)
|
||||
{
|
||||
return aSuffixes.map(function(suf) { return aPermName + "-" + suf; });
|
||||
}
|
||||
|
||||
// Permissions Matrix: https://docs.google.com/spreadsheet/ccc?key=0Akyz_Bqjgf5pdENVekxYRjBTX0dCXzItMnRyUU1RQ0E#gid=0
|
||||
|
||||
// Permissions that are implicit:
|
||||
// battery-status, idle, network-information, vibration,
|
||||
// device-capabilities, webapps-manage, web-activities
|
||||
|
||||
const PermissionsTable = { "resource-lock": {
|
||||
app: ALLOW_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
geolocation: {
|
||||
app: PROMPT_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
camera: {
|
||||
app: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
alarm: {
|
||||
app: ALLOW_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"network-tcp": {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
contacts: {
|
||||
app: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read",
|
||||
"write",
|
||||
"create"
|
||||
]
|
||||
},
|
||||
"device-storage:apps": {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"device-storage:pictures": {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"device-storage:videos": {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"device-storage:music": {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
sms: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
telephony: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
browser: {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
bluetooth: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
wifi: {
|
||||
app: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
keyboard: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
mobileconnection: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
power: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
push: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
settings: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read",
|
||||
"write"
|
||||
],
|
||||
},
|
||||
permissions: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
fmradio: {
|
||||
app: ALLOW_ACTION, // Matrix indicates '?'
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
attention: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
};
|
||||
|
||||
// Sometimes all permissions (fully expanded) need to be iterated through
|
||||
let AllPossiblePermissions = [];
|
||||
for (let permName in PermissionsTable) {
|
||||
if (PermissionsTable[permName].access) {
|
||||
AllPossiblePermissions =
|
||||
AllPossiblePermissions.concat(mapSuffixes(permName,
|
||||
PermissionsTable[permName].access));
|
||||
}
|
||||
else {
|
||||
AllPossiblePermissions.push(permName);
|
||||
}
|
||||
}
|
@ -111,13 +111,16 @@ WebappsRegistry.prototype = {
|
||||
manifest = JSON.parse(xhr.responseText, installOrigin);
|
||||
} catch (e) {
|
||||
Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR");
|
||||
Cu.reportError("Error installing app from: " + installOrigin + ": " + "MANIFEST_PARSE_ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AppsUtils.checkManifest(manifest, installOrigin)) {
|
||||
Services.DOMRequest.fireError(request, "INVALID_MANIFEST");
|
||||
Cu.reportError("Error installing app from: " + installOrigin + ": " + "INVALID_MANIFEST");
|
||||
} else if (!this.checkAppStatus(manifest)) {
|
||||
Services.DOMRequest.fireError(request, "INVALID_SECURITY_LEVEL");
|
||||
Cu.reportError("Error installing app, '" + manifest.name + "': " + "INVALID_SECURITY_LEVEL");
|
||||
} else {
|
||||
let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
|
||||
let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : [];
|
||||
@ -133,11 +136,13 @@ WebappsRegistry.prototype = {
|
||||
}
|
||||
} else {
|
||||
Services.DOMRequest.fireError(request, "MANIFEST_URL_ERROR");
|
||||
Cu.reportError("Error installing app from: " + installOrigin + ": " + "MANIFEST_URL_ERROR");
|
||||
}
|
||||
}).bind(this), false);
|
||||
|
||||
xhr.addEventListener("error", (function() {
|
||||
Services.DOMRequest.fireError(request, "NETWORK_ERROR");
|
||||
Cu.reportError("Error installing app from: " + installOrigin + ": " + "NETWORK_ERROR");
|
||||
}).bind(this), false);
|
||||
|
||||
xhr.send(null);
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function debug(aMsg) {
|
||||
// dump("-*- Webapps.jsm: " + aMsg + "\n");
|
||||
}
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
@ -16,14 +20,33 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import('resource://gre/modules/ActivitiesService.jsm');
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
Cu.import("resource://gre/modules/PermissionsTable.jsm");
|
||||
|
||||
const WEBAPP_RUNTIME = Services.appinfo.ID == "webapprt@mozilla.org";
|
||||
|
||||
// Permission access flags
|
||||
const READONLY = "readonly";
|
||||
const CREATEONLY = "createonly";
|
||||
const READCREATE = "readcreate";
|
||||
const READWRITE = "readwrite";
|
||||
|
||||
const PERM_TO_STRING = ["unknown", "allow", "deny", "prompt"];
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this,
|
||||
"PermSettings",
|
||||
"@mozilla.org/permissionSettings;1",
|
||||
"nsIDOMPermissionSettings");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
return NetUtil;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this,
|
||||
"permissionManager",
|
||||
"@mozilla.org/permissionmanager;1",
|
||||
"nsIPermissionManager");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||
"@mozilla.org/parentprocessmessagemanager;1",
|
||||
"nsIMessageBroadcaster");
|
||||
@ -48,6 +71,81 @@ XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
|
||||
const DIRECTORY_NAME = WEBAPP_RUNTIME ? "WebappRegD" : "ProfD";
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Determine the type of app (app, privileged, certified)
|
||||
* that is installed by the manifest
|
||||
* @param object aManifest
|
||||
* @returns integer
|
||||
**/
|
||||
function getAppManifestStatus(aManifest)
|
||||
{
|
||||
let type = aManifest.type || "web";
|
||||
|
||||
switch(type) {
|
||||
case "web":
|
||||
return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||
case "privileged":
|
||||
return Ci.nsIPrincipal.APP_STATUS_PRIVILEGED;
|
||||
case "certified":
|
||||
return Ci.nsIPrincipal.APP_STATUS_CERTIFIED;
|
||||
default:
|
||||
throw new Error("Webapps.jsm: Undetermined app manifest type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand an access string into multiple permission names,
|
||||
* e.g: perm 'contacts' with 'readwrite' =
|
||||
* ['contacts-read', 'contacts-create', contacts-write']
|
||||
* @param string aPermName
|
||||
* @param string aAccess
|
||||
* @returns Array
|
||||
**/
|
||||
function expandPermissions(aPermName, aAccess)
|
||||
{
|
||||
if (!PermissionsTable[aPermName]) {
|
||||
Cu.reportError("Unknown permission: " + aPermName);
|
||||
throw new Error("Webapps.jsm: App install failed, Unknown Permission: " + aPermName);
|
||||
}
|
||||
if (!aAccess && PermissionsTable[aPermName].access ||
|
||||
aAccess && !PermissionsTable[aPermName].access) {
|
||||
Cu.reportError("Webapps.jsm: installPermissions: Invalid Manifest");
|
||||
throw new Error("Webapps.jsm: App install failed, Invalid Manifest");
|
||||
}
|
||||
if (!PermissionsTable[aPermName].access) {
|
||||
return [aPermName];
|
||||
}
|
||||
|
||||
let requestedSuffixes = [];
|
||||
switch(aAccess) {
|
||||
case READONLY:
|
||||
requestedSuffixes.push("read");
|
||||
break;
|
||||
case CREATEONLY:
|
||||
requestedSuffixes.push("create");
|
||||
break;
|
||||
case READCREATE:
|
||||
requestedSuffixes.push("read", "create");
|
||||
break;
|
||||
case READWRITE:
|
||||
requestedSuffixes.push("read", "create", "write");
|
||||
break;
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
||||
let permArr = mapSuffixes(aPermName, requestedSuffixes);
|
||||
|
||||
let expandedPerms = [];
|
||||
for (let idx in permArr) {
|
||||
if (PermissionsTable[aPermName].access.indexOf(requestedSuffixes[idx]) != -1) {
|
||||
expandedPerms.push(permArr[idx]);
|
||||
}
|
||||
}
|
||||
return expandedPerms;
|
||||
}
|
||||
|
||||
let DOMApplicationRegistry = {
|
||||
appsFile: null,
|
||||
webapps: { },
|
||||
@ -550,13 +648,16 @@ let DOMApplicationRegistry = {
|
||||
},
|
||||
|
||||
confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
|
||||
let isReinstall = false;
|
||||
let app = aData.app;
|
||||
app.removable = true;
|
||||
let id = app.syncId || this._appId(app.origin);
|
||||
let localId = this.getAppLocalIdByManifestURL(app.manifestURL);
|
||||
let manifest = new DOMApplicationManifest(app.manifest, app.origin);
|
||||
|
||||
// Installing an application again is considered as an update.
|
||||
if (id) {
|
||||
isReinstall = true;
|
||||
let dir = this._getAppDir(id);
|
||||
try {
|
||||
dir.remove(true);
|
||||
@ -564,6 +665,7 @@ let DOMApplicationRegistry = {
|
||||
}
|
||||
} else {
|
||||
id = this.makeAppId();
|
||||
app.id = id;
|
||||
localId = this._nextLocalId();
|
||||
}
|
||||
|
||||
@ -578,6 +680,7 @@ let DOMApplicationRegistry = {
|
||||
let appNote = JSON.stringify(appObject);
|
||||
appNote.id = id;
|
||||
|
||||
appObject.permissions = {};
|
||||
appObject.localId = localId;
|
||||
appObject.basePath = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true, true).path;
|
||||
|
||||
@ -603,8 +706,7 @@ let DOMApplicationRegistry = {
|
||||
|
||||
appObject.status = "installed";
|
||||
appObject.name = app.manifest.name;
|
||||
|
||||
let manifest = new DOMApplicationManifest(app.manifest, app.origin);
|
||||
this.installPermissions(appObject, aData, isReinstall);
|
||||
|
||||
if (!aFromSync)
|
||||
this._saveApps((function() {
|
||||
@ -633,6 +735,107 @@ let DOMApplicationRegistry = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Install permissisions or remove deprecated permissions upon re-install
|
||||
* @param object aAppObject
|
||||
* The just installed AppUtils cloned appObject
|
||||
* @param object aData
|
||||
* The just-installed app configuration
|
||||
* @param boolean aIsReinstall
|
||||
* Indicates the app was just re-installed
|
||||
* @returns void
|
||||
**/
|
||||
installPermissions:
|
||||
function installPermissions(aAppObject, aData, aIsReinstall)
|
||||
{
|
||||
try {
|
||||
let newManifest = new DOMApplicationManifest(aData.app.manifest,
|
||||
aData.app.origin);
|
||||
if (!newManifest.permissions && !aIsReinstall) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aIsReinstall) {
|
||||
// Compare the original permissions against the new permissions
|
||||
// Remove any deprecated Permissions
|
||||
|
||||
if (newManifest.permissions) {
|
||||
// Expand perms
|
||||
let newPerms = [];
|
||||
for (let perm in newManifest.permissions) {
|
||||
let _perms = expandPermissions(perm,
|
||||
newManifest.permissions[perm].access);
|
||||
newPerms = newPerms.concat(_perms);
|
||||
}
|
||||
|
||||
for (let idx in AllPossiblePermissions) {
|
||||
let index = newPerms.indexOf(AllPossiblePermissions[idx]);
|
||||
if (index == -1) {
|
||||
// See if the permission was installed previously
|
||||
let _perm = PermSettings.get(AllPossiblePermissions[idx],
|
||||
aData.app.manifestURL,
|
||||
aData.app.origin,
|
||||
false);
|
||||
if (_perm == "unknown" || _perm == "deny") {
|
||||
// All 'deny' permissions should be preserved
|
||||
continue;
|
||||
}
|
||||
// Remove the deprecated permission
|
||||
// TODO: use PermSettings.remove, see bug 793204
|
||||
PermSettings.set(AllPossiblePermissions[idx],
|
||||
"unknown",
|
||||
aData.app.manifestURL,
|
||||
aData.app.origin,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let installPermType;
|
||||
// Check to see if the 'webapp' is app/priv/certified
|
||||
switch (getAppManifestStatus(newManifest)) {
|
||||
case Ci.nsIPrincipal.APP_STATUS_CERTIFIED:
|
||||
installPermType = "certified";
|
||||
break;
|
||||
case Ci.nsIPrincipal.APP_STATUS_PRIVILEGED:
|
||||
installPermType = "privileged";
|
||||
break;
|
||||
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
||||
installPermType = "app";
|
||||
break;
|
||||
default:
|
||||
// Cannot determine app type, abort install by throwing an error
|
||||
throw new Error("Webapps.jsm: Cannot determine app type, install cancelled");
|
||||
}
|
||||
|
||||
for (let permName in newManifest.permissions) {
|
||||
if (!PermissionsTable[permName]) {
|
||||
throw new Error("Webapps.jsm: '" + permName + "'" +
|
||||
" is not a valid Webapps permission type. Aborting Webapp installation");
|
||||
return;
|
||||
}
|
||||
|
||||
let perms = expandPermissions(permName,
|
||||
newManifest.permissions[permName].access);
|
||||
for (let idx in perms) {
|
||||
let perm = PermissionsTable[permName][installPermType];
|
||||
let permValue = PERM_TO_STRING[perm];
|
||||
PermSettings.set(perms[idx],
|
||||
permValue,
|
||||
aData.app.manifestURL,
|
||||
aData.app.origin,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
debug("Caught webapps install permissions error");
|
||||
Cu.reportError(ex);
|
||||
this.uninstall(aData);
|
||||
}
|
||||
},
|
||||
|
||||
_nextLocalId: function() {
|
||||
let id = Services.prefs.getIntPref("dom.mozApps.maxLocalId") + 1;
|
||||
Services.prefs.setIntPref("dom.mozApps.maxLocalId", id);
|
||||
@ -728,25 +931,6 @@ let DOMApplicationRegistry = {
|
||||
return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||
}
|
||||
|
||||
function getAppManifestStatus(aManifest) {
|
||||
let type = aManifest.type || "web";
|
||||
let manifestStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||
|
||||
switch(type) {
|
||||
case "web":
|
||||
manifestStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||
break;
|
||||
case "privileged":
|
||||
manifestStatus = Ci.nsIPrincipal.APP_STATUS_PRIVILEGED;
|
||||
break
|
||||
case "certified":
|
||||
manifestStatus = Ci.nsIPrincipal.APP_STATUS_CERTIFIED;
|
||||
break;
|
||||
}
|
||||
|
||||
return manifestStatus;
|
||||
}
|
||||
|
||||
function getAppStatus(aManifest) {
|
||||
let manifestStatus = getAppManifestStatus(aManifest);
|
||||
let inferedStatus = getInferedStatus();
|
||||
@ -796,7 +980,7 @@ let DOMApplicationRegistry = {
|
||||
receipts: aData.receipts,
|
||||
categories: aData.categories
|
||||
}
|
||||
}
|
||||
};
|
||||
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
|
||||
.createInstance(Ci.nsIZipReader);
|
||||
try {
|
||||
@ -841,6 +1025,7 @@ let DOMApplicationRegistry = {
|
||||
return;
|
||||
|
||||
found = true;
|
||||
|
||||
let appNote = JSON.stringify(AppsUtils.cloneAppObject(app));
|
||||
appNote.id = id;
|
||||
|
||||
@ -1036,6 +1221,7 @@ let DOMApplicationRegistry = {
|
||||
if (record.hidden) {
|
||||
if (!this.webapps[record.id] || !this.webapps[record.id].removable)
|
||||
continue;
|
||||
|
||||
let origin = this.webapps[record.id].origin;
|
||||
delete this.webapps[record.id];
|
||||
let dir = this._getAppDir(record.id);
|
||||
@ -1324,6 +1510,13 @@ DOMApplicationManifest.prototype = {
|
||||
return this._localeProp("orientation");
|
||||
},
|
||||
|
||||
get permissions() {
|
||||
if (this._manifest.permissions) {
|
||||
return this._manifest.permissions;
|
||||
}
|
||||
return {};
|
||||
},
|
||||
|
||||
iconURLForSize: function(aSize) {
|
||||
let icons = this._localeProp("icons");
|
||||
if (!icons)
|
||||
|
@ -4,11 +4,9 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
let DEBUG = 0;
|
||||
if (DEBUG)
|
||||
debug = function (s) { dump("-*- PermissionSettings: " + s + "\n"); }
|
||||
else
|
||||
debug = function (s) {}
|
||||
function debug(aMsg) {
|
||||
// dump("-*- PermissionSettings.js: " + aMsg + "\n");
|
||||
}
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
@ -45,7 +43,7 @@ PermissionSettings.prototype = {
|
||||
switch (result)
|
||||
{
|
||||
case Ci.nsIPermissionManager.UNKNOWN_ACTION:
|
||||
return "unknown"
|
||||
return "unknown";
|
||||
case Ci.nsIPermissionManager.ALLOW_ACTION:
|
||||
return "allow";
|
||||
case Ci.nsIPermissionManager.DENY_ACTION:
|
||||
|
@ -10,7 +10,7 @@ if (DEBUG)
|
||||
else
|
||||
debug = function (s) {}
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
|
@ -20,6 +20,12 @@ MOCHITEST_BROWSER_FILES := \
|
||||
browser_ConsoleStoragePBTest.js \
|
||||
browser_autofocus_preference.js \
|
||||
browser_bug396843.js \
|
||||
browser_webapps_permissions.js \
|
||||
browser_webapps_perms_reinstall.js \
|
||||
test-webapp.webapp \
|
||||
test-webapp-reinstall.webapp \
|
||||
test-webapp-original.webapp \
|
||||
test-webapps-permissions.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
156
dom/tests/browser/browser_webapps_permissions.js
Normal file
156
dom/tests/browser/browser_webapps_permissions.js
Normal file
@ -0,0 +1,156 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
const DEBUG = 0;
|
||||
function log()
|
||||
{
|
||||
if (DEBUG) {
|
||||
let output = [];
|
||||
for (let prop in arguments) {
|
||||
output.push(arguments[prop]);
|
||||
}
|
||||
dump("-*- browser_webapps_permissions test: " + output.join(" ") + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
let scope = {};
|
||||
Cu.import("resource://gre/modules/PermissionSettings.jsm", scope);
|
||||
|
||||
const TEST_URL =
|
||||
"http://mochi.test:8888/browser/dom/tests/browser/test-webapps-permissions.html";
|
||||
const TEST_MANIFEST_URL =
|
||||
"http://mochi.test:8888/browser/dom/tests/browser/test-webapp.webapp";
|
||||
const TEST_ORIGIN_URL = "http://mochi.test:8888";
|
||||
|
||||
const installedPermsToTest = {
|
||||
"geolocation": "prompt",
|
||||
"alarm": "allow",
|
||||
"contacts-read": "deny",
|
||||
"contacts-create": "deny",
|
||||
"contacts-write": "deny",
|
||||
"device-storage:apps": "deny",
|
||||
};
|
||||
|
||||
const uninstalledPermsToTest = {
|
||||
"geolocation": "unknown",
|
||||
"alarm": "unknown",
|
||||
"contacts-read": "unknown",
|
||||
"contacts-create": "unknown",
|
||||
"contacts-write": "unknown",
|
||||
"device-storage:apps": "unknown",
|
||||
};
|
||||
|
||||
var gWindow, gNavigator;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var tab = gBrowser.addTab(TEST_URL);
|
||||
gBrowser.selectedTab = tab;
|
||||
var browser = gBrowser.selectedBrowser;
|
||||
PopupNotifications.panel.addEventListener("popupshown", handlePopup, false);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gWindow = null;
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
browser.addEventListener("DOMContentLoaded", function onLoad(event) {
|
||||
browser.removeEventListener("DOMContentLoaded", onLoad, false);
|
||||
gWindow = browser.contentWindow;
|
||||
|
||||
SpecialPowers.setBoolPref("dom.mozApps.dev_mode", true);
|
||||
SpecialPowers.setBoolPref("dom.mozPermissionSettings.enabled", true);
|
||||
SpecialPowers.addPermission("permissions", true, browser.contentWindow.document);
|
||||
SpecialPowers.addPermission("permissions", true, browser.contentDocument);
|
||||
|
||||
executeSoon(function (){
|
||||
gWindow.focus();
|
||||
var nav = XPCNativeWrapper.unwrap(browser.contentWindow.navigator);
|
||||
ok(nav.mozApps, "we have a mozApps property");
|
||||
var navMozPerms = nav.mozPermissionSettings;
|
||||
ok(navMozPerms, "mozPermissions is available");
|
||||
Math.sin(0);
|
||||
// INSTALL app
|
||||
var pendingInstall = nav.mozApps.install(TEST_MANIFEST_URL, null);
|
||||
pendingInstall.onsuccess = function onsuccess()
|
||||
{
|
||||
ok(this.result, "we have a result: " + this.result);
|
||||
|
||||
function testPerm(aPerm, aAccess)
|
||||
{
|
||||
var res =
|
||||
navMozPerms.get(aPerm, TEST_MANIFEST_URL, TEST_ORIGIN_URL, false);
|
||||
is(res, aAccess, "install: " + aPerm + " is " + res);
|
||||
}
|
||||
|
||||
for (let permName in installedPermsToTest) {
|
||||
testPerm(permName, installedPermsToTest[permName]);
|
||||
}
|
||||
// uninstall checks
|
||||
uninstallApp();
|
||||
};
|
||||
|
||||
pendingInstall.onerror = function onerror(e)
|
||||
{
|
||||
ok(false, "install()'s onerror was called: " + e);
|
||||
ok(false, "All permission checks failed, uninstal tests were not run");
|
||||
};
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
function uninstallApp()
|
||||
{
|
||||
var browser = gBrowser.selectedBrowser;
|
||||
var nav = XPCNativeWrapper.unwrap(browser.contentWindow.navigator);
|
||||
var navMozPerms = nav.mozPermissionSettings;
|
||||
|
||||
var pending = nav.mozApps.getInstalled();
|
||||
pending.onsuccess = function onsuccess() {
|
||||
var m = this.result;
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
var app = m[i];
|
||||
|
||||
function uninstall() {
|
||||
var pendingUninstall = app.uninstall();
|
||||
|
||||
pendingUninstall.onsuccess = function(r) {
|
||||
// test to make sure all permissions have been removed
|
||||
function testPerm(aPerm, aAccess)
|
||||
{
|
||||
var res =
|
||||
navMozPerms.get(aPerm, TEST_MANIFEST_URL, TEST_ORIGIN_URL, false);
|
||||
is(res, aAccess, "uninstall: " + aPerm + " is " + res);
|
||||
}
|
||||
|
||||
for (let permName in uninstalledPermsToTest) {
|
||||
testPerm(permName, uninstalledPermsToTest[permName]);
|
||||
}
|
||||
delete nav.mozApps;
|
||||
delete navMozPerms;
|
||||
delete nav;
|
||||
finish();
|
||||
};
|
||||
|
||||
pending.onerror = function _onerror(e) {
|
||||
ok(false, e);
|
||||
ok(false, "All uninstall() permission checks failed!");
|
||||
delete nav.mozApps;
|
||||
delete navMozPerms;
|
||||
delete nav;
|
||||
finish();
|
||||
};
|
||||
};
|
||||
uninstall();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function handlePopup(aEvent)
|
||||
{
|
||||
aEvent.target.removeEventListener("popupshown", handlePopup, false);
|
||||
SpecialPowers.wrap(this).childNodes[0].button.doCommand();
|
||||
}
|
183
dom/tests/browser/browser_webapps_perms_reinstall.js
Normal file
183
dom/tests/browser/browser_webapps_perms_reinstall.js
Normal file
@ -0,0 +1,183 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
const DEBUG = 0;
|
||||
function log()
|
||||
{
|
||||
if (DEBUG) {
|
||||
let output = [];
|
||||
for (let prop in arguments) {
|
||||
output.push(arguments[prop]);
|
||||
}
|
||||
dump("-*- browser_webapps_perms_reinstall: " + output.join(" ") + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
function pprint(aObj) {
|
||||
function log(a){dump(a + "\n");}
|
||||
for (let prop in aObj) {
|
||||
if (typeof aObj[prop] == "object") {
|
||||
log("- " + prop + " -");
|
||||
pprint(aObj[prop]);
|
||||
}
|
||||
else {
|
||||
log(prop + ": " + aObj[prop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let scope = {};
|
||||
Cu.import("resource://gre/modules/PermissionSettings.jsm", scope);
|
||||
|
||||
const TEST_URL =
|
||||
"http://mochi.test:8888/browser/dom/tests/browser/test-webapps-permissions.html";
|
||||
const TEST_MANIFEST_URL =
|
||||
"http://mochi.test:8888/browser/dom/tests/browser/test-webapp.webapp";
|
||||
const TEST_ORIGIN_URL = "http://mochi.test:8888";
|
||||
|
||||
const installedPermsToTest = {
|
||||
"geolocation": "prompt",
|
||||
"alarm": "allow",
|
||||
"contacts-read": "deny",
|
||||
"contacts-create": "deny",
|
||||
"contacts-write": "deny",
|
||||
"device-storage:apps": "deny",
|
||||
};
|
||||
|
||||
const reinstalledPermsToTest = {
|
||||
"geolocation": "prompt",
|
||||
"alarm": "unknown",
|
||||
"contacts-read": "deny",
|
||||
"contacts-create": "deny",
|
||||
"contacts-write": "deny",
|
||||
"device-storage:apps": "deny",
|
||||
};
|
||||
|
||||
var gWindow, gNavigator;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var tab = gBrowser.addTab(TEST_URL);
|
||||
gBrowser.selectedTab = tab;
|
||||
var browser = gBrowser.selectedBrowser;
|
||||
PopupNotifications.panel.addEventListener("popupshown", handlePopup, false);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gWindow = null;
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
browser.addEventListener("DOMContentLoaded", function onLoad(event) {
|
||||
browser.removeEventListener("DOMContentLoaded", onLoad, false);
|
||||
gWindow = browser.contentWindow;
|
||||
SpecialPowers.setBoolPref("dom.mozApps.dev_mode", true);
|
||||
SpecialPowers.setBoolPref("dom.mozPermissionSettings.enabled", true);
|
||||
SpecialPowers.addPermission("permissions", true, browser.contentWindow.document);
|
||||
SpecialPowers.addPermission("permissions", true, browser.contentDocument);
|
||||
|
||||
let pendingInstall;
|
||||
|
||||
function testInstall() {
|
||||
var nav = XPCNativeWrapper.unwrap(browser.contentWindow.navigator);
|
||||
ok(nav.mozApps, "we have a mozApps property");
|
||||
var navMozPerms = nav.mozPermissionSettings;
|
||||
ok(navMozPerms, "mozPermissions is available");
|
||||
|
||||
// INSTALL app
|
||||
pendingInstall = nav.mozApps.install(TEST_MANIFEST_URL, null);
|
||||
pendingInstall.onsuccess = function onsuccess()
|
||||
{
|
||||
ok(this.result, "we have a result: " + this.result);
|
||||
function testPerm(aPerm, aAccess)
|
||||
{
|
||||
var res =
|
||||
navMozPerms.get(aPerm, TEST_MANIFEST_URL, TEST_ORIGIN_URL, false);
|
||||
is(res, aAccess, "install: " + aPerm + " is " + res);
|
||||
}
|
||||
|
||||
for (let permName in installedPermsToTest) {
|
||||
testPerm(permName, installedPermsToTest[permName]);
|
||||
}
|
||||
|
||||
writeUpdatesToWebappManifest();
|
||||
};
|
||||
|
||||
pendingInstall.onerror = function onerror(e)
|
||||
{
|
||||
ok(false, "install()'s onerror was called: " + e);
|
||||
ok(false, "All permission checks failed, reinstall tests were not run");
|
||||
};
|
||||
}
|
||||
testInstall();
|
||||
}, false);
|
||||
}
|
||||
|
||||
function reinstallApp()
|
||||
{
|
||||
var browser = gBrowser.selectedBrowser;
|
||||
var nav = XPCNativeWrapper.unwrap(browser.contentWindow.navigator);
|
||||
var navMozPerms = nav.mozPermissionSettings;
|
||||
|
||||
var pendingReinstall = nav.mozApps.install(TEST_MANIFEST_URL);
|
||||
pendingReinstall.onsuccess = function onsuccess()
|
||||
{
|
||||
ok(this.result, "we have a result: " + this.result);
|
||||
|
||||
function testPerm(aPerm, aAccess)
|
||||
{
|
||||
var res =
|
||||
navMozPerms.get(aPerm, TEST_MANIFEST_URL, TEST_ORIGIN_URL, false);
|
||||
is(res, aAccess, "reinstall: " + aPerm + " is " + res);
|
||||
}
|
||||
|
||||
for (let permName in reinstalledPermsToTest) {
|
||||
testPerm(permName, reinstalledPermsToTest[permName]);
|
||||
}
|
||||
writeUpdatesToWebappManifest(true);
|
||||
finish();
|
||||
};
|
||||
};
|
||||
|
||||
var qtyPopups = 0;
|
||||
|
||||
function handlePopup(aEvent)
|
||||
{
|
||||
qtyPopups++;
|
||||
if (qtyPopups == 2) {
|
||||
aEvent.target.removeEventListener("popupshown", handlePopup, false);
|
||||
}
|
||||
SpecialPowers.wrap(this).childNodes[0].button.doCommand();
|
||||
}
|
||||
|
||||
function writeUpdatesToWebappManifest(aRestore)
|
||||
{
|
||||
let newfile = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("XCurProcD", Ci.nsIFile);
|
||||
|
||||
let parents = ["_tests", "testing", "mochitest", "browser", "dom" , "tests", "browser"];
|
||||
newfile = newfile.parent; // up to dist/
|
||||
newfile = newfile.parent;// up to obj-dir/
|
||||
|
||||
for (let idx in parents) {
|
||||
newfile.append(parents[idx]);
|
||||
}
|
||||
|
||||
if (aRestore) {
|
||||
newfile.append("test-webapp-original.webapp");
|
||||
} else {
|
||||
newfile.append("test-webapp-reinstall.webapp");
|
||||
}
|
||||
|
||||
let oldfile = newfile.parent;
|
||||
oldfile.append("test-webapp.webapp");
|
||||
|
||||
newfile.copyTo(null, "test-webapp.webapp");
|
||||
|
||||
if (!aRestore) {
|
||||
executeSoon(function (){ reinstallApp(); });
|
||||
}
|
||||
}
|
20
dom/tests/browser/test-webapp-original.webapp
Normal file
20
dom/tests/browser/test-webapp-original.webapp
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Super Crazy Basic App",
|
||||
"installs_allowed_from": [ "*" ],
|
||||
"type": "privileged",
|
||||
"permissions": {
|
||||
"geolocation": {
|
||||
"description": "geolocate"
|
||||
},
|
||||
"alarm" : {
|
||||
"description": "alarm"
|
||||
},
|
||||
"contacts": {
|
||||
"description": "contacts",
|
||||
"access": "readwrite"
|
||||
},
|
||||
"device-storage:apps": {
|
||||
"description": "storage"
|
||||
}
|
||||
}
|
||||
}
|
17
dom/tests/browser/test-webapp-reinstall.webapp
Normal file
17
dom/tests/browser/test-webapp-reinstall.webapp
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "Super Crazy Basic App",
|
||||
"installs_allowed_from": [ "*" ],
|
||||
"type": "privileged",
|
||||
"permissions": {
|
||||
"geolocation": {
|
||||
"description": "geolocate"
|
||||
},
|
||||
"contacts": {
|
||||
"description": "contacts",
|
||||
"access": "read"
|
||||
},
|
||||
"device-storage:apps": {
|
||||
"description": "storage"
|
||||
}
|
||||
}
|
||||
}
|
20
dom/tests/browser/test-webapp.webapp
Normal file
20
dom/tests/browser/test-webapp.webapp
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Super Crazy Basic App",
|
||||
"installs_allowed_from": [ "*" ],
|
||||
"type": "privileged",
|
||||
"permissions": {
|
||||
"geolocation": {
|
||||
"description": "geolocate"
|
||||
},
|
||||
"alarm" : {
|
||||
"description": "alarm"
|
||||
},
|
||||
"contacts": {
|
||||
"description": "contacts",
|
||||
"access": "readwrite"
|
||||
},
|
||||
"device-storage:apps": {
|
||||
"description": "storage"
|
||||
}
|
||||
}
|
||||
}
|
9
dom/tests/browser/test-webapps-permissions.html
Normal file
9
dom/tests/browser/test-webapps-permissions.html
Normal file
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html dir="ltr" xml:lang="en-US" lang="en-US">
|
||||
<head>
|
||||
<title>Webapps permissions test page</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Webapps permissions</h1>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user