Backed out 2 changesets (bug 1943998) for causing wd failures @ phases.py CLOSED...
[gecko.git] / netwerk / cookie / ThirdPartyCookieBlockingExceptions.cpp
blob4aac8ab3e07579857d3698963b77a9dcd6ff8c77
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "ThirdPartyCookieBlockingExceptions.h"
7 #include "mozilla/Components.h"
8 #include "mozilla/dom/BrowsingContext.h"
9 #include "mozilla/dom/CanonicalBrowsingContext.h"
10 #include "mozilla/dom/Promise.h"
11 #include "mozilla/dom/Promise-inl.h"
12 #include "mozilla/dom/WindowGlobalParent.h"
13 #include "mozilla/ErrorNames.h"
14 #include "mozilla/Logging.h"
16 #include "nsIEffectiveTLDService.h"
17 #include "nsIChannel.h"
19 namespace mozilla {
20 namespace net {
22 LazyLogModule g3PCBExceptionLog("3pcbexception");
24 void ThirdPartyCookieBlockingExceptions::Initialize() {
25 if (mIsInitialized) {
26 return;
29 // Get the remote third-party cookie blocking exception list service instance.
30 nsresult rv;
31 m3PCBExceptionService = do_GetService(
32 NS_NSITHIRDPARTYCOOKIEBLOCKINGEXCEPTIONLISTSERVICE_CONTRACTID, &rv);
33 NS_ENSURE_SUCCESS_VOID(rv);
35 RefPtr<mozilla::dom::Promise> initPromise;
36 rv = m3PCBExceptionService->Init(getter_AddRefs(initPromise));
37 NS_ENSURE_SUCCESS_VOID(rv);
39 // Bail out earlier if we don't have a init promise.
40 if (!initPromise) {
41 MOZ_LOG(g3PCBExceptionLog, LogLevel::Error,
42 ("Failed to initialize 3PCB exception service: no init promise"));
43 return;
46 initPromise->AddCallbacksWithCycleCollectedArgs(
47 [&self = *this](JSContext*, JS::Handle<JS::Value>,
48 mozilla::ErrorResult&) { self.mIsInitialized = true; },
49 [](JSContext*, JS::Handle<JS::Value>, mozilla::ErrorResult& error) {
50 nsresult rv = error.StealNSResult();
52 nsAutoCString name;
53 GetErrorName(rv, name);
55 MOZ_LOG(
56 g3PCBExceptionLog, LogLevel::Error,
57 ("Failed to initialize 3PCB exception service: %s", name.get()));
58 });
61 void ThirdPartyCookieBlockingExceptions::Shutdown() {
62 if (m3PCBExceptionService) {
63 Unused << m3PCBExceptionService->Shutdown();
64 m3PCBExceptionService = nullptr;
67 mIsInitialized = false;
70 void ThirdPartyCookieBlockingExceptions::Insert(const nsACString& aException) {
71 m3PCBExceptionsSet.Insert(aException);
74 void ThirdPartyCookieBlockingExceptions::Remove(const nsACString& aException) {
75 m3PCBExceptionsSet.Remove(aException);
78 bool ThirdPartyCookieBlockingExceptions::CheckWildcardException(
79 const nsACString& aThirdPartySite) {
80 nsAutoCString key;
81 Create3PCBExceptionKey("*"_ns, aThirdPartySite, key);
83 return m3PCBExceptionsSet.Contains(key);
86 bool ThirdPartyCookieBlockingExceptions::CheckException(
87 const nsACString& aFirstPartySite, const nsACString& aThirdPartySite) {
88 nsAutoCString key;
89 Create3PCBExceptionKey(aFirstPartySite, aThirdPartySite, key);
91 return m3PCBExceptionsSet.Contains(key);
94 bool ThirdPartyCookieBlockingExceptions::CheckExceptionForURIs(
95 nsIURI* aFirstPartyURI, nsIURI* aThirdPartyURI) {
96 MOZ_ASSERT(XRE_IsParentProcess());
97 NS_ENSURE_TRUE(aFirstPartyURI, false);
98 NS_ENSURE_TRUE(aThirdPartyURI, false);
100 if (!mIsInitialized) {
101 return false;
104 nsCOMPtr<nsIEffectiveTLDService> eTLDService =
105 mozilla::components::EffectiveTLD::Service();
106 NS_ENSURE_TRUE(eTLDService, false);
108 nsAutoCString thirdPartySite;
109 nsresult rv = eTLDService->GetSite(aThirdPartyURI, thirdPartySite);
110 NS_ENSURE_SUCCESS(rv, false);
112 bool isInExceptionList = CheckWildcardException(thirdPartySite);
114 if (isInExceptionList) {
115 return true;
118 nsAutoCString firstPartySite;
119 rv = eTLDService->GetSite(aFirstPartyURI, firstPartySite);
120 NS_ENSURE_SUCCESS(rv, false);
122 return CheckException(firstPartySite, thirdPartySite);
125 bool ThirdPartyCookieBlockingExceptions::CheckExceptionForChannel(
126 nsIChannel* aChannel) {
127 MOZ_ASSERT(XRE_IsParentProcess());
128 NS_ENSURE_TRUE(aChannel, false);
130 if (!mIsInitialized) {
131 return false;
134 nsCOMPtr<nsIEffectiveTLDService> eTLDService =
135 mozilla::components::EffectiveTLD::Service();
136 NS_ENSURE_TRUE(eTLDService, false);
138 nsCOMPtr<nsIURI> uri;
139 nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
140 NS_ENSURE_SUCCESS(rv, false);
142 nsAutoCString thirdPartySite;
143 rv = eTLDService->GetSite(uri, thirdPartySite);
144 NS_ENSURE_SUCCESS(rv, false);
146 bool isInExceptionList = CheckWildcardException(thirdPartySite);
148 if (isInExceptionList) {
149 return true;
152 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
154 RefPtr<dom::BrowsingContext> bc;
155 loadInfo->GetBrowsingContext(getter_AddRefs(bc));
156 if (!bc) {
157 bc = loadInfo->GetWorkerAssociatedBrowsingContext();
160 nsAutoCString firstPartySite;
162 // If the channel is not associated with a browsing context, we will try to
163 // get the first party site from the partition key.
164 if (!bc) {
165 nsCOMPtr<nsICookieJarSettings> cjs;
166 nsresult rv = loadInfo->GetCookieJarSettings(getter_AddRefs(cjs));
167 NS_ENSURE_SUCCESS(rv, false);
169 nsAutoString partitionKey;
170 rv = cjs->GetPartitionKey(partitionKey);
171 NS_ENSURE_SUCCESS(rv, false);
173 nsAutoString site;
174 if (!OriginAttributes::ExtractSiteFromPartitionKey(partitionKey, site)) {
175 return false;
178 firstPartySite.Assign(NS_ConvertUTF16toUTF8(site));
179 } else {
180 RefPtr<dom::WindowGlobalParent> topWGP =
181 bc->Top()->Canonical()->GetCurrentWindowGlobal();
182 if (!topWGP) {
183 return false;
186 nsCOMPtr<nsIPrincipal> topPrincipal = topWGP->DocumentPrincipal();
188 // If the top window is an about page, we don't need to do anything. This
189 // could happen when fetching system resources, such as pocket's images
190 if (topPrincipal->SchemeIs("about")) {
191 return false;
194 nsCOMPtr<nsIURI> topURI = topPrincipal->GetURI();
196 nsAutoCString site;
197 nsresult rv = eTLDService->GetSite(topURI, firstPartySite);
198 NS_ENSURE_SUCCESS(rv, false);
201 return CheckException(firstPartySite, thirdPartySite);
204 void ThirdPartyCookieBlockingExceptions::GetExceptions(
205 nsTArray<nsCString>& aExceptions) {
206 aExceptions.Clear();
208 for (const auto& host : m3PCBExceptionsSet) {
209 aExceptions.AppendElement(host);
213 } // namespace net
214 } // namespace mozilla