/* * Copyright (C) 2019-2020 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #if ENABLE(RESOURCE_LOAD_STATISTICS) #include "RegistrableDomain.h" #include "Supplementable.h" #include namespace WebCore { class DeferredPromise; class Document; class UserGestureIndicator; enum class StorageAccessWasGranted : bool { No, Yes }; enum class StorageAccessPromptWasShown : bool { No, Yes }; enum class StorageAccessScope : bool { PerFrame, PerPage }; enum class StorageAccessQuickResult : bool { Grant, Reject }; struct RequestStorageAccessResult { StorageAccessWasGranted wasGranted; StorageAccessPromptWasShown promptWasShown; StorageAccessScope scope; RegistrableDomain topFrameDomain; RegistrableDomain subFrameDomain; template void encode(Encoder&) const; template static std::optional decode(Decoder&); }; const unsigned maxNumberOfTimesExplicitlyDeniedStorageAccess = 2; class DocumentStorageAccess final : public Supplement, public CanMakeWeakPtr { WTF_MAKE_FAST_ALLOCATED; public: explicit DocumentStorageAccess(Document&); ~DocumentStorageAccess(); static void hasStorageAccess(Document&, Ref&&); static bool hasStorageAccessForDocumentQuirk(Document&); static void requestStorageAccess(Document&, Ref&&); static void requestStorageAccessForDocumentQuirk(Document&, CompletionHandler&&); static void requestStorageAccessForNonDocumentQuirk(Document& hostingDocument, RegistrableDomain&& requestingDomain, CompletionHandler&&); private: std::optional hasStorageAccessQuickCheck(); void hasStorageAccess(Ref&&); bool hasStorageAccessQuirk(); std::optional requestStorageAccessQuickCheck(); void requestStorageAccess(Ref&&); void requestStorageAccessForDocumentQuirk(CompletionHandler&&); void requestStorageAccessForNonDocumentQuirk(RegistrableDomain&& requestingDomain, CompletionHandler&&); void requestStorageAccessQuirk(RegistrableDomain&& requestingDomain, CompletionHandler&&); static DocumentStorageAccess* from(Document&); static const char* supplementName(); bool hasFrameSpecificStorageAccess() const; void setWasExplicitlyDeniedFrameSpecificStorageAccess() { ++m_numberOfTimesExplicitlyDeniedFrameSpecificStorageAccess; }; bool isAllowedToRequestStorageAccess() { return m_numberOfTimesExplicitlyDeniedFrameSpecificStorageAccess < maxNumberOfTimesExplicitlyDeniedStorageAccess; }; void enableTemporaryTimeUserGesture(); void consumeTemporaryTimeUserGesture(); std::unique_ptr m_temporaryUserGesture; Document& m_document; uint8_t m_numberOfTimesExplicitlyDeniedFrameSpecificStorageAccess = 0; StorageAccessScope m_storageAccessScope = StorageAccessScope::PerPage; }; template void RequestStorageAccessResult::encode(Encoder& encoder) const { encoder << wasGranted << promptWasShown << scope << topFrameDomain << subFrameDomain; } template std::optional RequestStorageAccessResult::decode(Decoder& decoder) { std::optional wasGranted; decoder >> wasGranted; if (!wasGranted) return std::nullopt; std::optional promptWasShown; decoder >> promptWasShown; if (!promptWasShown) return std::nullopt; std::optional scope; decoder >> scope; if (!scope) return std::nullopt; std::optional topFrameDomain; decoder >> topFrameDomain; if (!topFrameDomain) return std::nullopt; std::optional subFrameDomain; decoder >> subFrameDomain; if (!subFrameDomain) return std::nullopt; return { { WTFMove(*wasGranted), WTFMove(*promptWasShown), WTFMove(*scope), WTFMove(*topFrameDomain), WTFMove(*subFrameDomain) } }; } } // namespace WebCore #endif // ENABLE(RESOURCE_LOAD_STATISTICS)