Bug 918880 - MaybeAllowOfflineAppByDefault must work on child processes, r=jduell

This commit is contained in:
Honza Bambas 2013-11-19 23:15:59 +01:00
parent d816d0d2e2
commit 4fc7ebc647
10 changed files with 104 additions and 15 deletions

View File

@ -511,6 +511,9 @@ var shell = {
Services.perms.addFromPrincipal(principal, 'offline-app',
Ci.nsIPermissionManager.ALLOW_ACTION);
let documentURI = Services.io.newURI(contentWindow.document.documentURI,
null,
null);
let manifestURI = Services.io.newURI(manifest, null, documentURI);
let updateService = Cc['@mozilla.org/offlinecacheupdate-service;1']
.getService(Ci.nsIOfflineCacheUpdateService);

View File

@ -1460,7 +1460,7 @@ public:
* If offline-apps.allow_by_default is true, we set offline-app permission
* for the principal and return true. Otherwise false.
*/
static bool MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal);
static bool MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal, nsIDOMWindow *aWindow);
/**
* Increases the count of blockers preventing scripts from running.

View File

@ -1055,7 +1055,7 @@ nsContentSink::ProcessOfflineManifest(const nsAString& aManifestSpec)
// Only continue if the document has permission to use offline APIs or
// when preferences indicate to permit it automatically.
if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal()) &&
!nsContentUtils::MaybeAllowOfflineAppByDefault(mDocument->NodePrincipal()) &&
!nsContentUtils::MaybeAllowOfflineAppByDefault(mDocument->NodePrincipal(), mDocument->GetWindow()) &&
!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) {
return;
}

View File

@ -1428,7 +1428,8 @@ nsContentUtils::OfflineAppAllowed(nsIPrincipal *aPrincipal)
}
bool
nsContentUtils::MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal)
nsContentUtils::MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal,
nsIDOMWindow *aWindow)
{
if (!Preferences::GetRootBranch())
return false;
@ -1444,19 +1445,14 @@ nsContentUtils::MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal)
if (!allowedByDefault)
return false;
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager)
nsCOMPtr<nsIOfflineCacheUpdateService> updateService =
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
if (!updateService) {
return false;
}
rv = permissionManager->AddFromPrincipal(
aPrincipal, "offline-app", nsIPermissionManager::ALLOW_ACTION,
nsIPermissionManager::EXPIRE_NEVER, 0);
if (NS_FAILED(rv))
return false;
// We have added the permission
return true;
rv = updateService->AllowOfflineApp(aWindow, aPrincipal);
return NS_SUCCEEDED(rv);
}
// static

View File

@ -255,6 +255,13 @@ parent:
POfflineCacheUpdate(URIParams manifestURI, URIParams documentURI,
bool stickDocument);
/**
* Sets "offline-app" permission for the principal. Called when we hit
* a web app with the manifest attribute in <html> and
* offline-apps.allow_by_default is set to true.
*/
SetOfflinePermission(Principal principal);
sync PIndexedDB(nsCString group, nsCString asciiOrigin)
returns (bool allowed);

View File

@ -1577,6 +1577,14 @@ TabParent::DeallocPOfflineCacheUpdateParent(mozilla::docshell::POfflineCacheUpda
return true;
}
bool
TabParent::RecvSetOfflinePermission(const IPC::Principal& aPrincipal)
{
nsIPrincipal* principal = aPrincipal;
nsContentUtils::MaybeAllowOfflineAppByDefault(principal, nullptr);
return true;
}
bool
TabParent::ShouldDelayDialogs()
{

View File

@ -236,6 +236,7 @@ public:
const URIParams& aDocumentURI,
const bool& stickDocument) MOZ_OVERRIDE;
virtual bool DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* actor);
virtual bool RecvSetOfflinePermission(const IPC::Principal& principal);
bool GetGlobalJSObject(JSContext* cx, JSObject** globalp);

View File

