Bug 768868 - App manifest should support application type [r=vingtetun]

This commit is contained in:
Fabrice Desré 2012-08-27 19:43:57 -07:00
parent a8c212eb9e
commit f24d334b22
3 changed files with 85 additions and 23 deletions

View File

@ -20,7 +20,7 @@ function convertAppsArray(aApps, aWindow) {
let apps = Cu.createArrayIn(aWindow);
for (let i = 0; i < aApps.length; i++) {
let app = aApps[i];
apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
app.receipts, app.installOrigin, app.installTime));
}
@ -55,6 +55,14 @@ WebappsRegistry.prototype = {
return true;
},
// Hosted apps can't be trusted or certified, so just check that the
// manifest doesn't ask for those.
checkAppStatus: function(aManifest) {
let manifestStatus = aManifest.type || "web";
return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") ||
manifestStatus === "web");
},
receiveMessage: function(aMessage) {
let msg = aMessage.json;
if (msg.oid != this._id)
@ -92,11 +100,11 @@ WebappsRegistry.prototype = {
_getOrigin: function(aURL) {
let uri = Services.io.newURI(aURL, null, null);
return uri.prePath;
return uri.prePath;
},
// mozIDOMApplicationRegistry implementation
install: function(aURL, aParams) {
let installURL = this._window.location.href;
let installOrigin = this._getOrigin(installURL);
@ -113,17 +121,21 @@ WebappsRegistry.prototype = {
if (!this.checkManifest(manifest, installOrigin)) {
Services.DOMRequest.fireError(request, "INVALID_MANIFEST");
} else {
let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : [];
cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
origin: this._getOrigin(aURL),
manifestURL: aURL,
manifest: manifest,
receipts: receipts,
categories: categories },
from: installURL,
oid: this._id,
requestID: requestID });
if (!this.checkAppStatus(manifest)) {
Services.DOMRequest.fireError(request, "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 : [];
cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
origin: this._getOrigin(aURL),
manifestURL: aURL,
manifest: manifest,
receipts: receipts,
categories: categories },
from: installURL,
oid: this._id,
requestID: requestID });
}
}
} catch(e) {
Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR");
@ -131,7 +143,7 @@ WebappsRegistry.prototype = {
}
else {
Services.DOMRequest.fireError(request, "MANIFEST_URL_ERROR");
}
}
}).bind(this), false);
xhr.addEventListener("error", (function() {
@ -195,11 +207,11 @@ WebappsRegistry.prototype = {
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this._id = util.outerWindowID;
},
classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry, Ci.nsIDOMGlobalPropertyInitializer]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
contractID: "@mozilla.org/webapps;1",
interfaces: [Ci.mozIDOMApplicationRegistry],
@ -294,7 +306,7 @@ WebappsApplication.prototype = {
case "Webapps:OfflineCache":
if (msg.manifest != this.manifestURL)
return;
this.status = msg.status;
if (this._onprogress) {
let event = new this._window.MozApplicationEvent("applicationinstall", { application: this });
@ -393,7 +405,7 @@ WebappsApplicationMgmt.prototype = {
let req = this.getRequest(msg.requestID);
// We want Webapps:Install:Return:OK and Webapps:Uninstall:Return:OK to be boradcasted
// to all instances of mozApps.mgmt
if (!((msg.oid == this._id && req)
if (!((msg.oid == this._id && req)
|| aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
return;
switch (aMessage.name) {
@ -409,7 +421,7 @@ WebappsApplicationMgmt.prototype = {
case "Webapps:Install:Return:OK":
if (this._oninstall) {
let app = msg.app;
let event = new this._window.MozApplicationEvent("applicationinstall",
let event = new this._window.MozApplicationEvent("applicationinstall",
{ application : createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime) });
this._oninstall.handleEvent(event);
@ -417,7 +429,7 @@ WebappsApplicationMgmt.prototype = {
break;
case "Webapps:Uninstall:Return:OK":
if (this._onuninstall) {
let event = new this._window.MozApplicationEvent("applicationuninstall",
let event = new this._window.MozApplicationEvent("applicationuninstall",
{ application : createApplicationObject(this._window, msg.origin, null, null, null, null, 0) });
this._onuninstall.handleEvent(event);
}

View File

@ -484,6 +484,47 @@ let DOMApplicationRegistry = {
error: aError });
}
function getInferedStatus() {
// XXX Update once we have digital signatures (bug 772365)
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();
return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") ? manifestStatus
: inferedStatus);
}
// Returns true if the privilege level from the manifest
// is lower or equal to the one we infered for the app.
function checkAppStatus(aManifest) {
if (Services.prefs.getBoolPref("dom.mozApps.dev_mode")) {
return true;
}
return (getAppManifestStatus(aManifest) <= getInferedStatus());
}
NetUtil.asyncFetch(aData.url, function(aInput, aResult, aRequest) {
if (!Components.isSuccessCode(aResult)) {
// We failed to fetch the zip.
@ -529,14 +570,19 @@ let DOMApplicationRegistry = {
msg.app.manifest = JSON.parse(NetUtil.readInputStreamToString(istream,
istream.available()) || "");
if (!checkManifest(msg.app.manifest)) {
throw "Invalid manifest";
throw "INVALID_MANIFEST";
}
if (!checkAppStatus(msg.app.manifest)) {
throw "INVALID_SECURITY_LEVEL";
}
msg.appStatus = getAppStatus(msg.app.manifest);
Services.obs.notifyObservers(this, "webapps-ask-install",
JSON.stringify(msg));
} catch (e) {
// XXX we may need new error messages.
cleanup("INVALID_MANIFEST");
cleanup(e);
} finally {
zipReader.close();
}

View File

@ -3689,3 +3689,7 @@ pref("social.enabled", false);
// Disable idle observer fuzz, because only privileged content can access idle
// observers (bug 780507).
pref("dom.idle-observers-api.fuzz_time.disabled", true);
// Setting that to true grant elevated privileges to apps that ask
// for them in their manifest.
pref("dom.mozApps.dev_mode", false);