From e0c3fde4084de8b2caae2e0b1d91fdb4eca7c1c2 Mon Sep 17 00:00:00 2001 From: Jan Varga Date: Thu, 17 Oct 2024 10:14:47 +0000 Subject: [PATCH] Bug 1867997 - Add support for group directory locks; r=dom-storage-reviewers,jari Some operations need to lock entire origin group (eTLD+1 domain). One of such operations is EstimateOp. However, the primary motivation for group directory locks is planned background initialization of origin groups. Differential Revision: https://phabricator.services.mozilla.com/D196047 --- dom/quota/OriginScope.h | 96 +++++++++++++++++++++++- dom/quota/test/gtest/TestOriginScope.cpp | 61 +++++++++++++++ 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/dom/quota/OriginScope.h b/dom/quota/OriginScope.h index 836e035915db..1213cb0bc715 100644 --- a/dom/quota/OriginScope.h +++ b/dom/quota/OriginScope.h @@ -41,6 +41,8 @@ class OriginScope { return mPrincipalMetadata; } + const nsACString& GetGroup() const { return mPrincipalMetadata.mGroup; } + const nsACString& GetOrigin() const { return mPrincipalMetadata.mOrigin; } const nsACString& GetOriginNoSuffix() const { return mOriginNoSuffix; } @@ -62,15 +64,52 @@ class OriginScope { class Prefix { const PrincipalMetadata mPrincipalMetadata; + nsCString mGroupNoSuffix; nsCString mOriginNoSuffix; public: explicit Prefix(const PrincipalMetadata& aPrincipalMetadata) - : mOriginNoSuffix(aPrincipalMetadata.mOrigin) {} + : mGroupNoSuffix(aPrincipalMetadata.mGroup), + mOriginNoSuffix(aPrincipalMetadata.mOrigin) {} + + const nsACString& GetGroupNoSuffix() const { return mGroupNoSuffix; } const nsCString& GetOriginNoSuffix() const { return mOriginNoSuffix; } }; + class Group { + nsCString mGroup; + nsCString mGroupNoSuffix; + UniquePtr mAttributes; + + public: + explicit Group(const nsACString& aGroup) : mGroup(aGroup) { InitMembers(); } + + Group(const Group& aOther) + : mGroup(aOther.mGroup), + mGroupNoSuffix(aOther.mGroupNoSuffix), + mAttributes(MakeUnique(*aOther.mAttributes)) {} + + Group(Group&& aOther) = default; + + const nsACString& GetGroup() const { return mGroup; } + + const nsACString& GetGroupNoSuffix() const { return mGroupNoSuffix; } + + const OriginAttributes& GetAttributes() const { + MOZ_ASSERT(mAttributes); + + return *mAttributes; + } + + private: + void InitMembers() { + mAttributes = MakeUnique(); + + MOZ_ALWAYS_TRUE(mAttributes->PopulateFromOrigin(mGroup, mGroupNoSuffix)); + } + }; + class Pattern { UniquePtr mPattern; @@ -106,7 +145,7 @@ class OriginScope { struct Null {}; - using DataType = Variant; + using DataType = Variant; DataType mData; @@ -122,6 +161,10 @@ class OriginScope { return OriginScope(std::move(Prefix(aPrincipalMetadata))); } + static OriginScope FromGroup(const nsACString& aGroup) { + return OriginScope(std::move(Group(aGroup))); + } + static OriginScope FromPattern(const OriginAttributesPattern& aPattern) { return OriginScope(std::move(Pattern(aPattern))); } @@ -205,6 +248,10 @@ class OriginScope { return mThis.MatchesPrefix(aOther); } + bool operator()(const Group& aOther) { + return mThis.MatchesGroup(aOther); + } + bool operator()(const Pattern& aOther) { return mThis.MatchesPattern(aOther); } @@ -223,6 +270,8 @@ class OriginScope { explicit OriginScope(const Prefix&& aPrefix) : mData(aPrefix) {} + explicit OriginScope(const Group&& aGroup) : mData(aGroup) {} + explicit OriginScope(const Pattern&& aPattern) : mData(aPattern) {} explicit OriginScope(const Null&& aNull) : mData(aNull) {} @@ -244,6 +293,10 @@ class OriginScope { return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); } + bool operator()(const Group& aThis) { + return aThis.GetGroup().Equals(mOther.GetGroup()); + } + bool operator()(const Pattern& aThis) { return aThis.GetPattern().Matches(mOther.GetAttributes()); } @@ -271,6 +324,10 @@ class OriginScope { return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); } + bool operator()(const Group& aThis) { + return aThis.GetGroupNoSuffix().Equals(mOther.GetGroupNoSuffix()); + } + bool operator()(const Pattern& aThis) { // The match will be always true here because any origin attributes // pattern overlaps any origin prefix (an origin prefix targets all @@ -287,6 +344,37 @@ class OriginScope { return mData.match(PrefixMatcher(aOther)); } + bool MatchesGroup(const Group& aOther) const { + struct GroupMatcher { + const Group& mOther; + + explicit GroupMatcher(const Group& aOther) : mOther(aOther) {} + + bool operator()(const Origin& aThis) { + return aThis.GetGroup().Equals(mOther.GetGroup()); + } + + bool operator()(const Prefix& aThis) { + return aThis.GetGroupNoSuffix().Equals(mOther.GetGroupNoSuffix()); + } + + bool operator()(const Group& aThis) { + return aThis.GetGroup().Equals(mOther.GetGroup()); + } + + bool operator()(const Pattern& aThis) { + return aThis.GetPattern().Matches(mOther.GetAttributes()); + } + + bool operator()(const Null& aThis) { + // Null covers everything. + return true; + } + }; + + return mData.match(GroupMatcher(aOther)); + } + bool MatchesPattern(const Pattern& aOther) const { struct PatternMatcher { const Pattern& mOther; @@ -304,6 +392,10 @@ class OriginScope { return true; } + bool operator()(const Group& aThis) { + return mOther.GetPattern().Matches(aThis.GetAttributes()); + } + bool operator()(const Pattern& aThis) { return aThis.GetPattern().Overlaps(mOther.GetPattern()); } diff --git a/dom/quota/test/gtest/TestOriginScope.cpp b/dom/quota/test/gtest/TestOriginScope.cpp index c43ba7324871..43d6e67f0399 100644 --- a/dom/quota/test/gtest/TestOriginScope.cpp +++ b/dom/quota/test/gtest/TestOriginScope.cpp @@ -117,4 +117,65 @@ TEST(DOM_Quota_OriginScope, MatchesOrigin) } } +TEST(DOM_Quota_OriginScope, MatchesGroup) +{ + { + const auto originScope(OriginScope::FromOrigin( + GetPrincipalMetadata("mozilla.org"_ns, "http://www.mozilla.org"_ns))); + + ASSERT_TRUE(originScope.Matches(OriginScope::FromGroup("mozilla.org"_ns))); + ASSERT_FALSE(originScope.Matches( + OriginScope::FromGroup("mozilla.org^userContextId=1"_ns))); + ASSERT_FALSE(originScope.Matches(OriginScope::FromGroup("mozilla.com"_ns))); + } + + { + const auto originScope(OriginScope::FromOrigin(GetPrincipalMetadata( + "userContextId=1"_ns, "mozilla.org"_ns, "http://www.mozilla.org"_ns))); + + ASSERT_FALSE(originScope.Matches(OriginScope::FromGroup("mozilla.org"_ns))); + ASSERT_TRUE(originScope.Matches( + OriginScope::FromGroup("mozilla.org^userContextId=1"_ns))); + ASSERT_FALSE(originScope.Matches(OriginScope::FromGroup("mozilla.com"_ns))); + } + + { + const auto originScope(OriginScope::FromPrefix( + GetPrincipalMetadata("mozilla.org"_ns, "http://www.mozilla.org"_ns))); + + ASSERT_TRUE(originScope.Matches(OriginScope::FromGroup("mozilla.org"_ns))); + ASSERT_TRUE(originScope.Matches( + OriginScope::FromGroup("mozilla.org^userContextId=1"_ns))); + ASSERT_FALSE(originScope.Matches(OriginScope::FromGroup("mozilla.com"_ns))); + } + + { + const auto originScope( + OriginScope::FromJSONPattern(u"{ \"userContextId\": 1 }"_ns)); + + ASSERT_FALSE(originScope.Matches(OriginScope::FromGroup("mozilla.org"_ns))); + ASSERT_TRUE(originScope.Matches( + OriginScope::FromGroup("mozilla.org^userContextId=1"_ns))); + ASSERT_FALSE(originScope.Matches(OriginScope::FromGroup("mozilla.com"_ns))); + } + + { + const auto originScope(OriginScope::FromGroup("mozilla.org"_ns)); + + ASSERT_TRUE(originScope.Matches(OriginScope::FromGroup("mozilla.org"_ns))); + ASSERT_FALSE(originScope.Matches( + OriginScope::FromGroup("mozilla.org^userContextId=1"_ns))); + ASSERT_FALSE(originScope.Matches(OriginScope::FromGroup("mozilla.com"_ns))); + } + + { + const auto originScope(OriginScope::FromNull()); + + ASSERT_TRUE(originScope.Matches(OriginScope::FromGroup("mozilla.org"_ns))); + ASSERT_TRUE(originScope.Matches( + OriginScope::FromGroup("mozilla.org^userContextId=1"_ns))); + ASSERT_TRUE(originScope.Matches(OriginScope::FromGroup("mozilla.com"_ns))); + } +} + } // namespace mozilla::dom::quota