mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 16:32:59 +00:00
Bug 1777497, part 3 - Require a grant (auto or manual) for the requestStorageAccessUnderSite permission, r=timhuang,pbz,anti-tracking-reviewers
Depends on D151279 Differential Revision: https://phabricator.services.mozilla.com/D151280
This commit is contained in:
parent
8484a990ab
commit
54d8159ea5
@ -282,6 +282,7 @@
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsDocShellLoadTypes.h"
|
||||
#include "nsEffectiveTLDService.h"
|
||||
#include "nsError.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsFocusManager.h"
|
||||
@ -17126,18 +17127,65 @@ already_AddRefed<Promise> Document::RequestStorageAccessUnderSite(
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal(NodePrincipal());
|
||||
|
||||
// Set a permission in the parent process that this document wants storage
|
||||
// access under the argument's site, resolving our returned promise on success
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
if (!cc) {
|
||||
// TODO(bug 1778561): Make this work in non-content processes.
|
||||
// Test if the permission this is requesting is already set
|
||||
nsCOMPtr<nsIPrincipal> argumentPrincipal =
|
||||
BasePrincipal::CreateContentPrincipal(
|
||||
siteURI, NodePrincipal()->OriginAttributesRef());
|
||||
if (!argumentPrincipal) {
|
||||
this->ConsumeTransientUserGestureActivation();
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
cc->SendSetAllowStorageAccessRequestFlag(NodePrincipal(), siteURI)
|
||||
nsCString originNoSuffix;
|
||||
rv = NodePrincipal()->GetOriginNoSuffix(originNoSuffix);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
MOZ_ASSERT(cc);
|
||||
RefPtr<Document> self(this);
|
||||
cc->SendTestStorageAccessPermission(IPC::Principal(argumentPrincipal),
|
||||
originNoSuffix)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise, siteURI,
|
||||
self](const ContentChild::TestStorageAccessPermissionPromise::
|
||||
ResolveValueType& aResult) {
|
||||
if (aResult) {
|
||||
return StorageAccessAPIHelper::
|
||||
StorageAccessPermissionGrantPromise::CreateAndResolve(
|
||||
StorageAccessAPIHelper::eAllow, __func__);
|
||||
}
|
||||
// Get a grant for the storage access permission that will be set
|
||||
// when this is completed in the embedding context
|
||||
nsCString serializedSite;
|
||||
RefPtr<nsEffectiveTLDService> etld =
|
||||
nsEffectiveTLDService::GetInstance();
|
||||
if (!etld) {
|
||||
return StorageAccessAPIHelper::
|
||||
StorageAccessPermissionGrantPromise::CreateAndReject(
|
||||
false, __func__);
|
||||
}
|
||||
nsresult rv = etld->GetSite(siteURI, serializedSite);
|
||||
if (NS_FAILED(rv)) {
|
||||
return StorageAccessAPIHelper::
|
||||
StorageAccessPermissionGrantPromise::CreateAndReject(
|
||||
false, __func__);
|
||||
}
|
||||
return self->CreatePermissionGrantPromise(
|
||||
self->GetInnerWindow(), self->NodePrincipal(), true,
|
||||
Some(serializedSite))();
|
||||
},
|
||||
[](const ContentChild::TestStorageAccessPermissionPromise::
|
||||
RejectValueType& aResult) {
|
||||
return StorageAccessAPIHelper::StorageAccessPermissionGrantPromise::
|
||||
CreateAndReject(false, __func__);
|
||||
})
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise, principal, siteURI](int result) {
|
||||
@ -17145,11 +17193,26 @@ already_AddRefed<Promise> Document::RequestStorageAccessUnderSite(
|
||||
if (!cc) {
|
||||
// TODO(bug 1778561): Make this work in non-content processes.
|
||||
promise->MaybeRejectWithUndefined();
|
||||
return;
|
||||
}
|
||||
// Set a permission in the parent process that this document wants
|
||||
// storage access under the argument's site, resolving our returned
|
||||
// promise on success
|
||||
cc->SendSetAllowStorageAccessRequestFlag(principal, siteURI)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise](bool success) {
|
||||
if (success) {
|
||||
promise->MaybeResolveWithUndefined();
|
||||
} else {
|
||||
promise->MaybeRejectWithUndefined();
|
||||
}
|
||||
},
|
||||
[promise](mozilla::ipc::ResponseRejectReason reason) {
|
||||
promise->MaybeRejectWithUndefined();
|
||||
});
|
||||
},
|
||||
[promise](mozilla::ipc::ResponseRejectReason reason) {
|
||||
promise->MaybeRejectWithUndefined();
|
||||
});
|
||||
[promise](bool result) { promise->MaybeRejectWithUndefined(); });
|
||||
|
||||
// Return the promise that is resolved in the async handler above
|
||||
return promise.forget();
|
||||
|
@ -6752,6 +6752,38 @@ mozilla::ipc::IPCResult ContentParent::RecvTestCookiePermissionDecided(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvTestStorageAccessPermission(
|
||||
const Principal& aEmbeddingPrincipal, const nsCString& aEmbeddedOrigin,
|
||||
const TestStorageAccessPermissionResolver&& aResolver) {
|
||||
// Get the permission manager and build the key.
|
||||
RefPtr<PermissionManager> permManager = PermissionManager::GetInstance();
|
||||
if (!permManager) {
|
||||
aResolver(Nothing());
|
||||
return IPC_OK();
|
||||
}
|
||||
nsCString requestPermissionKey;
|
||||
AntiTrackingUtils::CreateStoragePermissionKey(aEmbeddedOrigin,
|
||||
requestPermissionKey);
|
||||
|
||||
// Test the permission
|
||||
uint32_t access = nsIPermissionManager::UNKNOWN_ACTION;
|
||||
nsresult rv = permManager->TestPermissionFromPrincipal(
|
||||
aEmbeddingPrincipal, requestPermissionKey, &access);
|
||||
if (NS_FAILED(rv)) {
|
||||
aResolver(Nothing());
|
||||
return IPC_OK();
|
||||
}
|
||||
if (access == nsIPermissionManager::ALLOW_ACTION) {
|
||||
aResolver(Some(true));
|
||||
} else if (access == nsIPermissionManager::DENY_ACTION) {
|
||||
aResolver(Some(false));
|
||||
} else {
|
||||
aResolver(Nothing());
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvNotifyMediaPlaybackChanged(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
MediaPlaybackState aState) {
|
||||
|
@ -1274,6 +1274,10 @@ class ContentParent final : public PContentParent,
|
||||
const MaybeDiscarded<BrowsingContext>& aContext, nsIPrincipal* aPrincipal,
|
||||
const TestCookiePermissionDecidedResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvTestStorageAccessPermission(
|
||||
const Principal& aEmbeddingPrincipal, const nsCString& aEmbeddedOrigin,
|
||||
const TestStorageAccessPermissionResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotifyMediaPlaybackChanged(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
MediaPlaybackState aState);
|
||||
|
@ -1669,6 +1669,10 @@ parent:
|
||||
nsIPrincipal aPrincipal)
|
||||
returns (bool? allowed);
|
||||
|
||||
async TestStorageAccessPermission(Principal aEmbeddingPrincipal,
|
||||
nsCString aEmbeddedOrigin)
|
||||
returns (bool? allowed);
|
||||
|
||||
/**
|
||||
* When media element's controlled state changed in the content process, we
|
||||
* have to notify the chrome process in order to update the status of the
|
||||
|
@ -984,8 +984,8 @@ StorageAccessAPIHelper::RequestStorageAccessAsyncHelper(
|
||||
aInnerWindow, principal, aHasUserInteraction, Nothing());
|
||||
|
||||
// Try to allow access for the given principal.
|
||||
return StorageAccessAPIHelper::AllowAccessFor(principal, aBrowsingContext,
|
||||
aNotifier, performPermissionGrant);
|
||||
return StorageAccessAPIHelper::AllowAccessFor(
|
||||
principal, aBrowsingContext, aNotifier, performPermissionGrant);
|
||||
}
|
||||
|
||||
// There are two methods to handle permission update:
|
||||
|
@ -163,7 +163,8 @@ class StorageAccessAPIHelper final {
|
||||
// trying to perform an "autogrant" if aRequireGrant is true.
|
||||
// This will return a promise whose values correspond to those of a
|
||||
// ContentBlocking::AllowAccessFor call that ends the function.
|
||||
static RefPtr<StorageAccessPermissionGrantPromise> RequestStorageAccessAsyncHelper(
|
||||
static RefPtr<StorageAccessPermissionGrantPromise>
|
||||
RequestStorageAccessAsyncHelper(
|
||||
dom::Document* aDocument, nsPIDOMWindowInner* aInnerWindow,
|
||||
dom::BrowsingContext* aBrowsingContext, nsIPrincipal* aPrincipal,
|
||||
bool aHasUserInteraction,
|
||||
|
Loading…
Reference in New Issue
Block a user