Bug 1933479 - Add tab close button on hover to vertical tabs when sidebar is collapse...
[gecko.git] / toolkit / components / antitracking / StorageAccessAPIHelper.h
blobdd6f326604e5e1edc579ca3bb58d19f8cb01a57b
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/. */
7 #ifndef mozilla_antitrackingservice_h
8 #define mozilla_antitrackingservice_h
10 #include "nsString.h"
11 #include "mozilla/ContentBlockingNotifier.h"
12 #include "mozilla/MozPromise.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/StaticPrefs_privacy.h"
16 #include "nsIUrlClassifierFeature.h"
18 class nsIChannel;
19 class nsICookieJarSettings;
20 class nsIPermission;
21 class nsIPrincipal;
22 class nsIURI;
23 class nsPIDOMWindowInner;
24 class nsPIDOMWindowOuter;
26 namespace mozilla {
28 class OriginAttributes;
30 namespace dom {
31 class BrowsingContext;
32 class ContentParent;
33 class Document;
34 } // namespace dom
36 class StorageAccessAPIHelper final {
37 public:
38 enum StorageAccessPromptChoices { eAllow, eAllowAutoGrant };
40 // Grant the permission for aOrigin to have access to the first party storage.
41 // This methods can handle 2 different scenarios:
42 // - aParentContext is a 3rd party context, it opens an aOrigin window and the
43 // user interacts with it. We want to grant the permission at the
44 // combination: top-level + aParentWindow + aOrigin.
45 // Ex: example.net loads an iframe tracker.com, which opens a popup
46 // tracker.org and the user interacts with it. tracker.org is allowed if
47 // loaded by tracker.com when loaded by example.net.
48 // - aParentContext is a first party context and a 3rd party resource
49 // (probably becuase of a script) opens a popup and the user interacts with
50 // it. We want to grant the permission for the 3rd party context to have
51 // access to the first party stoage when loaded in aParentWindow. Ex:
52 // example.net import tracker.com/script.js which does opens a popup and the
53 // user interacts with it. tracker.com is allowed when loaded by
54 // example.net.
55 typedef MozPromise<int, bool, true> StorageAccessPermissionGrantPromise;
56 typedef std::function<RefPtr<StorageAccessPermissionGrantPromise>()>
57 PerformPermissionGrant;
58 [[nodiscard]] static RefPtr<StorageAccessPermissionGrantPromise>
59 AllowAccessForOnParentProcess(
60 nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext,
61 ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
62 const PerformPermissionGrant& aPerformFinalChecks = nullptr);
64 [[nodiscard]] static RefPtr<StorageAccessPermissionGrantPromise>
65 AllowAccessForOnChildProcess(
66 nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext,
67 ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
68 const PerformPermissionGrant& aPerformFinalChecks = nullptr);
70 // This function handles tasks that have to be done in the process
71 // of the window that we just grant permission for.
72 static void OnAllowAccessFor(
73 dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin,
74 uint32_t aCookieBehavior,
75 ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason);
77 // For IPC only.
78 typedef MozPromise<nsresult, bool, true> ParentAccessGrantPromise;
79 static RefPtr<ParentAccessGrantPromise> SaveAccessForOriginOnParentProcess(
80 nsIPrincipal* aParentPrincipal, nsIPrincipal* aTrackingPrincipal,
81 int aAllowMode, bool aFrameOnly,
82 uint64_t aExpirationTime =
83 StaticPrefs::privacy_restrict3rdpartystorage_expiration());
85 static RefPtr<ParentAccessGrantPromise> SaveAccessForOriginOnParentProcess(
86 uint64_t aTopLevelWindowId, dom::BrowsingContext* aParentContext,
87 nsIPrincipal* aTrackingPrincipal, int aAllowMode, bool aFrameOnly,
88 uint64_t aExpirationTime =
89 StaticPrefs::privacy_restrict3rdpartystorage_expiration());
91 // This function checks if the document has explicit permission either to
92 // allow or deny access to cookies. This may be because of the "cookie"
93 // permission or because the domain is on the ContentBlockingAllowList
94 // e.g. because the user flipped the sheild.
95 // This returns:
96 // Some(true) if unpartitioned cookies will be permitted
97 // Some(false) if unpartitioned cookies will be blocked
98 // None if it is not clear from permission alone what to do
99 static Maybe<bool> CheckCookiesPermittedDecidesStorageAccessAPI(
100 nsICookieJarSettings* aCookieJarSettings,
101 nsIPrincipal* aRequestingPrincipal);
103 // Calls CheckCookiesPermittedDecidesStorageAccessAPI in the Content Parent
104 // using aBrowsingContext's Top's Window Global's CookieJarSettings.
105 static RefPtr<MozPromise<Maybe<bool>, nsresult, true>>
106 AsyncCheckCookiesPermittedDecidesStorageAccessAPIOnChildProcess(
107 dom::BrowsingContext* aBrowsingContext,
108 nsIPrincipal* aRequestingPrincipal);
110 // This function checks if the browser settings give explicit permission
111 // either to allow or deny access to cookies. This only checks the
112 // cookieBehavior setting. This requires an additional bool to indicate
113 // whether or not the context considered is third-party. This returns:
114 // Some(true) if unpartitioned cookies will be permitted
115 // Some(false) if unpartitioned cookies will be blocked
116 // None if it is not clear from settings alone what to do
117 static Maybe<bool> CheckBrowserSettingsDecidesStorageAccessAPI(
118 nsICookieJarSettings* aCookieJarSettings, bool aThirdParty,
119 bool aIsOnThirdPartySkipList, bool aIsThirdPartyTracker);
121 // This function checks if the document's context (like if it is third-party
122 // or an iframe) gives an answer of how a the StorageAccessAPI call, that is
123 // meant to be called by an embedded third party, should return.
124 // This requires an argument that allows some checks to be run only if the
125 // caller of this function is performing a request for storage access.
126 // This returns:
127 // Some(true) if the calling context has access to cookies if it is not
128 // disallowed by the browser settings and cookie permissions
129 // Some(false) if the calling context should not have access to cookies if
130 // it is not expressly allowed by the browser settings and
131 // cookie permissions
132 // None if the calling context does not determine the document's access to
133 // unpartitioned cookies
134 static Maybe<bool> CheckCallingContextDecidesStorageAccessAPI(
135 dom::Document* aDocument, bool aRequestingStorageAccess);
137 // This function checks if the document's context (like if it is third-party
138 // or an iframe) gives an answer of how a the StorageAccessAPI call that is
139 // meant to be called in a top-level context, should return.
140 // This returns:
141 // Some(true) if the calling context indicates calls to the top-level
142 // API must resolve if it is not
143 // disallowed by the browser settings and cookie permissions
144 // Some(false) if the calling context must reject when calling top level
145 // portions of the API if it is not expressly allowed by the
146 // browser settings and cookie permissions
147 // None if the calling context does not determine the outcome of the
148 // document's use of the top-level portions of the Storage Access API.
149 static Maybe<bool> CheckSameSiteCallingContextDecidesStorageAccessAPI(
150 dom::Document* aDocument, bool aRequireUserActivation);
152 // This function checks if the document has already been granted or denied
153 // access to its unpartitioned cookies by the StorageAccessAPI
154 // This returns:
155 // Some(true) if the document has been granted access by the Storage Access
156 // API before
157 // Some(false) if the document has been denied access by the Storage Access
158 // API before
159 // None if the document has not been granted or denied access by the Storage
160 // Access API before
161 static Maybe<bool> CheckExistingPermissionDecidesStorageAccessAPI(
162 dom::Document* aDocument, bool aRequestingStorageAccess);
164 // This function performs the asynchronous portion of checking if requests
165 // for storage access will be successful or not. This includes calling
166 // Document member functions that creating a permission prompt request and
167 // trying to perform an "autogrant" if aRequireGrant is true.
168 // This will return a promise whose values correspond to those of a
169 // ContentBlocking::AllowAccessFor call that ends the function.
170 static RefPtr<StorageAccessPermissionGrantPromise>
171 RequestStorageAccessAsyncHelper(
172 dom::Document* aDocument, nsPIDOMWindowInner* aInnerWindow,
173 dom::BrowsingContext* aBrowsingContext, nsIPrincipal* aPrincipal,
174 bool aHasUserInteraction, bool aRequireUserInteraction, bool aFrameOnly,
175 ContentBlockingNotifier::StorageAccessPermissionGrantedReason aNotifier,
176 bool aRequireGrant);
178 private:
179 friend class dom::ContentParent;
181 // This function performs browser setting, cookie behavior and requesting
182 // context checks that might grant/reject storage access immediately using
183 // information provided by the inputs aPrincipal and aParentContext. To reduce
184 // redundancy the following out parameters with information also required in
185 // AllowAccessFor() are set in the function: aTrackingPrinciple,
186 // aTrackingOrigin, aTopLevelWindowId, aBehavior. If storage access can be
187 // granted/rejected due to settings/behavior returns a promise, else returns
188 // nullptr.
189 [[nodiscard]] static RefPtr<
190 StorageAccessAPIHelper::StorageAccessPermissionGrantPromise>
191 AllowAccessForHelper(
192 nsIPrincipal* aPrincipal, dom::BrowsingContext* aParentContext,
193 ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
194 nsCOMPtr<nsIPrincipal>* aTrackingPrincipal, nsACString& aTrackingOrigin,
195 uint64_t* aTopLevelWindowId, uint32_t* aBehavior);
197 [[nodiscard]] static RefPtr<StorageAccessPermissionGrantPromise>
198 CompleteAllowAccessForOnParentProcess(
199 dom::BrowsingContext* aParentContext, uint64_t aTopLevelWindowId,
200 nsIPrincipal* aTrackingPrincipal, const nsACString& aTrackingOrigin,
201 uint32_t aCookieBehavior,
202 ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
203 const PerformPermissionGrant& aPerformFinalChecks = nullptr);
205 [[nodiscard]] static RefPtr<StorageAccessPermissionGrantPromise>
206 CompleteAllowAccessForOnChildProcess(
207 dom::BrowsingContext* aParentContext, uint64_t aTopLevelWindowId,
208 nsIPrincipal* aTrackingPrincipal, const nsACString& aTrackingOrigin,
209 uint32_t aCookieBehavior,
210 ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason,
211 const PerformPermissionGrant& aPerformFinalChecks = nullptr);
213 static void UpdateAllowAccessOnCurrentProcess(
214 dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin);
216 static void UpdateAllowAccessOnParentProcess(
217 dom::BrowsingContext* aParentContext, const nsACString& aTrackingOrigin);
220 } // namespace mozilla
222 #endif // mozilla_antitrackingservice_h