@ -192,7 +192,7 @@ interface nsIOfflineCacheUpdate : nsISupports {
readonly attribute uint64_t byteProgress;
};
[scriptable, uuid(cf362a31-4166-4994-8443-b68704ecdcc0)]
[scriptable, uuid(6ee353ba-11ea-4008-a78a-55b343fb2a49)]
interface nsIOfflineCacheUpdateService : nsISupports {
/**
* Constants for the offline-app permission.
@ -291,4 +291,11 @@ interface nsIOfflineCacheUpdateService : nsISupports {
*/
boolean offlineAppAllowedForURI(in nsIURI aURI,
in nsIPrefBranch aPrefBranch);
/**
* Sets the "offline-app" permission for the principal.
* In the single process model calls directly on permission manager.
* In the multi process model dispatches to the parent process.
*/
void allowOfflineApp(in nsIDOMWindow aWindow, in nsIPrincipal aPrincipal);
};

View File

@ -31,6 +31,8 @@
#include "nsWeakReference.h"
#include "nsICryptoHash.h"
#include "mozilla/Attributes.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
class nsOfflineCacheUpdate;
@ -356,10 +358,13 @@ public:
nsIPrefBranch *aPrefBranch,
bool *aPinned);
static nsTHashtable<nsCStringHashKey>* AllowedDomains();
private:
nsresult ProcessNextUpdate();
nsTArray<nsRefPtr<nsOfflineCacheUpdate> > mUpdates;
static nsTHashtable<nsCStringHashKey>* mAllowedDomains;
bool mDisabled;
bool mUpdateRunning;

View File

@ -48,11 +48,28 @@
#include "mozilla/Preferences.h"
#include "mozilla/Attributes.h"
#include "nsIDiskSpaceWatcher.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeOwner.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/PermissionMessageUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nullptr;
nsTHashtable<nsCStringHashKey>* nsOfflineCacheUpdateService::mAllowedDomains = nullptr;
nsTHashtable<nsCStringHashKey>* nsOfflineCacheUpdateService::AllowedDomains()
{
if (!mAllowedDomains)
mAllowedDomains = new nsTHashtable<nsCStringHashKey>();
return mAllowedDomains;
}
typedef mozilla::docshell::OfflineCacheUpdateParent OfflineCacheUpdateParent;
typedef mozilla::docshell::OfflineCacheUpdateChild OfflineCacheUpdateChild;
typedef mozilla::docshell::OfflineCacheUpdateGlue OfflineCacheUpdateGlue;
@ -681,6 +698,15 @@ OfflineAppPermForURI(nsIURI *aURI,
}
}
nsAutoCString domain;
rv = innerURI->GetAsciiHost(domain);
NS_ENSURE_SUCCESS(rv, rv);
if (nsOfflineCacheUpdateService::AllowedDomains()->Contains(domain)) {
*aAllowed = true;
return NS_OK;
}
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager) {
@ -717,3 +743,39 @@ nsOfflineCacheUpdateService::OfflineAppPinnedForURI(nsIURI *aDocumentURI,
{
return OfflineAppPermForURI(aDocumentURI, aPrefBranch, true, aPinned);
}
NS_IMETHODIMP
nsOfflineCacheUpdateService::AllowOfflineApp(nsIDOMWindow *aWindow,
nsIPrincipal *aPrincipal)
{
nsresult rv;
if (GeckoProcessType_Default != XRE_GetProcessType()) {
TabChild* child = TabChild::GetFrom(aWindow);
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
if (!child->SendSetOfflinePermission(IPC::Principal(aPrincipal))) {
return NS_ERROR_FAILURE;
}
nsAutoCString domain;
rv = aPrincipal->GetBaseDomain(domain);
NS_ENSURE_SUCCESS(rv, rv);
nsOfflineCacheUpdateService::AllowedDomains()->PutEntry(domain);
}
else {
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager)
return NS_ERROR_NOT_AVAILABLE;
rv = permissionManager->AddFromPrincipal(
aPrincipal, "offline-app", nsIPermissionManager::ALLOW_ACTION,
nsIPermissionManager::EXPIRE_NEVER, 0);
if (NS_FAILED(rv))
return rv;
}
return NS_OK;
}