diff --git a/dom/indexedDB/ActorsChild.cpp b/dom/indexedDB/ActorsChild.cpp index 62479d8ea75e..977b2427f2e5 100644 --- a/dom/indexedDB/ActorsChild.cpp +++ b/dom/indexedDB/ActorsChild.cpp @@ -52,7 +52,6 @@ #include "nsPIDOMWindow.h" #include "nsThreadUtils.h" #include "nsTraceRefcnt.h" -#include "PermissionRequestBase.h" #include "ProfilerHelpers.h" #include "ReportInternalError.h" #include "ThreadLocal.h" @@ -328,30 +327,6 @@ nsresult GetResult(JSContext* aCx, const nsTArray* aKeys, } } // namespace detail -class PermissionRequestMainProcessHelper final : public PermissionRequestBase { - BackgroundFactoryRequestChild* mActor; - SafeRefPtr mFactory; - - public: - PermissionRequestMainProcessHelper(BackgroundFactoryRequestChild* aActor, - SafeRefPtr aFactory, - Element* aOwnerElement, - nsIPrincipal* aPrincipal) - : PermissionRequestBase(aOwnerElement, aPrincipal), - mActor(aActor), - mFactory(std::move(aFactory)) { - MOZ_ASSERT(aActor); - MOZ_ASSERT(mFactory); - aActor->AssertIsOnOwningThread(); - } - - protected: - ~PermissionRequestMainProcessHelper() = default; - - private: - virtual void OnPromptComplete(PermissionValue aPermissionValue) override; -}; - auto DeserializeStructuredCloneFiles( IDBDatabase* aDatabase, const nsTArray& aSerializedFiles, @@ -654,178 +629,6 @@ PRFileDesc* GetFileDescriptorFromStream(nsIInputStream* aStream) { return fileDesc; } -class WorkerPermissionChallenge; - -// This class calles WorkerPermissionChallenge::OperationCompleted() in the -// worker thread. -class WorkerPermissionOperationCompleted final : public WorkerControlRunnable { - RefPtr mChallenge; - - public: - WorkerPermissionOperationCompleted(WorkerPrivate* aWorkerPrivate, - WorkerPermissionChallenge* aChallenge) - : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount), - mChallenge(aChallenge) { - MOZ_ASSERT(NS_IsMainThread()); - } - - virtual bool WorkerRun(JSContext* aCx, - WorkerPrivate* aWorkerPrivate) override; -}; - -// This class used to do prompting in the main thread and main process. -class WorkerPermissionRequest final : public PermissionRequestBase { - RefPtr mChallenge; - - public: - WorkerPermissionRequest(Element* aElement, nsIPrincipal* aPrincipal, - WorkerPermissionChallenge* aChallenge) - : PermissionRequestBase(aElement, aPrincipal), mChallenge(aChallenge) { - MOZ_ASSERT(XRE_IsParentProcess()); - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aChallenge); - } - - private: - ~WorkerPermissionRequest() { MOZ_ASSERT(NS_IsMainThread()); } - - virtual void OnPromptComplete(PermissionValue aPermissionValue) override; -}; - -class WorkerPermissionChallenge final : public Runnable { - public: - WorkerPermissionChallenge(WorkerPrivate* aWorkerPrivate, - BackgroundFactoryRequestChild* aActor, - SafeRefPtr aFactory, - PrincipalInfo&& aPrincipalInfo) - : Runnable("indexedDB::WorkerPermissionChallenge"), - mWorkerPrivate(aWorkerPrivate), - mActor(aActor), - mFactory(std::move(aFactory)), - mPrincipalInfo(std::move(aPrincipalInfo)) { - MOZ_ASSERT(mWorkerPrivate); - MOZ_ASSERT(aActor); - MOZ_ASSERT(mFactory); - mWorkerPrivate->AssertIsOnWorkerThread(); - } - - bool Dispatch() { - mWorkerPrivate->AssertIsOnWorkerThread(); - if (NS_WARN_IF(!mWorkerPrivate->ModifyBusyCountFromWorker(true))) { - return false; - } - - if (NS_WARN_IF(NS_FAILED(mWorkerPrivate->DispatchToMainThread(this)))) { - mWorkerPrivate->ModifyBusyCountFromWorker(false); - return false; - } - - return true; - } - - NS_IMETHOD - Run() override { - const bool completed = RunInternal(); - if (completed) { - OperationCompleted(); - } - - return NS_OK; - } - - void OperationCompleted() { - if (NS_IsMainThread()) { - const RefPtr runnable = - new WorkerPermissionOperationCompleted(mWorkerPrivate, this); - - MOZ_ALWAYS_TRUE(runnable->Dispatch()); - return; - } - - MOZ_ASSERT(mActor); - mActor->AssertIsOnOwningThread(); - - MaybeCollectGarbageOnIPCMessage(); - - const SafeRefPtr factory = std::move(mFactory); - Unused << factory; // XXX see Bug 1605075 - - mActor->SendPermissionRetry(); - mActor = nullptr; - - mWorkerPrivate->AssertIsOnWorkerThread(); - mWorkerPrivate->ModifyBusyCountFromWorker(false); - } - - private: - bool RunInternal() { - MOZ_ASSERT(NS_IsMainThread()); - - // Walk up to our containing page - WorkerPrivate* wp = mWorkerPrivate; - while (wp->GetParent()) { - wp = wp->GetParent(); - } - - nsPIDOMWindowInner* const window = wp->GetWindow(); - if (!window) { - return true; - } - - QM_TRY_UNWRAP(auto principal, - mozilla::ipc::PrincipalInfoToPrincipal(mPrincipalInfo), true); - - if (XRE_IsParentProcess()) { - const nsCOMPtr ownerElement = - do_QueryInterface(window->GetChromeEventHandler()); - if (NS_WARN_IF(!ownerElement)) { - return true; - } - - RefPtr helper = - new WorkerPermissionRequest(ownerElement, principal, this); - - QM_TRY_INSPECT(const PermissionRequestBase::PermissionValue& permission, - helper->PromptIfNeeded(), true); - - MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed || - permission == PermissionRequestBase::kPermissionDenied || - permission == PermissionRequestBase::kPermissionPrompt); - - return permission != PermissionRequestBase::kPermissionPrompt; - } - - BrowserChild* browserChild = BrowserChild::GetFrom(window); - MOZ_ASSERT(browserChild); - - RefPtr self(this); - browserChild->SendIndexedDBPermissionRequest(principal)->Then( - GetCurrentSerialEventTarget(), __func__, - [self](const uint32_t& aPermission) { self->OperationCompleted(); }, - [](const mozilla::ipc::ResponseRejectReason) {}); - return false; - } - - private: - WorkerPrivate* const mWorkerPrivate; - BackgroundFactoryRequestChild* mActor; - SafeRefPtr mFactory; - const PrincipalInfo mPrincipalInfo; -}; - -void WorkerPermissionRequest::OnPromptComplete( - PermissionValue aPermissionValue) { - MOZ_ASSERT(NS_IsMainThread()); - mChallenge->OperationCompleted(); -} - -bool WorkerPermissionOperationCompleted::WorkerRun( - JSContext* aCx, WorkerPrivate* aWorkerPrivate) { - aWorkerPrivate->AssertIsOnWorkerThread(); - mChallenge->OperationCompleted(); - return true; -} - class MOZ_STACK_CLASS AutoSetCurrentFileHandle final { using BackgroundChildImpl = mozilla::ipc::BackgroundChildImpl; @@ -1138,23 +941,6 @@ class BackgroundRequestChild::PreprocessHelper final NS_DECL_NSIFILEMETADATACALLBACK }; -/******************************************************************************* - * Local class implementations - ******************************************************************************/ - -void PermissionRequestMainProcessHelper::OnPromptComplete( - PermissionValue aPermissionValue) { - MOZ_ASSERT(mActor); - mActor->AssertIsOnOwningThread(); - - MaybeCollectGarbageOnIPCMessage(); - - mActor->SendPermissionRetry(); - - mActor = nullptr; - mFactory = nullptr; -} - /******************************************************************************* * BackgroundRequestChildBase ******************************************************************************/ @@ -1425,76 +1211,6 @@ mozilla::ipc::IPCResult BackgroundFactoryRequestChild::Recv__delete__( return IPC_OK(); } -mozilla::ipc::IPCResult BackgroundFactoryRequestChild::RecvPermissionChallenge( - PrincipalInfo&& aPrincipalInfo) { - AssertIsOnOwningThread(); - - MaybeCollectGarbageOnIPCMessage(); - - if (!NS_IsMainThread()) { - WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); - MOZ_ASSERT(workerPrivate); - workerPrivate->AssertIsOnWorkerThread(); - - RefPtr challenge = new WorkerPermissionChallenge( - workerPrivate, this, mFactory.clonePtr(), std::move(aPrincipalInfo)); - if (!challenge->Dispatch()) { - QM_WARNONLY_TRY(OkIf(SendPermissionRetry())); - } - return IPC_OK(); - } - - QM_TRY_UNWRAP(auto principal, - mozilla::ipc::PrincipalInfoToPrincipal(aPrincipalInfo), - IPC_FAIL(this, "PrincipalInfoToPrincipal failed!")); - - if (XRE_IsParentProcess()) { - nsCOMPtr global = mFactory->GetParentObject(); - nsCOMPtr window = do_QueryInterface(global); - MOZ_ASSERT(window); - - nsCOMPtr ownerElement = - do_QueryInterface(window->GetChromeEventHandler()); - if (NS_WARN_IF(!ownerElement)) { - // If this fails, the page was navigated. Fail the permission check by - // forcing an immediate retry. - QM_WARNONLY_TRY(OkIf(SendPermissionRetry())); - return IPC_OK(); - } - - RefPtr helper = - new PermissionRequestMainProcessHelper(this, mFactory.clonePtr(), - ownerElement, principal); - - QM_TRY_INSPECT(const PermissionRequestBase::PermissionValue& permission, - helper->PromptIfNeeded(), - IPC_FAIL(this, "PromptIfNeeded failed!")); - - MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed || - permission == PermissionRequestBase::kPermissionDenied || - permission == PermissionRequestBase::kPermissionPrompt); - - if (permission != PermissionRequestBase::kPermissionPrompt) { - SendPermissionRetry(); - } - return IPC_OK(); - } - - RefPtr browserChild = mFactory->GetBrowserChild(); - MOZ_ASSERT(browserChild); - - browserChild->SendIndexedDBPermissionRequest(principal)->Then( - GetCurrentSerialEventTarget(), __func__, - [this](const uint32_t& aPermission) { - this->AssertIsOnOwningThread(); - MaybeCollectGarbageOnIPCMessage(); - this->SendPermissionRetry(); - }, - [](const mozilla::ipc::ResponseRejectReason) {}); - - return IPC_OK(); -} - mozilla::ipc::IPCResult BackgroundFactoryRequestChild::RecvBlocked( const uint64_t aCurrentVersion) { AssertIsOnOwningThread(); diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 053ed12d61b0..5263459687db 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -34,7 +34,6 @@ #include "IndexedDatabaseManager.h" #include "KeyPath.h" #include "MainThreadUtils.h" -#include "PermissionRequestBase.h" #include "ProfilerHelpers.h" #include "ReportInternalError.h" #include "SafeRefPtr.h" @@ -3106,15 +3105,6 @@ class FactoryOp // if permission is granted. Initial, - // Sending a permission challenge message to the child on the PBackground - // thread. Next step is PermissionRetry. - PermissionChallenge, - - // Retrying permission check after a challenge on the main thread. Next step - // is either SendingResults if permission is denied or FinishOpen - // if permission is granted. - PermissionRetry, - // Ensuring quota manager is created and opening directory on the // PBackground thread. Next step is either SendingResults if quota manager // is not available or DirectoryOpenPending if quota manager is available. @@ -3236,12 +3226,6 @@ class FactoryOp nsresult Open(); - nsresult ChallengePermission(); - - void PermissionRetry(); - - nsresult RetryCheckPermission(); - nsresult DirectoryOpen(); nsresult SendToIOThread(); @@ -3287,13 +3271,11 @@ class FactoryOp // IPDL methods. void ActorDestroy(ActorDestroyReason aWhy) override; - mozilla::ipc::IPCResult RecvPermissionRetry() final; - virtual void SendBlockedNotification() = 0; private: - mozilla::Result - CheckPermission(ContentParent* aContentParent); + mozilla::Result CheckPermission( + ContentParent* aContentParent); static bool CheckAtLeastOneAppHasPermission( ContentParent* aContentParent, const nsACString& aPermissionString); @@ -15126,14 +15108,6 @@ void FactoryOp::StringifyState(nsACString& aResult) const { aResult.AppendLiteral("Initial"); return; - case State::PermissionChallenge: - aResult.AppendLiteral("PermissionChallenge"); - return; - - case State::PermissionRetry: - aResult.AppendLiteral("PermissionRetry"); - return; - case State::FinishOpen: aResult.AppendLiteral("FinishOpen"); return; @@ -15210,11 +15184,10 @@ nsresult FactoryOp::Open() { QM_TRY_INSPECT(const auto& permission, CheckPermission(contentParent)); - MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed || - permission == PermissionRequestBase::kPermissionDenied || - permission == PermissionRequestBase::kPermissionPrompt); + MOZ_ASSERT(permission == PermissionValue::kPermissionAllowed || + permission == PermissionValue::kPermissionDenied); - if (permission == PermissionRequestBase::kPermissionDenied) { + if (permission == PermissionValue::kPermissionDenied) { return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR; } @@ -15242,13 +15215,7 @@ nsresult FactoryOp::Open() { mDatabaseId.Append('*'); mDatabaseId.Append(NS_ConvertUTF16toUTF8(metadata.name())); - if (permission == PermissionRequestBase::kPermissionPrompt) { - mState = State::PermissionChallenge; - MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget->Dispatch(this, NS_DISPATCH_NORMAL)); - return NS_OK; - } - - MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed); + MOZ_ASSERT(permission == PermissionValue::kPermissionAllowed); if (mInPrivateBrowsing) { const auto lockedPrivateBrowsingInfoHashtable = @@ -15275,69 +15242,6 @@ nsresult FactoryOp::Open() { return NS_OK; } -nsresult FactoryOp::ChallengePermission() { - AssertIsOnOwningThread(); - MOZ_ASSERT(mState == State::PermissionChallenge); - - const PrincipalInfo& principalInfo = mCommonParams.principalInfo(); - MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo); - - if (NS_WARN_IF(!SendPermissionChallenge(principalInfo))) { - return NS_ERROR_FAILURE; - } - - mWaitingForPermissionRetry = true; - - return NS_OK; -} - -void FactoryOp::PermissionRetry() { - AssertIsOnOwningThread(); - MOZ_ASSERT(mState == State::PermissionChallenge); - - mContentParent = BackgroundParent::GetContentParent(Manager()->Manager()); - - mState = State::PermissionRetry; - - mWaitingForPermissionRetry = false; - - MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(this)); -} - -nsresult FactoryOp::RetryCheckPermission() { - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mState == State::PermissionRetry); - MOZ_ASSERT(mCommonParams.principalInfo().type() == - PrincipalInfo::TContentPrincipalInfo); - - // Move this to the stack now to ensure that we release it on this thread. - const RefPtr contentParent = std::move(mContentParent); - - if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) || - !OperationMayProceed()) { - IDB_REPORT_INTERNAL_ERR(); - return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; - } - - QM_TRY_INSPECT(const auto& permission, CheckPermission(contentParent)); - - MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed || - permission == PermissionRequestBase::kPermissionDenied || - permission == PermissionRequestBase::kPermissionPrompt); - - if (permission == PermissionRequestBase::kPermissionDenied || - permission == PermissionRequestBase::kPermissionPrompt) { - return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR; - } - - MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed); - - mState = State::FinishOpen; - MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget->Dispatch(this, NS_DISPATCH_NORMAL)); - - return NS_OK; -} - nsresult FactoryOp::DirectoryOpen() { AssertIsOnOwningThread(); MOZ_ASSERT(mState == State::DirectoryOpenPending); @@ -15456,10 +15360,10 @@ void FactoryOp::FinishSendResults() { mFactory = nullptr; } -Result -FactoryOp::CheckPermission(ContentParent* aContentParent) { +Result FactoryOp::CheckPermission( + ContentParent* aContentParent) { MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mState == State::Initial || mState == State::PermissionRetry); + MOZ_ASSERT(mState == State::Initial); const PrincipalInfo& principalInfo = mCommonParams.principalInfo(); if (principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) { @@ -15545,7 +15449,7 @@ FactoryOp::CheckPermission(ContentParent* aContentParent) { mEnforcingQuota = false; } - return PermissionRequestBase::kPermissionAllowed; + return PermissionValue::kPermissionAllowed; } MOZ_ASSERT(principalInfo.type() == PrincipalInfo::TContentPrincipalInfo); @@ -15556,26 +15460,21 @@ FactoryOp::CheckPermission(ContentParent* aContentParent) { QM_TRY_UNWRAP(auto principalMetadata, QuotaManager::GetInfoFromPrincipal(principal)); - QM_TRY_INSPECT(const auto& permission, - ([persistenceType, &origin = principalMetadata.mOrigin, - &principal = *principal]() - -> mozilla::Result { - if (persistenceType == PERSISTENCE_TYPE_PERSISTENT) { - if (QuotaManager::IsOriginInternal(origin)) { - return PermissionRequestBase::kPermissionAllowed; - } -#ifdef IDB_MOBILE - return Err(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR); -#else - return PermissionRequestBase::GetCurrentPermission( - principal); -#endif - } - return PermissionRequestBase::kPermissionAllowed; - })()); + QM_TRY_INSPECT( + const auto& permission, + ([persistenceType, &origin = principalMetadata.mOrigin, + &principal = + *principal]() -> mozilla::Result { + if (persistenceType == PERSISTENCE_TYPE_PERSISTENT) { + if (QuotaManager::IsOriginInternal(origin)) { + return PermissionValue::kPermissionAllowed; + } + return Err(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR); + } + return PermissionValue::kPermissionAllowed; + })()); - if (permission != PermissionRequestBase::kPermissionDenied && + if (permission != PermissionValue::kPermissionDenied && State::Initial == mState) { mOriginMetadata = {std::move(principalMetadata), persistenceType}; @@ -15730,14 +15629,6 @@ FactoryOp::Run() { QM_TRY(MOZ_TO_RESULT(Open()), NS_OK, handleError); break; - case State::PermissionChallenge: - QM_TRY(MOZ_TO_RESULT(ChallengePermission()), NS_OK, handleError); - break; - - case State::PermissionRetry: - QM_TRY(MOZ_TO_RESULT(RetryCheckPermission()), NS_OK, handleError); - break; - case State::FinishOpen: QM_TRY(MOZ_TO_RESULT(FinishOpen()), NS_OK, handleError); break; @@ -15812,32 +15703,6 @@ void FactoryOp::ActorDestroy(ActorDestroyReason aWhy) { AssertIsOnBackgroundThread(); NoteActorDestroyed(); - - // Assume ActorDestroy can happen at any time, so we can't probe the current - // state since mState can be modified on any thread (only one thread at a time - // based on the state machine). However we can use mWaitingForPermissionRetry - // which is only touched on the owning thread. If mWaitingForPermissionRetry - // is true, we can also modify mState since we are guaranteed that there are - // no pending runnables which would probe mState to decide what code needs to - // run (there shouldn't be any running runnables on other threads either). - - if (mWaitingForPermissionRetry) { - PermissionRetry(); - } - - // We don't have to handle the case when mWaitingForPermissionRetry is not - // true since it means that either nothing has been initialized yet, so - // nothing to cleanup or there are pending runnables that will detect that the - // actor has been destroyed and cleanup accordingly. -} - -mozilla::ipc::IPCResult FactoryOp::RecvPermissionRetry() { - AssertIsOnOwningThread(); - MOZ_ASSERT(!IsActorDestroyed()); - - PermissionRetry(); - - return IPC_OK(); } OpenDatabaseOp::OpenDatabaseOp(SafeRefPtr aFactory, @@ -21475,13 +21340,6 @@ mozilla::ipc::IPCResult Utils::RecvGetFileReferences( return IPC_OK(); } -void PermissionRequestHelper::OnPromptComplete( - PermissionValue aPermissionValue) { - MOZ_ASSERT(NS_IsMainThread()); - - mResolver(aPermissionValue); -} - #ifdef DEBUG NS_IMPL_ISUPPORTS(DEBUGThreadSlower, nsIThreadObserver) diff --git a/dom/indexedDB/ActorsParent.h b/dom/indexedDB/ActorsParent.h index 40cca245b7a4..ab6c6c142ff7 100644 --- a/dom/indexedDB/ActorsParent.h +++ b/dom/indexedDB/ActorsParent.h @@ -8,9 +8,9 @@ #define mozilla_dom_indexeddb_actorsparent_h__ #include "mozilla/AlreadyAddRefed.h" -#include "mozilla/dom/indexedDB/PermissionRequestBase.h" #include "mozilla/dom/PBrowserParent.h" #include "mozilla/RefPtr.h" +#include "nsIPermissionManager.h" class nsIPrincipal; @@ -27,6 +27,12 @@ class Client; namespace indexedDB { +enum class PermissionValue { + kPermissionAllowed = nsIPermissionManager::ALLOW_ACTION, + kPermissionDenied = nsIPermissionManager::DENY_ACTION, + kPermissionPrompt = nsIPermissionManager::PROMPT_ACTION +}; + class LoggingInfo; class PBackgroundIDBFactoryParent; class PBackgroundIndexedDBUtilsParent; @@ -50,23 +56,6 @@ RefPtr CreateQuotaClient(); FileHandleThreadPool* GetFileHandleThreadPool(); -class PermissionRequestHelper final : public PermissionRequestBase { - public: - PermissionRequestHelper( - Element* aOwnerElement, nsIPrincipal* aPrincipal, - PBrowserParent::IndexedDBPermissionRequestResolver& aResolver) - : PermissionRequestBase(aOwnerElement, aPrincipal), - mResolver(aResolver) {} - - protected: - ~PermissionRequestHelper() override = default; - - private: - PBrowserParent::IndexedDBPermissionRequestResolver mResolver; - - void OnPromptComplete(PermissionValue aPermissionValue) override; -}; - } // namespace indexedDB } // namespace mozilla::dom diff --git a/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl b/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl index 42714671c86d..d85e7741b514 100644 --- a/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl +++ b/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl @@ -38,12 +38,7 @@ protocol PBackgroundIDBFactoryRequest child: async __delete__(FactoryRequestResponse response); - async PermissionChallenge(PrincipalInfo principalInfo); - async Blocked(uint64_t currentVersion); - -parent: - async PermissionRetry(); }; } // namespace indexedDB diff --git a/dom/indexedDB/PermissionRequestBase.cpp b/dom/indexedDB/PermissionRequestBase.cpp deleted file mode 100644 index a6e37df0e242..000000000000 --- a/dom/indexedDB/PermissionRequestBase.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PermissionRequestBase.h" - -#include "IndexedDBCommon.h" - -#include "MainThreadUtils.h" -#include "mozilla/Assertions.h" -#include "mozilla/Services.h" -#include "mozilla/dom/Element.h" -#include "mozilla/dom/quota/ResultExtensions.h" -#include "nsIObserverService.h" -#include "nsIPrincipal.h" -#include "nsXULAppAPI.h" - -namespace mozilla::dom::indexedDB { - -using namespace mozilla::services; - -namespace { - -#define IDB_PREFIX "indexedDB" -#define TOPIC_PREFIX IDB_PREFIX "-permissions-" - -const nsLiteralCString kPermissionString = nsLiteralCString(IDB_PREFIX); - -const char kPermissionPromptTopic[] = TOPIC_PREFIX "prompt"; - -#ifdef DEBUG -const char kPermissionResponseTopic[] = TOPIC_PREFIX "response"; -#endif - -#undef TOPIC_PREFIX -#undef IDB_PREFIX - -const uint32_t kPermissionDefault = nsIPermissionManager::UNKNOWN_ACTION; - -void AssertSanity() { - MOZ_ASSERT(XRE_IsParentProcess()); - MOZ_ASSERT(NS_IsMainThread()); -} - -} // namespace - -PermissionRequestBase::PermissionRequestBase(Element* aOwnerElement, - nsIPrincipal* aPrincipal) - : mOwnerElement(aOwnerElement), mPrincipal(aPrincipal) { - AssertSanity(); - MOZ_ASSERT(aOwnerElement); - MOZ_ASSERT(aPrincipal); -} - -PermissionRequestBase::~PermissionRequestBase() { AssertSanity(); } - -// static -Result -PermissionRequestBase::GetCurrentPermission(nsIPrincipal& aPrincipal) { - AssertSanity(); - - const nsCOMPtr permMan = GetPermissionManager(); - QM_TRY(OkIf(permMan), Err(NS_ERROR_FAILURE)); - - QM_TRY_INSPECT( - const uint32_t& intPermission, - MOZ_TO_RESULT_INVOKE_MEMBER(permMan, TestExactPermissionFromPrincipal, - &aPrincipal, kPermissionString)); - - const PermissionValue permission = - PermissionValueForIntPermission(intPermission); - - MOZ_ASSERT(permission == kPermissionAllowed || - permission == kPermissionDenied || - permission == kPermissionPrompt); - - return permission; -} - -// static -auto PermissionRequestBase::PermissionValueForIntPermission( - uint32_t aIntPermission) -> PermissionValue { - AssertSanity(); - - switch (aIntPermission) { - case kPermissionDefault: - return kPermissionPrompt; - case kPermissionAllowed: - return kPermissionAllowed; - case kPermissionDenied: - return kPermissionDenied; - default: - MOZ_CRASH("Bad permission!"); - } - - MOZ_CRASH("Should never get here!"); -} - -Result -PermissionRequestBase::PromptIfNeeded() { - AssertSanity(); - MOZ_ASSERT(mPrincipal); - - // Tricky, we want to release the window and principal in all cases except - // when we successfully prompt. - nsCOMPtr element = std::move(mOwnerElement); - nsCOMPtr principal = std::move(mPrincipal); - - QM_TRY_INSPECT(const PermissionValue& currentValue, - GetCurrentPermission(*principal)); - MOZ_ASSERT(currentValue != kPermissionDefault); - - if (currentValue == kPermissionPrompt) { - nsCOMPtr obsSvc = GetObserverService(); - QM_TRY(OkIf(obsSvc), Err(NS_ERROR_FAILURE)); - - // We're about to prompt so move the members back. - mOwnerElement = std::move(element); - mPrincipal = std::move(principal); - - QM_TRY( - MOZ_TO_RESULT(obsSvc->NotifyObservers(static_cast(this), - kPermissionPromptTopic, nullptr)), - QM_PROPAGATE, [this](const auto&) { - // Finally release if we failed the prompt. - mOwnerElement = nullptr; - mPrincipal = nullptr; - }); - } - - return currentValue; -} - -void PermissionRequestBase::SetExplicitPermission(nsIPrincipal* aPrincipal, - uint32_t aIntPermission) { - AssertSanity(); - MOZ_ASSERT(aPrincipal); - MOZ_ASSERT(aIntPermission == kPermissionAllowed || - aIntPermission == kPermissionDenied); - - nsCOMPtr permMan = GetPermissionManager(); - if (NS_WARN_IF(!permMan)) { - return; - } - - nsresult rv = - permMan->AddFromPrincipal(aPrincipal, kPermissionString, aIntPermission, - nsIPermissionManager::EXPIRE_NEVER, - /* aExpireTime */ 0); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } -} - -NS_IMPL_ISUPPORTS(PermissionRequestBase, nsIObserver, nsIIDBPermissionsRequest) - -NS_IMETHODIMP -PermissionRequestBase::GetBrowserElement(Element** aElement) { - AssertSanity(); - *aElement = do_AddRef(mOwnerElement).take(); - return NS_OK; -} - -NS_IMETHODIMP -PermissionRequestBase::GetResponseObserver(nsIObserver** aObserver) { - AssertSanity(); - *aObserver = do_AddRef(this).take(); - return NS_OK; -} - -NS_IMETHODIMP -PermissionRequestBase::Observe(nsISupports* aSubject, const char* aTopic, - const char16_t* aData) { - AssertSanity(); - MOZ_ASSERT(!strcmp(aTopic, kPermissionResponseTopic)); - MOZ_ASSERT(mOwnerElement); - MOZ_ASSERT(mPrincipal); - - const nsCOMPtr element = std::move(mOwnerElement); - Unused << element; - const nsCOMPtr principal = std::move(mPrincipal); - - nsresult rv; - uint32_t promptResult = nsDependentString(aData).ToInteger(&rv); - MOZ_ALWAYS_SUCCEEDS(rv); - - // The UI prompt code will only return one of these three values. We have to - // transform it to our values. - MOZ_ASSERT(promptResult == kPermissionDefault || - promptResult == kPermissionAllowed || - promptResult == kPermissionDenied); - - if (promptResult != kPermissionDefault) { - // Save explicitly allowed or denied permissions now. - SetExplicitPermission(principal, promptResult); - } - - PermissionValue permission; - switch (promptResult) { - case kPermissionDefault: - permission = kPermissionPrompt; - break; - - case kPermissionAllowed: - permission = kPermissionAllowed; - break; - - case kPermissionDenied: - permission = kPermissionDenied; - break; - - default: - MOZ_CRASH("Bad prompt result!"); - } - - OnPromptComplete(permission); - return NS_OK; -} - -} // namespace mozilla::dom::indexedDB diff --git a/dom/indexedDB/PermissionRequestBase.h b/dom/indexedDB/PermissionRequestBase.h deleted file mode 100644 index d083c7c58f41..000000000000 --- a/dom/indexedDB/PermissionRequestBase.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_indexeddb_permissionrequestbase_h__ -#define mozilla_dom_indexeddb_permissionrequestbase_h__ - -#include "mozilla/Attributes.h" -#include "nsCOMPtr.h" -#include "nsIIDBPermissionsRequest.h" -#include "nsIObserver.h" -#include "nsIPermissionManager.h" -#include "nsISupportsImpl.h" -#include "nsString.h" - -class nsIPrincipal; - -namespace mozilla::dom { - -class Element; - -namespace indexedDB { - -class PermissionRequestBase : public nsIObserver, - public nsIIDBPermissionsRequest { - nsCOMPtr mOwnerElement; - nsCOMPtr mPrincipal; - - public: - enum PermissionValue { - kPermissionAllowed = nsIPermissionManager::ALLOW_ACTION, - kPermissionDenied = nsIPermissionManager::DENY_ACTION, - kPermissionPrompt = nsIPermissionManager::PROMPT_ACTION - }; - - NS_DECL_ISUPPORTS - - // This function will not actually prompt. It will never return - // kPermissionDefault but will instead translate the permission manager value - // into the correct value for the given type. - static Result GetCurrentPermission( - nsIPrincipal& aPrincipal); - - static PermissionValue PermissionValueForIntPermission( - uint32_t aIntPermission); - - // This function will prompt if needed. It may only be called once. - Result PromptIfNeeded(); - - protected: - PermissionRequestBase(Element* aOwnerElement, nsIPrincipal* aPrincipal); - - // Reference counted. - virtual ~PermissionRequestBase(); - - virtual void OnPromptComplete(PermissionValue aPermissionValue) = 0; - - private: - void SetExplicitPermission(nsIPrincipal* aPrincipal, uint32_t aIntPermission); - - NS_DECL_NSIOBSERVER - NS_DECL_NSIIDBPERMISSIONSREQUEST -}; - -} // namespace indexedDB -} // namespace mozilla::dom - -#endif // mozilla_dom_indexeddb_permissionrequestbase_h__ diff --git a/dom/indexedDB/moz.build b/dom/indexedDB/moz.build index 9282d91ae18c..52b005f374f0 100644 --- a/dom/indexedDB/moz.build +++ b/dom/indexedDB/moz.build @@ -50,7 +50,6 @@ EXPORTS.mozilla.dom.indexedDB += [ "IDBResult.h", "Key.h", "KeyPath.h", - "PermissionRequestBase.h", "SerializationHelpers.h", "ThreadLocal.h", ] @@ -77,7 +76,6 @@ UNIFIED_SOURCES += [ "IndexedDatabaseManager.cpp", "IndexedDBCommon.cpp", "KeyPath.cpp", - "PermissionRequestBase.cpp", "ProfilerHelpers.cpp", "ReportInternalError.cpp", "SchemaUpgrades.cpp", diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp index c65d1164e3a5..05b04279d753 100644 --- a/dom/ipc/BrowserParent.cpp +++ b/dom/ipc/BrowserParent.cpp @@ -1361,36 +1361,6 @@ bool BrowserParent::DeallocPFilePickerParent(PFilePickerParent* actor) { return true; } -IPCResult BrowserParent::RecvIndexedDBPermissionRequest( - nsIPrincipal* aPrincipal, IndexedDBPermissionRequestResolver&& aResolve) { - MOZ_ASSERT(NS_IsMainThread()); - - nsCOMPtr principal(aPrincipal); - if (!principal) { - return IPC_FAIL_NO_REASON(this); - } - - if (NS_WARN_IF(!mFrameElement)) { - return IPC_FAIL_NO_REASON(this); - } - - RefPtr actor = - new indexedDB::PermissionRequestHelper(mFrameElement, principal, - aResolve); - - mozilla::Result permissionOrErr = actor->PromptIfNeeded(); - if (permissionOrErr.isErr()) { - return IPC_FAIL_NO_REASON(this); - } - - if (permissionOrErr.inspect() != - indexedDB::PermissionRequestBase::kPermissionPrompt) { - aResolve(permissionOrErr.inspect()); - } - - return IPC_OK(); -} - already_AddRefed BrowserParent::AllocPSessionStoreParent() { RefPtr sessionStore = diff --git a/dom/ipc/BrowserParent.h b/dom/ipc/BrowserParent.h index c918b52fd69a..35952fc13e30 100644 --- a/dom/ipc/BrowserParent.h +++ b/dom/ipc/BrowserParent.h @@ -604,9 +604,6 @@ class BrowserParent final : public PBrowserParent, bool DeallocPFilePickerParent(PFilePickerParent* actor); - mozilla::ipc::IPCResult RecvIndexedDBPermissionRequest( - nsIPrincipal* aPrincipal, IndexedDBPermissionRequestResolver&& aResolve); - bool GetGlobalJSObject(JSContext* cx, JSObject** globalp); void StartPersistence(CanonicalBrowsingContext* aContext, diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 4df5474ff564..5a344e52dcb7 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -441,19 +441,6 @@ parent: async PFilePicker(nsString aTitle, int16_t aMode); - /** - * Initiates an asynchronous request for one of the special indexedDB - * permissions for the provided principal. - * - * @param principal - * The principal of the request. - * - * NOTE: The principal is untrusted in the parent process. Only - * principals that can live in the content process should - * provided. - */ - async IndexedDBPermissionRequest(nsIPrincipal aPrincipal) returns (uint32_t permission); - /** * Tells the containing widget whether the given input block results in a * swipe. Should be called in response to a WidgetWheelEvent that has