diff --git a/dom/ipc/PWindowGlobal.ipdl b/dom/ipc/PWindowGlobal.ipdl index 74c186963597..207feae3329d 100644 --- a/dom/ipc/PWindowGlobal.ipdl +++ b/dom/ipc/PWindowGlobal.ipdl @@ -210,6 +210,8 @@ parent: async DiscoverIdentityCredentialFromExternalSource(IdentityCredentialRequestOptions aOptions) returns (IPCIdentityCredential? identityCredential); + async HasStorageAccessPermission() returns(bool granted); + child: async NotifyPermissionChange(nsCString type); }; diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp index 63823f5725e4..7e92f9ad5641 100644 --- a/dom/ipc/WindowGlobalParent.cpp +++ b/dom/ipc/WindowGlobalParent.cpp @@ -8,6 +8,7 @@ #include +#include "mozilla/AntiTrackingUtils.h" #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/ContentBlockingAllowList.h" @@ -1374,6 +1375,68 @@ IPCResult WindowGlobalParent::RecvDiscoverIdentityCredentialFromExternalSource( return IPC_OK(); } +IPCResult WindowGlobalParent::RecvHasStorageAccessPermission( + HasStorageAccessPermissionResolver&& aResolve) { + WindowGlobalParent* top = TopWindowContext(); + if (!top) { + return IPC_FAIL_NO_REASON(this); + } + nsIPrincipal* topPrincipal = top->DocumentPrincipal(); + nsIPrincipal* principal = DocumentPrincipal(); + + nsCOMPtr permMgr = + components::PermissionManager::Service(); + if (!permMgr) { + return IPC_FAIL( + this, + "Storage Access Permission: Failed to get Permission Manager service"); + } + + // Build the permission keys + nsAutoCString requestPermissionKey; + bool success = AntiTrackingUtils::CreateStoragePermissionKey( + principal, requestPermissionKey); + if (!success) { + return IPC_FAIL( + this, + "Storage Access Permission: Failed to create top level permission key"); + } + + nsAutoCString requestFramePermissionKey; + success = AntiTrackingUtils::CreateStorageFramePermissionKey( + principal, requestFramePermissionKey); + if (!success) { + return IPC_FAIL( + this, + "Storage Access Permission: Failed to create frame permission key"); + } + + // Test the permission + uint32_t access = nsIPermissionManager::UNKNOWN_ACTION; + nsresult rv = permMgr->TestPermissionFromPrincipal( + topPrincipal, requestPermissionKey, &access); + if (NS_WARN_IF(NS_FAILED(rv))) { + return IPC_FAIL(this, + "Storage Access Permission: Permission Manager failed to " + "test permission"); + } + if (access == nsIPermissionManager::ALLOW_ACTION) { + aResolve(true); + return IPC_OK(); + } + + uint32_t frameAccess = nsIPermissionManager::UNKNOWN_ACTION; + rv = permMgr->TestPermissionFromPrincipal( + topPrincipal, requestFramePermissionKey, &frameAccess); + if (NS_WARN_IF(NS_FAILED(rv))) { + return IPC_FAIL(this, + "Storage Access Permission: Permission Manager failed to " + "test permission"); + } + aResolve(frameAccess == nsIPermissionManager::ALLOW_ACTION); + return IPC_OK(); +} + void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) { if (GetBrowsingContext()->IsTopContent()) { Telemetry::Accumulate(Telemetry::ORB_DID_EVER_BLOCK_RESPONSE, diff --git a/dom/ipc/WindowGlobalParent.h b/dom/ipc/WindowGlobalParent.h index de96207d0cde..2327a177c104 100644 --- a/dom/ipc/WindowGlobalParent.h +++ b/dom/ipc/WindowGlobalParent.h @@ -310,6 +310,9 @@ class WindowGlobalParent final : public WindowContext, const IdentityCredentialRequestOptions& aOptions, const DiscoverIdentityCredentialFromExternalSourceResolver& aResolver); + mozilla::ipc::IPCResult RecvHasStorageAccessPermission( + HasStorageAccessPermissionResolver&& aResolve); + private: WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext, uint64_t aInnerWindowId, uint64_t aOuterWindowId,