Bug 781620 - Bridge the DOM webapps registry with nsIPrincipal::GetStatus() - Part 1 : nsPrincipal changes [r=mounir]

This commit is contained in:
Fabrice Desré 2012-08-27 19:43:57 -07:00
parent ba942b526f
commit 17c1f0d102
3 changed files with 78 additions and 25 deletions

View File

@ -30,6 +30,9 @@
#include "mozilla/Preferences.h"
#include "mozilla/HashFunctions.h"
#include "nsIAppsService.h"
#include "mozIApplication.h"
using namespace mozilla;
static bool gCodeBasePrincipalSupport = false;
@ -1299,10 +1302,45 @@ nsPrincipal::GetAppStatus()
// Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
// and they are not inside a mozbrowser.
return mAppId != nsIScriptSecurityManager::NO_APP_ID &&
mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID && !mInMozBrowser
? nsIPrincipal::APP_STATUS_INSTALLED
: nsIPrincipal::APP_STATUS_NOT_INSTALLED;
if (mAppId == nsIScriptSecurityManager::NO_APP_ID ||
mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID || mInMozBrowser) {
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(appsService, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsCOMPtr<mozIDOMApplication> domApp;
appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
NS_ENSURE_TRUE(app, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
uint16_t status = nsIPrincipal::APP_STATUS_INSTALLED;
NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsCAutoString origin;
NS_ENSURE_SUCCESS(GetOrigin(getter_Copies(origin)),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsString appOrigin;
NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
// We go from string -> nsIURI -> origin to be sure we
// compare two punny-encoded origins.
nsCOMPtr<nsIURI> appURI;
NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsCAutoString appOriginPunned;
NS_ENSURE_SUCCESS(GetOriginForURI(appURI, getter_Copies(appOriginPunned)),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
if (!appOriginPunned.Equals(origin)) {
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
}
return status;
}
/************************************************************************************************************************/

View File

@ -80,6 +80,11 @@ let DOMApplicationRegistry = {
if (!this.webapps[id].localId) {
this.webapps[id].localId = this._nextLocalId();
}
// Default to a non privileged status.
if (this.webapps[id].appStatus === undefined) {
this.webapps[id].appStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
}
};
}).bind(this));
}
@ -290,6 +295,8 @@ let DOMApplicationRegistry = {
receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
installTime: aApp.installTime,
manifestURL: aApp.manifestURL,
appStatus: aApp.appStatus,
localId: aApp.localId,
progress: aApp.progress || 0.0,
status: aApp.status || "installed"
};
@ -332,6 +339,7 @@ let DOMApplicationRegistry = {
}
let appObject = this._cloneAppObject(app);
appObject.appStatus = app.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
appObject.installTime = app.installTime = Date.now();
let appNote = JSON.stringify(appObject);
appNote.id = id;
@ -696,6 +704,28 @@ let DOMApplicationRegistry = {
return app;
},
_cloneAsMozIApplication: function(aApp) {
let res = this._cloneAppObject(aApp);
res.hasPermission = function(permission) {
let localId = DOMApplicationRegistry.getAppLocalIdByManifestURL(
this.manifestURL);
let uri = Services.io.newURI(this.origin, null, null);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
// XXX for the purposes of permissions checking, this helper
// should never been called with isBrowser=true, so we
// assume false here.
let principal = secMan.getAppCodebasePrincipal(uri, localId,
/*mozbrowser*/false);
let perm = Services.perms.testExactPermissionFromPrincipal(principal,
permission);
return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
};
res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
Ci.mozIApplication]);
return res;
},
getAppByManifestURL: function(aManifestURL) {
// This could be O(1) if |webapps| was a dictionary indexed on manifestURL
// which should be the unique app identifier.
@ -703,25 +733,7 @@ let DOMApplicationRegistry = {
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.manifestURL == aManifestURL) {
let res = this._cloneAppObject(app);
res.hasPermission = function(permission) {
let localId = DOMApplicationRegistry.getAppLocalIdByManifestURL(
this.manifestURL);
let uri = Services.io.newURI(this.manifestURL, null, null);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
// XXX for the purposes of permissions checking, this helper
// should always be called on !isBrowser frames, so we
// assume false here.
let principal = secMan.getAppCodebasePrincipal(uri, localId,
/*mozbrowser*/false);
let perm = Services.perms.testExactPermissionFromPrincipal(principal,
permission);
return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
};
res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
Ci.mozIApplication]);
return res;
return this._cloneAsMozIApplication(app);
}
}
@ -732,7 +744,7 @@ let DOMApplicationRegistry = {
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.localId == aLocalId) {
return this._cloneAppObject(app);
return this._cloneAsMozIApplication(app);
}
}

View File

@ -11,9 +11,12 @@
* We expose Gecko-internal helpers related to "web apps" through this
* sub-interface.
*/
[scriptable, uuid(8de25e36-b4cb-4e89-9310-a199dce4e5f4)]
[scriptable, uuid(acf46a46-729a-4ab4-9da3-8d59ecfd103d)]
interface mozIApplication: mozIDOMApplication
{
/* Return true if this app has |permission|. */
boolean hasPermission(in string permission);
/* Application status as defined in nsIPrincipal. */
readonly attribute unsigned short appStatus;
};