OriginScope.h (11571B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_quota_originorpatternstring_h__ 8 #define mozilla_dom_quota_originorpatternstring_h__ 9 10 #include <utility> 11 12 #include "mozilla/Assertions.h" 13 #include "mozilla/OriginAttributes.h" 14 #include "mozilla/UniquePtr.h" 15 #include "mozilla/Variant.h" 16 #include "mozilla/dom/quota/CommonMetadata.h" 17 #include "nsStringFlags.h" 18 #include "nsStringFwd.h" 19 20 namespace mozilla::dom::quota { 21 22 class OriginScope { 23 class Origin { 24 const PrincipalMetadata mPrincipalMetadata; 25 nsCString mOriginNoSuffix; 26 UniquePtr<OriginAttributes> mAttributes; 27 28 public: 29 explicit Origin(const PrincipalMetadata& aPrincipalMetadata) 30 : mPrincipalMetadata(aPrincipalMetadata) { 31 InitMembers(); 32 } 33 34 Origin(const Origin& aOther) 35 : mPrincipalMetadata(aOther.mPrincipalMetadata), 36 mOriginNoSuffix(aOther.mOriginNoSuffix), 37 mAttributes(MakeUnique<OriginAttributes>(*aOther.mAttributes)) {} 38 39 Origin(Origin&& aOther) = default; 40 41 const PrincipalMetadata& GetPrincipalMetadata() const { 42 return mPrincipalMetadata; 43 } 44 45 const nsACString& GetGroup() const { return mPrincipalMetadata.mGroup; } 46 47 const nsACString& GetOrigin() const { return mPrincipalMetadata.mOrigin; } 48 49 const nsACString& GetOriginNoSuffix() const { return mOriginNoSuffix; } 50 51 const OriginAttributes& GetAttributes() const { 52 MOZ_ASSERT(mAttributes); 53 54 return *mAttributes; 55 } 56 57 private: 58 void InitMembers() { 59 mAttributes = MakeUnique<OriginAttributes>(); 60 61 MOZ_ALWAYS_TRUE(mAttributes->PopulateFromOrigin( 62 mPrincipalMetadata.mOrigin, mOriginNoSuffix)); 63 } 64 }; 65 66 class Prefix { 67 const PrincipalMetadata mPrincipalMetadata; 68 nsCString mGroupNoSuffix; 69 nsCString mOriginNoSuffix; 70 71 public: 72 explicit Prefix(const PrincipalMetadata& aPrincipalMetadata) 73 : mGroupNoSuffix(aPrincipalMetadata.mGroup), 74 mOriginNoSuffix(aPrincipalMetadata.mOrigin) {} 75 76 const nsACString& GetGroupNoSuffix() const { return mGroupNoSuffix; } 77 78 const nsCString& GetOriginNoSuffix() const { return mOriginNoSuffix; } 79 }; 80 81 class Group { 82 nsCString mGroup; 83 nsCString mGroupNoSuffix; 84 UniquePtr<OriginAttributes> mAttributes; 85 86 public: 87 explicit Group(const nsACString& aGroup) : mGroup(aGroup) { InitMembers(); } 88 89 Group(const Group& aOther) 90 : mGroup(aOther.mGroup), 91 mGroupNoSuffix(aOther.mGroupNoSuffix), 92 mAttributes(MakeUnique<OriginAttributes>(*aOther.mAttributes)) {} 93 94 Group(Group&& aOther) = default; 95 96 const nsACString& GetGroup() const { return mGroup; } 97 98 const nsACString& GetGroupNoSuffix() const { return mGroupNoSuffix; } 99 100 const OriginAttributes& GetAttributes() const { 101 MOZ_ASSERT(mAttributes); 102 103 return *mAttributes; 104 } 105 106 private: 107 void InitMembers() { 108 mAttributes = MakeUnique<OriginAttributes>(); 109 110 MOZ_ALWAYS_TRUE(mAttributes->PopulateFromOrigin(mGroup, mGroupNoSuffix)); 111 } 112 }; 113 114 class Pattern { 115 UniquePtr<OriginAttributesPattern> mPattern; 116 117 public: 118 explicit Pattern(const OriginAttributesPattern& aPattern) 119 : mPattern(MakeUnique<OriginAttributesPattern>(aPattern)) {} 120 121 explicit Pattern(const nsAString& aJSONPattern) 122 : mPattern(MakeUnique<OriginAttributesPattern>()) { 123 MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern)); 124 } 125 126 Pattern(const Pattern& aOther) 127 : mPattern(MakeUnique<OriginAttributesPattern>(*aOther.mPattern)) {} 128 129 Pattern(Pattern&& aOther) = default; 130 131 const OriginAttributesPattern& GetPattern() const { 132 MOZ_ASSERT(mPattern); 133 134 return *mPattern; 135 } 136 137 nsString GetJSONPattern() const { 138 MOZ_ASSERT(mPattern); 139 140 nsString result; 141 MOZ_ALWAYS_TRUE(mPattern->ToJSON(result)); 142 143 return result; 144 } 145 }; 146 147 struct Null {}; 148 149 using DataType = Variant<Origin, Prefix, Group, Pattern, Null>; 150 151 DataType mData; 152 153 public: 154 OriginScope() : mData(Null()) {} 155 156 // XXX Consider renaming these static methods to Create 157 static OriginScope FromOrigin(const PrincipalMetadata& aPrincipalMetadata) { 158 return OriginScope(std::move(Origin(aPrincipalMetadata))); 159 } 160 161 static OriginScope FromPrefix(const PrincipalMetadata& aPrincipalMetadata) { 162 return OriginScope(std::move(Prefix(aPrincipalMetadata))); 163 } 164 165 static OriginScope FromGroup(const nsACString& aGroup) { 166 return OriginScope(std::move(Group(aGroup))); 167 } 168 169 static OriginScope FromPattern(const OriginAttributesPattern& aPattern) { 170 return OriginScope(std::move(Pattern(aPattern))); 171 } 172 173 static OriginScope FromJSONPattern(const nsAString& aJSONPattern) { 174 return OriginScope(std::move(Pattern(aJSONPattern))); 175 } 176 177 static OriginScope FromNull() { return OriginScope(std::move(Null())); } 178 179 bool IsOrigin() const { return mData.is<Origin>(); } 180 181 bool IsPrefix() const { return mData.is<Prefix>(); } 182 183 bool IsPattern() const { return mData.is<Pattern>(); } 184 185 bool IsNull() const { return mData.is<Null>(); } 186 187 void SetFromOrigin(const PrincipalMetadata& aPrincipalMetadata) { 188 mData = AsVariant(Origin(aPrincipalMetadata)); 189 } 190 191 void SetFromPrefix(const PrincipalMetadata& aPrincipalMetadata) { 192 mData = AsVariant(Prefix(aPrincipalMetadata)); 193 } 194 195 void SetFromPattern(const OriginAttributesPattern& aPattern) { 196 mData = AsVariant(Pattern(aPattern)); 197 } 198 199 void SetFromJSONPattern(const nsAString& aJSONPattern) { 200 mData = AsVariant(Pattern(aJSONPattern)); 201 } 202 203 void SetFromNull() { mData = AsVariant(Null()); } 204 205 const PrincipalMetadata& GetPrincipalMetadata() const { 206 MOZ_ASSERT(IsOrigin()); 207 208 return mData.as<Origin>().GetPrincipalMetadata(); 209 } 210 211 const nsACString& GetOrigin() const { 212 MOZ_ASSERT(IsOrigin()); 213 214 return mData.as<Origin>().GetOrigin(); 215 } 216 217 const nsACString& GetOriginNoSuffix() const { 218 MOZ_ASSERT(IsOrigin() || IsPrefix()); 219 220 if (IsOrigin()) { 221 return mData.as<Origin>().GetOriginNoSuffix(); 222 } 223 return mData.as<Prefix>().GetOriginNoSuffix(); 224 } 225 226 const OriginAttributesPattern& GetPattern() const { 227 MOZ_ASSERT(IsPattern()); 228 229 return mData.as<Pattern>().GetPattern(); 230 } 231 232 nsString GetJSONPattern() const { 233 MOZ_ASSERT(IsPattern()); 234 235 return mData.as<Pattern>().GetJSONPattern(); 236 } 237 238 bool Matches(const OriginScope& aOther) const { 239 struct Matcher { 240 const OriginScope& mThis; 241 242 explicit Matcher(const OriginScope& aThis) : mThis(aThis) {} 243 244 bool operator()(const Origin& aOther) { 245 return mThis.MatchesOrigin(aOther); 246 } 247 248 bool operator()(const Prefix& aOther) { 249 return mThis.MatchesPrefix(aOther); 250 } 251 252 bool operator()(const Group& aOther) { 253 return mThis.MatchesGroup(aOther); 254 } 255 256 bool operator()(const Pattern& aOther) { 257 return mThis.MatchesPattern(aOther); 258 } 259 260 bool operator()(const Null& aOther) { return true; } 261 }; 262 263 return aOther.mData.match(Matcher(*this)); 264 } 265 266 OriginScope Clone() { return OriginScope(mData); } 267 268 private: 269 // Move constructors 270 explicit OriginScope(const Origin&& aOrigin) : mData(aOrigin) {} 271 272 explicit OriginScope(const Prefix&& aPrefix) : mData(aPrefix) {} 273 274 explicit OriginScope(const Group&& aGroup) : mData(aGroup) {} 275 276 explicit OriginScope(const Pattern&& aPattern) : mData(aPattern) {} 277 278 explicit OriginScope(const Null&& aNull) : mData(aNull) {} 279 280 // Copy constructor 281 explicit OriginScope(const DataType& aOther) : mData(aOther) {} 282 283 bool MatchesOrigin(const Origin& aOther) const { 284 struct OriginMatcher { 285 const Origin& mOther; 286 287 explicit OriginMatcher(const Origin& aOther) : mOther(aOther) {} 288 289 bool operator()(const Origin& aThis) { 290 return aThis.GetOrigin().Equals(mOther.GetOrigin()); 291 } 292 293 bool operator()(const Prefix& aThis) { 294 return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); 295 } 296 297 bool operator()(const Group& aThis) { 298 return aThis.GetGroup().Equals(mOther.GetGroup()); 299 } 300 301 bool operator()(const Pattern& aThis) { 302 return aThis.GetPattern().Matches(mOther.GetAttributes()); 303 } 304 305 bool operator()(const Null& aThis) { 306 // Null covers everything. 307 return true; 308 } 309 }; 310 311 return mData.match(OriginMatcher(aOther)); 312 } 313 314 bool MatchesPrefix(const Prefix& aOther) const { 315 struct PrefixMatcher { 316 const Prefix& mOther; 317 318 explicit PrefixMatcher(const Prefix& aOther) : mOther(aOther) {} 319 320 bool operator()(const Origin& aThis) { 321 return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); 322 } 323 324 bool operator()(const Prefix& aThis) { 325 return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix()); 326 } 327 328 bool operator()(const Group& aThis) { 329 return aThis.GetGroupNoSuffix().Equals(mOther.GetGroupNoSuffix()); 330 } 331 332 bool operator()(const Pattern& aThis) { 333 // The match will be always true here because any origin attributes 334 // pattern overlaps any origin prefix (an origin prefix targets all 335 // origin attributes). 336 return true; 337 } 338 339 bool operator()(const Null& aThis) { 340 // Null covers everything. 341 return true; 342 } 343 }; 344 345 return mData.match(PrefixMatcher(aOther)); 346 } 347 348 bool MatchesGroup(const Group& aOther) const { 349 struct GroupMatcher { 350 const Group& mOther; 351 352 explicit GroupMatcher(const Group& aOther) : mOther(aOther) {} 353 354 bool operator()(const Origin& aThis) { 355 return aThis.GetGroup().Equals(mOther.GetGroup()); 356 } 357 358 bool operator()(const Prefix& aThis) { 359 return aThis.GetGroupNoSuffix().Equals(mOther.GetGroupNoSuffix()); 360 } 361 362 bool operator()(const Group& aThis) { 363 return aThis.GetGroup().Equals(mOther.GetGroup()); 364 } 365 366 bool operator()(const Pattern& aThis) { 367 return aThis.GetPattern().Matches(mOther.GetAttributes()); 368 } 369 370 bool operator()(const Null& aThis) { 371 // Null covers everything. 372 return true; 373 } 374 }; 375 376 return mData.match(GroupMatcher(aOther)); 377 } 378 379 bool MatchesPattern(const Pattern& aOther) const { 380 struct PatternMatcher { 381 const Pattern& mOther; 382 383 explicit PatternMatcher(const Pattern& aOther) : mOther(aOther) {} 384 385 bool operator()(const Origin& aThis) { 386 return mOther.GetPattern().Matches(aThis.GetAttributes()); 387 } 388 389 bool operator()(const Prefix& aThis) { 390 // The match will be always true here because any origin attributes 391 // pattern overlaps any origin prefix (an origin prefix targets all 392 // origin attributes). 393 return true; 394 } 395 396 bool operator()(const Group& aThis) { 397 return mOther.GetPattern().Matches(aThis.GetAttributes()); 398 } 399 400 bool operator()(const Pattern& aThis) { 401 return aThis.GetPattern().Overlaps(mOther.GetPattern()); 402 } 403 404 bool operator()(const Null& aThis) { 405 // Null covers everything. 406 return true; 407 } 408 }; 409 410 PatternMatcher patternMatcher(aOther); 411 return mData.match(PatternMatcher(aOther)); 412 } 413 414 bool operator==(const OriginScope& aOther) = delete; 415 }; 416 417 } // namespace mozilla::dom::quota 418 419 #endif // mozilla_dom_quota_originorpatternstring_h__