Bug 1769321 [wpt PR 34062] - Update wpt metadata, a=testonly
[gecko.git] / caps / OriginAttributes.h
blob8e78a7cb24f1e50e4e9c586538cd66596b410fc7
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_OriginAttributes_h
8 #define mozilla_OriginAttributes_h
10 #include "mozilla/dom/ChromeUtilsBinding.h"
11 #include "mozilla/StaticPrefs_privacy.h"
12 #include "nsIScriptSecurityManager.h"
14 namespace mozilla {
16 class OriginAttributes : public dom::OriginAttributesDictionary {
17 public:
18 OriginAttributes() = default;
20 explicit OriginAttributes(bool aInIsolatedMozBrowser) {
21 mInIsolatedMozBrowser = aInIsolatedMozBrowser;
24 explicit OriginAttributes(const OriginAttributesDictionary& aOther)
25 : OriginAttributesDictionary(aOther) {}
27 void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI,
28 bool aForced = false);
29 void SetFirstPartyDomain(const bool aIsTopLevelDocument,
30 const nsACString& aDomain);
31 void SetFirstPartyDomain(const bool aIsTopLevelDocument,
32 const nsAString& aDomain, bool aForced = false);
34 void SetPartitionKey(nsIURI* aURI);
35 void SetPartitionKey(const nsACString& aDomain);
36 void SetPartitionKey(const nsAString& aDomain);
38 enum {
39 STRIP_FIRST_PARTY_DOMAIN = 0x01,
40 STRIP_USER_CONTEXT_ID = 0x02,
41 STRIP_PRIVATE_BROWSING_ID = 0x04,
42 STRIP_PARITION_KEY = 0x08,
45 inline void StripAttributes(uint32_t aFlags) {
46 if (aFlags & STRIP_FIRST_PARTY_DOMAIN) {
47 mFirstPartyDomain.Truncate();
50 if (aFlags & STRIP_USER_CONTEXT_ID) {
51 mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
54 if (aFlags & STRIP_PRIVATE_BROWSING_ID) {
55 mPrivateBrowsingId =
56 nsIScriptSecurityManager::DEFAULT_PRIVATE_BROWSING_ID;
59 if (aFlags & STRIP_PARITION_KEY) {
60 mPartitionKey.Truncate();
64 bool operator==(const OriginAttributes& aOther) const {
65 return EqualsIgnoringFPD(aOther) &&
66 mFirstPartyDomain == aOther.mFirstPartyDomain &&
67 // FIXME(emilio, bug 1667440): Should this be part of
68 // EqualsIgnoringFPD instead?
69 mPartitionKey == aOther.mPartitionKey;
72 bool operator!=(const OriginAttributes& aOther) const {
73 return !(*this == aOther);
76 [[nodiscard]] bool EqualsIgnoringFPD(const OriginAttributes& aOther) const {
77 return mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser &&
78 mUserContextId == aOther.mUserContextId &&
79 mPrivateBrowsingId == aOther.mPrivateBrowsingId &&
80 mGeckoViewSessionContextId == aOther.mGeckoViewSessionContextId;
83 [[nodiscard]] bool EqualsIgnoringPartitionKey(
84 const OriginAttributes& aOther) const {
85 return EqualsIgnoringFPD(aOther) &&
86 mFirstPartyDomain == aOther.mFirstPartyDomain;
89 // Serializes/Deserializes non-default values into the suffix format, i.e.
90 // |^key1=value1&key2=value2|. If there are no non-default attributes, this
91 // returns an empty string.
92 void CreateSuffix(nsACString& aStr) const;
94 // Like CreateSuffix, but returns an atom instead of producing a string.
95 already_AddRefed<nsAtom> CreateSuffixAtom() const;
97 // Don't use this method for anything else than debugging!
98 void CreateAnonymizedSuffix(nsACString& aStr) const;
100 [[nodiscard]] bool PopulateFromSuffix(const nsACString& aStr);
102 // Populates the attributes from a string like
103 // |uri^key1=value1&key2=value2| and returns the uri without the suffix.
104 [[nodiscard]] bool PopulateFromOrigin(const nsACString& aOrigin,
105 nsACString& aOriginNoSuffix);
107 // Helper function to match mIsPrivateBrowsing to existing private browsing
108 // flags. Once all other flags are removed, this can be removed too.
109 void SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing);
111 // check if "privacy.firstparty.isolate" is enabled.
112 static inline bool IsFirstPartyEnabled() {
113 return StaticPrefs::privacy_firstparty_isolate();
116 static inline bool UseSiteForFirstPartyDomain() {
117 if (IsFirstPartyEnabled()) {
118 return StaticPrefs::privacy_firstparty_isolate_use_site();
120 return StaticPrefs::privacy_dynamic_firstparty_use_site();
123 // check if the access of window.opener across different FPDs is restricted.
124 // We only restrict the access of window.opener when first party isolation
125 // is enabled and "privacy.firstparty.isolate.restrict_opener_access" is on.
126 static inline bool IsRestrictOpenerAccessForFPI() {
127 // We always want to restrict window.opener if first party isolation is
128 // disabled.
129 return !StaticPrefs::privacy_firstparty_isolate() ||
130 StaticPrefs::privacy_firstparty_isolate_restrict_opener_access();
133 // Check whether we block the postMessage across different FPDs when the
134 // targetOrigin is '*'.
135 [[nodiscard]] static inline bool IsBlockPostMessageForFPI() {
136 return StaticPrefs::privacy_firstparty_isolate() &&
137 StaticPrefs::privacy_firstparty_isolate_block_post_message();
140 // returns true if the originAttributes suffix has mPrivateBrowsingId value
141 // different than 0.
142 static bool IsPrivateBrowsing(const nsACString& aOrigin);
144 // Parse a partitionKey of the format "(<scheme>,<baseDomain>,[port])" into
145 // its components.
146 // Returns false if the partitionKey cannot be parsed because the format is
147 // invalid.
148 static bool ParsePartitionKey(const nsAString& aPartitionKey,
149 nsAString& outScheme, nsAString& outBaseDomain,
150 int32_t& outPort);
153 class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary {
154 public:
155 // To convert a JSON string to an OriginAttributesPattern, do the following:
157 // OriginAttributesPattern pattern;
158 // if (!pattern.Init(aJSONString)) {
159 // ... // handle failure.
160 // }
161 OriginAttributesPattern() = default;
163 explicit OriginAttributesPattern(
164 const OriginAttributesPatternDictionary& aOther)
165 : OriginAttributesPatternDictionary(aOther) {}
167 // Performs a match of |aAttrs| against this pattern.
168 bool Matches(const OriginAttributes& aAttrs) const {
169 if (mInIsolatedMozBrowser.WasPassed() &&
170 mInIsolatedMozBrowser.Value() != aAttrs.mInIsolatedMozBrowser) {
171 return false;
174 if (mUserContextId.WasPassed() &&
175 mUserContextId.Value() != aAttrs.mUserContextId) {
176 return false;
179 if (mPrivateBrowsingId.WasPassed() &&
180 mPrivateBrowsingId.Value() != aAttrs.mPrivateBrowsingId) {
181 return false;
184 if (mFirstPartyDomain.WasPassed() &&
185 mFirstPartyDomain.Value() != aAttrs.mFirstPartyDomain) {
186 return false;
189 if (mGeckoViewSessionContextId.WasPassed() &&
190 mGeckoViewSessionContextId.Value() !=
191 aAttrs.mGeckoViewSessionContextId) {
192 return false;
195 // If both mPartitionKey and mPartitionKeyPattern are passed, mPartitionKey
196 // takes precedence.
197 if (mPartitionKey.WasPassed()) {
198 if (mPartitionKey.Value() != aAttrs.mPartitionKey) {
199 return false;
201 } else if (mPartitionKeyPattern.WasPassed()) {
202 auto& pkPattern = mPartitionKeyPattern.Value();
204 if (pkPattern.mScheme.WasPassed() || pkPattern.mBaseDomain.WasPassed() ||
205 pkPattern.mPort.WasPassed()) {
206 if (aAttrs.mPartitionKey.IsEmpty()) {
207 return false;
210 nsString scheme;
211 nsString baseDomain;
212 int32_t port;
213 bool success = OriginAttributes::ParsePartitionKey(
214 aAttrs.mPartitionKey, scheme, baseDomain, port);
215 if (!success) {
216 return false;
219 if (pkPattern.mScheme.WasPassed() &&
220 pkPattern.mScheme.Value() != scheme) {
221 return false;
223 if (pkPattern.mBaseDomain.WasPassed() &&
224 pkPattern.mBaseDomain.Value() != baseDomain) {
225 return false;
227 if (pkPattern.mPort.WasPassed() && pkPattern.mPort.Value() != port) {
228 return false;
233 return true;
236 bool Overlaps(const OriginAttributesPattern& aOther) const {
237 if (mInIsolatedMozBrowser.WasPassed() &&
238 aOther.mInIsolatedMozBrowser.WasPassed() &&
239 mInIsolatedMozBrowser.Value() != aOther.mInIsolatedMozBrowser.Value()) {
240 return false;
243 if (mUserContextId.WasPassed() && aOther.mUserContextId.WasPassed() &&
244 mUserContextId.Value() != aOther.mUserContextId.Value()) {
245 return false;
248 if (mPrivateBrowsingId.WasPassed() &&
249 aOther.mPrivateBrowsingId.WasPassed() &&
250 mPrivateBrowsingId.Value() != aOther.mPrivateBrowsingId.Value()) {
251 return false;
254 if (mFirstPartyDomain.WasPassed() && aOther.mFirstPartyDomain.WasPassed() &&
255 mFirstPartyDomain.Value() != aOther.mFirstPartyDomain.Value()) {
256 return false;
259 if (mGeckoViewSessionContextId.WasPassed() &&
260 aOther.mGeckoViewSessionContextId.WasPassed() &&
261 mGeckoViewSessionContextId.Value() !=
262 aOther.mGeckoViewSessionContextId.Value()) {
263 return false;
266 if (mPartitionKey.WasPassed() && aOther.mPartitionKey.WasPassed() &&
267 mPartitionKey.Value() != aOther.mPartitionKey.Value()) {
268 return false;
271 if (mPartitionKeyPattern.WasPassed() &&
272 aOther.mPartitionKeyPattern.WasPassed()) {
273 auto& self = mPartitionKeyPattern.Value();
274 auto& other = aOther.mPartitionKeyPattern.Value();
276 if (self.mScheme.WasPassed() && other.mScheme.WasPassed() &&
277 self.mScheme.Value() != other.mScheme.Value()) {
278 return false;
280 if (self.mBaseDomain.WasPassed() && other.mBaseDomain.WasPassed() &&
281 self.mBaseDomain.Value() != other.mBaseDomain.Value()) {
282 return false;
284 if (self.mPort.WasPassed() && other.mPort.WasPassed() &&
285 self.mPort.Value() != other.mPort.Value()) {
286 return false;
290 return true;
294 } // namespace mozilla
296 #endif /* mozilla_OriginAttributes_h */