/* -*- 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 "FileSystemManagerParentFactory.h" #include "mozilla/OriginAttributes.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/dom/FileSystemDataManager.h" #include "mozilla/dom/FileSystemLog.h" #include "mozilla/dom/FileSystemManagerParent.h" #include "mozilla/dom/FileSystemTypes.h" #include "mozilla/dom/quota/QuotaCommon.h" #include "mozilla/dom/quota/QuotaManager.h" #include "mozilla/dom/quota/ResultExtensions.h" #include "mozilla/ipc/Endpoint.h" #include "nsIScriptObjectPrincipal.h" #include "nsString.h" namespace mozilla::dom { mozilla::ipc::IPCResult CreateFileSystemManagerParent( const mozilla::ipc::PrincipalInfo& aPrincipalInfo, mozilla::ipc::Endpoint&& aParentEndpoint, std::function&& aResolver) { using CreateActorPromise = MozPromise, nsresult, true>; QM_TRY(OkIf(StaticPrefs::dom_fs_enabled()), IPC_OK(), [aResolver](const auto&) { aResolver(NS_ERROR_DOM_NOT_ALLOWED_ERR); }); QM_TRY(OkIf(aParentEndpoint.IsValid()), IPC_OK(), [aResolver](const auto&) { aResolver(NS_ERROR_INVALID_ARG); }); // This blocks Null and Expanded principals QM_TRY(OkIf(quota::QuotaManager::IsPrincipalInfoValid(aPrincipalInfo)), IPC_OK(), [aResolver](const auto&) { aResolver(NS_ERROR_DOM_SECURITY_ERR); }); QM_TRY(quota::QuotaManager::EnsureCreated(), IPC_OK(), [aResolver](const auto rv) { aResolver(rv); }); auto* const quotaManager = quota::QuotaManager::Get(); MOZ_ASSERT(quotaManager); QM_TRY_UNWRAP(auto principalMetadata, quotaManager->GetInfoFromValidatedPrincipalInfo(aPrincipalInfo), IPC_OK(), [aResolver](const auto rv) { aResolver(rv); }); quota::OriginMetadata originMetadata(std::move(principalMetadata), quota::PERSISTENCE_TYPE_DEFAULT); // Block use for now in PrivateBrowsing QM_TRY(OkIf(!OriginAttributes::IsPrivateBrowsing(originMetadata.mOrigin)), IPC_OK(), [aResolver](const auto&) { aResolver(NS_ERROR_DOM_NOT_ALLOWED_ERR); }); LOG(("CreateFileSystemManagerParent, origin: %s", originMetadata.mOrigin.get())); // This creates the file system data manager, which has to be done on // PBackground fs::data::FileSystemDataManager::GetOrCreateFileSystemDataManager( originMetadata) ->Then( GetCurrentSerialEventTarget(), __func__, [origin = originMetadata.mOrigin, parentEndpoint = std::move(aParentEndpoint), aResolver](const fs::Registered& dataManager) mutable { QM_TRY_UNWRAP( fs::EntryId rootId, fs::data::GetRootHandle(origin), QM_VOID, [aResolver](const auto& aRv) { aResolver(ToNSResult(aRv)); }); InvokeAsync( dataManager->MutableIOTaskQueuePtr(), __func__, [dataManager = RefPtr(dataManager), rootId, parentEndpoint = std::move(parentEndpoint)]() mutable { RefPtr parent = new FileSystemManagerParent(std::move(dataManager), rootId); LOG(("Binding parent endpoint")); if (!parentEndpoint.Bind(parent)) { return CreateActorPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); } return CreateActorPromise::CreateAndResolve(std::move(parent), __func__); }) ->Then(GetCurrentSerialEventTarget(), __func__, [dataManager = dataManager, aResolver]( CreateActorPromise::ResolveOrRejectValue&& aValue) { if (aValue.IsReject()) { aResolver(aValue.RejectValue()); } else { RefPtr parent = std::move(aValue.ResolveValue()); dataManager->RegisterActor(WrapNotNull(parent)); aResolver(NS_OK); } }); }, [aResolver](nsresult aRejectValue) { aResolver(aRejectValue); }); return IPC_OK(); } } // namespace mozilla::dom