зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1777497, part 2 - Make "finalChecks" callback creation easier to use flexibly, r=anti-tracking-reviewers,pbz,timhuang
Depends on D151278 Differential Revision: https://phabricator.services.mozilla.com/D151279
This commit is contained in:
Родитель
64d2f3f974
Коммит
04fdece310
|
@ -16661,31 +16661,24 @@ Document::GetContentBlockingEvents() {
|
|||
});
|
||||
}
|
||||
|
||||
RefPtr<MozPromise<int, bool, true>> Document::RequestStorageAccessAsyncHelper(
|
||||
nsPIDOMWindowInner* aInnerWindow, BrowsingContext* aBrowsingContext,
|
||||
nsIPrincipal* aPrincipal, bool aHasUserInteraction,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aNotifier,
|
||||
bool requireFinalChecks) {
|
||||
if (!requireFinalChecks) {
|
||||
// Try to allow access for the given principal.
|
||||
return StorageAccessAPIHelper::AllowAccessFor(aPrincipal, aBrowsingContext,
|
||||
aNotifier);
|
||||
}
|
||||
|
||||
StorageAccessAPIHelper::PerformPermissionGrant
|
||||
Document::CreatePermissionGrantPromise(
|
||||
nsPIDOMWindowInner* aInnerWindow, nsIPrincipal* aPrincipal,
|
||||
bool aHasUserInteraction, const Maybe<nsCString>& aTopLevelBaseDomain) {
|
||||
MOZ_ASSERT(aInnerWindow);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
RefPtr<Document> self(this);
|
||||
RefPtr<nsPIDOMWindowInner> inner(aInnerWindow);
|
||||
RefPtr<nsIPrincipal> principal(aPrincipal);
|
||||
|
||||
// This is a lambda function that has some variables bound to it. It will be
|
||||
// called later in CompleteAllowAccessFor inside of AllowAccessFor.
|
||||
auto performFinalChecks = [inner, self, principal, aHasUserInteraction]() {
|
||||
return [inner, self, principal, aHasUserInteraction, aTopLevelBaseDomain]() {
|
||||
// Create the user prompt
|
||||
RefPtr<StorageAccessAPIHelper::StorageAccessFinalCheckPromise::Private> p =
|
||||
new StorageAccessAPIHelper::StorageAccessFinalCheckPromise::Private(
|
||||
__func__);
|
||||
RefPtr<StorageAccessAPIHelper::StorageAccessPermissionGrantPromise::Private>
|
||||
p = new StorageAccessAPIHelper::StorageAccessPermissionGrantPromise::
|
||||
Private(__func__);
|
||||
RefPtr<StorageAccessPermissionRequest> sapr =
|
||||
StorageAccessPermissionRequest::Create(
|
||||
inner, principal,
|
||||
inner, principal, aTopLevelBaseDomain,
|
||||
// Allow
|
||||
[p] {
|
||||
Telemetry::AccumulateCategorical(
|
||||
|
@ -16768,10 +16761,6 @@ RefPtr<MozPromise<int, bool, true>> Document::RequestStorageAccessAsyncHelper(
|
|||
|
||||
return p;
|
||||
};
|
||||
|
||||
// Try to allow access for the given principal.
|
||||
return StorageAccessAPIHelper::AllowAccessFor(principal, aBrowsingContext,
|
||||
aNotifier, performFinalChecks);
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
|
||||
|
@ -16906,9 +16895,9 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
|
|||
// perform an automatic decision or notify the user, then perform some follow
|
||||
// on work changing state to reflect the result of the API. If it resolves,
|
||||
// the request was granted. If it rejects it was denied.
|
||||
RequestStorageAccessAsyncHelper(inner, bc, NodePrincipal(), true,
|
||||
ContentBlockingNotifier::eStorageAccessAPI,
|
||||
true)
|
||||
StorageAccessAPIHelper::RequestStorageAccessAsyncHelper(
|
||||
this, inner, bc, NodePrincipal(), true,
|
||||
ContentBlockingNotifier::eStorageAccessAPI, true)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[self, inner, promise] {
|
||||
|
@ -17061,8 +17050,8 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccessForOrigin(
|
|||
// Step 4c: Try to request storage access, either automatically or
|
||||
// with a user-prompt. This is the part that is async in the
|
||||
// typical requestStorageAccess function.
|
||||
return self->RequestStorageAccessAsyncHelper(
|
||||
inner, bc, principal, hasUserActivation,
|
||||
return StorageAccessAPIHelper::RequestStorageAccessAsyncHelper(
|
||||
self, inner, bc, principal, hasUserActivation,
|
||||
ContentBlockingNotifier::ePrivilegeStorageAccessForOriginAPI,
|
||||
true);
|
||||
},
|
||||
|
@ -17170,6 +17159,8 @@ 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
|
||||
|
@ -17182,10 +17173,10 @@ already_AddRefed<Promise> Document::RequestStorageAccessUnderSite(
|
|||
cc->SendSetAllowStorageAccessRequestFlag(NodePrincipal(), siteURI)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise](bool success) {
|
||||
if (success) {
|
||||
promise->MaybeResolveWithUndefined();
|
||||
} else {
|
||||
[promise, principal, siteURI](int result) {
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
if (!cc) {
|
||||
// TODO(bug 1778561): Make this work in non-content processes.
|
||||
promise->MaybeRejectWithUndefined();
|
||||
}
|
||||
},
|
||||
|
@ -17330,8 +17321,8 @@ already_AddRefed<Promise> Document::CompleteStorageAccessRequestFromSite(
|
|||
// We ignore the final checks because this is where the "grant"
|
||||
// either by prompt doorhanger or autogrant takes place. We already
|
||||
// gathered an equivalent grant in requestStorageAccessUnderSite.
|
||||
return self->RequestStorageAccessAsyncHelper(
|
||||
inner, bc, principal, true,
|
||||
return StorageAccessAPIHelper::RequestStorageAccessAsyncHelper(
|
||||
self, inner, bc, principal, true,
|
||||
ContentBlockingNotifier::eStorageAccessAPI, false);
|
||||
},
|
||||
// If the IPC rejects, we should reject our promise here which will
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/SegmentedVector.h"
|
||||
#include "mozilla/StorageAccessAPIHelper.h"
|
||||
#include "mozilla/TaskCategory.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
@ -1260,16 +1261,10 @@ class Document : public nsINode,
|
|||
nsresult HasStorageAccessSync(bool& aHasStorageAccess);
|
||||
already_AddRefed<Promise> HasStorageAccess(ErrorResult& aRv);
|
||||
|
||||
// This function performs the asynchronous portion of checking if requests
|
||||
// for storage access will be sucessful or not. This includes creating a
|
||||
// permission prompt request and trying to perform an "autogrant"
|
||||
// This will return a promise whose values correspond to those of a
|
||||
// ContentBlocking::AllowAccessFor call that ends the funciton.
|
||||
RefPtr<MozPromise<int, bool, true>> RequestStorageAccessAsyncHelper(
|
||||
nsPIDOMWindowInner* aInnerWindow, BrowsingContext* aBrowsingContext,
|
||||
nsIPrincipal* aPrincipal, bool aHasUserInteraction,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aNotifier,
|
||||
bool performFinalChecks);
|
||||
StorageAccessAPIHelper::PerformPermissionGrant CreatePermissionGrantPromise(
|
||||
nsPIDOMWindowInner* aInnerWindow, nsIPrincipal* aPrincipal,
|
||||
bool aHasUserInteraction, const Maybe<nsCString>& aTopLevelBaseDomain);
|
||||
|
||||
already_AddRefed<Promise> RequestStorageAccess(ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> RequestStorageAccessForOrigin(
|
||||
|
|
|
@ -70,7 +70,7 @@ bool GetTopLevelWindowId(BrowsingContext* aParentContext, uint32_t aBehavior,
|
|||
StorageAccessAPIHelper::AllowAccessFor(
|
||||
nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
|
||||
const StorageAccessAPIHelper::PerformFinalChecks& aPerformFinalChecks) {
|
||||
const StorageAccessAPIHelper::PerformPermissionGrant& aPerformFinalChecks) {
|
||||
MOZ_ASSERT(aParentContext);
|
||||
|
||||
switch (aReason) {
|
||||
|
@ -289,7 +289,7 @@ StorageAccessAPIHelper::AllowAccessFor(
|
|||
}
|
||||
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
// Only support PerformFinalChecks when we run ::CompleteAllowAccessFor in
|
||||
// Only support PerformPermissionGrant when we run ::CompleteAllowAccessFor in
|
||||
// the same process. This callback is only used by eStorageAccessAPI,
|
||||
// which is always runned in the same process.
|
||||
MOZ_ASSERT(!aPerformFinalChecks);
|
||||
|
@ -361,7 +361,7 @@ StorageAccessAPIHelper::CompleteAllowAccessFor(
|
|||
nsIPrincipal* aTrackingPrincipal, const nsACString& aTrackingOrigin,
|
||||
uint32_t aCookieBehavior,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
|
||||
const PerformFinalChecks& aPerformFinalChecks) {
|
||||
const PerformPermissionGrant& aPerformFinalChecks) {
|
||||
MOZ_ASSERT(aParentContext);
|
||||
MOZ_ASSERT_IF(XRE_IsContentProcess(), aParentContext->IsInProcess());
|
||||
|
||||
|
@ -960,6 +960,34 @@ StorageAccessAPIHelper::CheckExistingPermissionDecidesStorageAccessAPI(
|
|||
return Nothing();
|
||||
}
|
||||
|
||||
// static
|
||||
RefPtr<StorageAccessAPIHelper::StorageAccessPermissionGrantPromise>
|
||||
StorageAccessAPIHelper::RequestStorageAccessAsyncHelper(
|
||||
dom::Document* aDocument, nsPIDOMWindowInner* aInnerWindow,
|
||||
dom::BrowsingContext* aBrowsingContext, nsIPrincipal* aPrincipal,
|
||||
bool aHasUserInteraction,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aNotifier,
|
||||
bool aRequireGrant) {
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
||||
if (!aRequireGrant) {
|
||||
// Try to allow access for the given principal.
|
||||
return StorageAccessAPIHelper::AllowAccessFor(aPrincipal, aBrowsingContext,
|
||||
aNotifier);
|
||||
}
|
||||
|
||||
RefPtr<nsIPrincipal> principal(aPrincipal);
|
||||
|
||||
// This is a lambda function that has some variables bound to it. It will be
|
||||
// called later in CompleteAllowAccessFor inside of AllowAccessFor.
|
||||
auto performPermissionGrant = aDocument->CreatePermissionGrantPromise(
|
||||
aInnerWindow, principal, aHasUserInteraction, Nothing());
|
||||
|
||||
// Try to allow access for the given principal.
|
||||
return StorageAccessAPIHelper::AllowAccessFor(principal, aBrowsingContext,
|
||||
aNotifier, performPermissionGrant);
|
||||
}
|
||||
|
||||
// There are two methods to handle permission update:
|
||||
// 1. UpdateAllowAccessOnCurrentProcess
|
||||
// 2. UpdateAllowAccessOnParentProcess
|
||||
|
|
|
@ -53,15 +53,14 @@ class StorageAccessAPIHelper final {
|
|||
// Ex: example.net import tracker.com/script.js which does opens a popup and
|
||||
// the user interacts with it. tracker.com is allowed when loaded by
|
||||
// example.net.
|
||||
typedef MozPromise<int, bool, true> StorageAccessFinalCheckPromise;
|
||||
typedef std::function<RefPtr<StorageAccessFinalCheckPromise>()>
|
||||
PerformFinalChecks;
|
||||
typedef MozPromise<int, bool, true> StorageAccessPermissionGrantPromise;
|
||||
typedef std::function<RefPtr<StorageAccessPermissionGrantPromise>()>
|
||||
PerformPermissionGrant;
|
||||
[[nodiscard]] static RefPtr<StorageAccessPermissionGrantPromise>
|
||||
AllowAccessFor(
|
||||
nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
|
||||
const PerformFinalChecks& aPerformFinalChecks = nullptr);
|
||||
const PerformPermissionGrant& aPerformFinalChecks = nullptr);
|
||||
|
||||
// This function handles tasks that have to be done in the process
|
||||
// of the window that we just grant permission for.
|
||||
|
@ -158,6 +157,19 @@ class StorageAccessAPIHelper final {
|
|||
static Maybe<bool> CheckExistingPermissionDecidesStorageAccessAPI(
|
||||
dom::Document* aDocument, bool aRequestingStorageAccess);
|
||||
|
||||
// This function performs the asynchronous portion of checking if requests
|
||||
// for storage access will be successful or not. This includes calling
|
||||
// Document member functions that creating a permission prompt request and
|
||||
// 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(
|
||||
dom::Document* aDocument, nsPIDOMWindowInner* aInnerWindow,
|
||||
dom::BrowsingContext* aBrowsingContext, nsIPrincipal* aPrincipal,
|
||||
bool aHasUserInteraction,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aNotifier,
|
||||
bool aRequireGrant);
|
||||
|
||||
private:
|
||||
friend class dom::ContentParent;
|
||||
// This should be running either in the parent process or in the child
|
||||
|
@ -168,7 +180,7 @@ class StorageAccessAPIHelper final {
|
|||
nsIPrincipal* aTrackingPrincipal, const nsACString& aTrackingOrigin,
|
||||
uint32_t aCookieBehavior,
|
||||
ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
|
||||
const PerformFinalChecks& aPerformFinalChecks = nullptr);
|
||||
const PerformPermissionGrant& aPerformFinalChecks = nullptr);
|
||||
|
||||
static void UpdateAllowAccessOnCurrentProcess(
|
||||
dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin);
|
||||
|
|
Загрузка…
Ссылка в новой задаче