Bug 1941046 - Part 4: Send a callback request for impression and clicks of MARS Top...
[gecko.git] / dom / quota / PrincipalUtils.cpp
blob604f009c85599f3ef4ac4390ecd4f091a7de7c4d
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 #include "mozilla/dom/quota/PrincipalUtils.h"
9 #include "mozilla/SystemPrincipal.h"
10 #include "mozilla/dom/quota/Constants.h"
11 #include "mozilla/dom/quota/CommonMetadata.h"
12 #include "mozilla/dom/quota/QuotaCommon.h"
13 #include "mozilla/dom/quota/QuotaManager.h"
14 #include "mozilla/dom/quota/ResultExtensions.h"
15 #include "mozilla/ipc/PBackgroundSharedTypes.h"
16 #include "nsIScriptObjectPrincipal.h"
17 #include "nsNetUtil.h"
18 #include "nsPIDOMWindow.h"
19 #include "OriginParser.h"
21 namespace mozilla::dom::quota {
23 using namespace mozilla::ipc;
25 bool IsPrincipalInfoValid(const PrincipalInfo& aPrincipalInfo) {
26 switch (aPrincipalInfo.type()) {
27 // A system principal is acceptable.
28 case PrincipalInfo::TSystemPrincipalInfo: {
29 return true;
32 // Validate content principals to ensure that the spec, originNoSuffix and
33 // baseDomain are sane.
34 case PrincipalInfo::TContentPrincipalInfo: {
35 const ContentPrincipalInfo& info =
36 aPrincipalInfo.get_ContentPrincipalInfo();
38 // Verify the principal spec parses.
39 nsCOMPtr<nsIURI> uri;
40 QM_TRY(MOZ_TO_RESULT(NS_NewURI(getter_AddRefs(uri), info.spec())), false);
42 nsCOMPtr<nsIPrincipal> principal =
43 BasePrincipal::CreateContentPrincipal(uri, info.attrs());
44 QM_TRY(MOZ_TO_RESULT(principal), false);
46 // Verify the principal originNoSuffix matches spec.
47 QM_TRY_INSPECT(const auto& originNoSuffix,
48 MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsAutoCString, principal,
49 GetOriginNoSuffix),
50 false);
52 if (NS_WARN_IF(originNoSuffix != info.originNoSuffix())) {
53 QM_WARNING("originNoSuffix (%s) doesn't match passed one (%s)!",
54 originNoSuffix.get(), info.originNoSuffix().get());
55 return false;
58 if (NS_WARN_IF(info.originNoSuffix().EqualsLiteral(kChromeOrigin))) {
59 return false;
62 if (NS_WARN_IF(info.originNoSuffix().FindChar('^', 0) != -1)) {
63 QM_WARNING("originNoSuffix (%s) contains the '^' character!",
64 info.originNoSuffix().get());
65 return false;
68 // Verify the principal baseDomain exists.
69 if (NS_WARN_IF(info.baseDomain().IsVoid())) {
70 return false;
73 // Verify the principal baseDomain matches spec.
74 QM_TRY_INSPECT(const auto& baseDomain,
75 MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsAutoCString, principal,
76 GetBaseDomain),
77 false);
79 if (NS_WARN_IF(baseDomain != info.baseDomain())) {
80 QM_WARNING("baseDomain (%s) doesn't match passed one (%s)!",
81 baseDomain.get(), info.baseDomain().get());
82 return false;
85 return true;
88 default: {
89 break;
93 // Null and expanded principals are not acceptable.
94 return false;
97 Result<PrincipalMetadata, nsresult> GetInfoFromValidatedPrincipalInfo(
98 QuotaManager& aQuotaManager, const PrincipalInfo& aPrincipalInfo) {
99 MOZ_ASSERT(IsPrincipalInfoValid(aPrincipalInfo));
101 switch (aPrincipalInfo.type()) {
102 case PrincipalInfo::TSystemPrincipalInfo: {
103 return GetInfoForChrome();
106 case PrincipalInfo::TContentPrincipalInfo: {
107 const ContentPrincipalInfo& info =
108 aPrincipalInfo.get_ContentPrincipalInfo();
110 nsCString suffix;
111 info.attrs().CreateSuffix(suffix);
113 nsCString origin = info.originNoSuffix() + suffix;
115 if (IsUUIDOrigin(origin)) {
116 QM_TRY_INSPECT(const auto& originalOrigin,
117 aQuotaManager.GetOriginFromStorageOrigin(origin));
119 nsCOMPtr<nsIPrincipal> principal =
120 BasePrincipal::CreateContentPrincipal(originalOrigin);
121 QM_TRY(MOZ_TO_RESULT(principal));
123 PrincipalInfo principalInfo;
124 QM_TRY(
125 MOZ_TO_RESULT(PrincipalToPrincipalInfo(principal, &principalInfo)));
127 return GetInfoFromValidatedPrincipalInfo(aQuotaManager, principalInfo);
130 PrincipalMetadata principalMetadata;
132 principalMetadata.mSuffix = suffix;
134 principalMetadata.mGroup = info.baseDomain() + suffix;
136 principalMetadata.mOrigin = origin;
138 if (info.attrs().IsPrivateBrowsing()) {
139 QM_TRY_UNWRAP(principalMetadata.mStorageOrigin,
140 aQuotaManager.EnsureStorageOriginFromOrigin(origin));
141 } else {
142 principalMetadata.mStorageOrigin = origin;
145 principalMetadata.mIsPrivate = info.attrs().IsPrivateBrowsing();
147 return principalMetadata;
150 default: {
151 MOZ_ASSERT_UNREACHABLE("Should never get here!");
152 return Err(NS_ERROR_UNEXPECTED);
157 nsAutoCString GetGroupFromValidatedPrincipalInfo(
158 const PrincipalInfo& aPrincipalInfo) {
159 MOZ_ASSERT(IsPrincipalInfoValid(aPrincipalInfo));
161 switch (aPrincipalInfo.type()) {
162 case PrincipalInfo::TSystemPrincipalInfo: {
163 return nsAutoCString{GetGroupForChrome()};
166 case PrincipalInfo::TContentPrincipalInfo: {
167 const ContentPrincipalInfo& info =
168 aPrincipalInfo.get_ContentPrincipalInfo();
170 nsAutoCString suffix;
172 info.attrs().CreateSuffix(suffix);
174 return info.baseDomain() + suffix;
177 default: {
178 MOZ_CRASH("Should never get here!");
183 nsAutoCString GetOriginFromValidatedPrincipalInfo(
184 const PrincipalInfo& aPrincipalInfo) {
185 MOZ_ASSERT(IsPrincipalInfoValid(aPrincipalInfo));
187 switch (aPrincipalInfo.type()) {
188 case PrincipalInfo::TSystemPrincipalInfo: {
189 return nsAutoCString{GetOriginForChrome()};
192 case PrincipalInfo::TContentPrincipalInfo: {
193 const ContentPrincipalInfo& info =
194 aPrincipalInfo.get_ContentPrincipalInfo();
196 nsAutoCString suffix;
198 info.attrs().CreateSuffix(suffix);
200 return info.originNoSuffix() + suffix;
203 default: {
204 MOZ_CRASH("Should never get here!");
209 Result<PrincipalMetadata, nsresult> GetInfoFromPrincipal(
210 nsIPrincipal* aPrincipal) {
211 MOZ_ASSERT(aPrincipal);
213 if (aPrincipal->IsSystemPrincipal()) {
214 return GetInfoForChrome();
217 if (aPrincipal->GetIsNullPrincipal()) {
218 NS_WARNING("IndexedDB not supported from this principal!");
219 return Err(NS_ERROR_FAILURE);
222 PrincipalMetadata principalMetadata;
224 QM_TRY(MOZ_TO_RESULT(aPrincipal->GetOrigin(principalMetadata.mOrigin)));
226 if (principalMetadata.mOrigin.EqualsLiteral(kChromeOrigin)) {
227 NS_WARNING("Non-chrome principal can't use chrome origin!");
228 return Err(NS_ERROR_FAILURE);
231 aPrincipal->OriginAttributesRef().CreateSuffix(principalMetadata.mSuffix);
233 nsAutoCString baseDomain;
234 QM_TRY(MOZ_TO_RESULT(aPrincipal->GetBaseDomain(baseDomain)));
236 MOZ_ASSERT(!baseDomain.IsEmpty());
238 principalMetadata.mGroup = baseDomain + principalMetadata.mSuffix;
240 principalMetadata.mStorageOrigin = principalMetadata.mOrigin;
242 principalMetadata.mIsPrivate = aPrincipal->GetIsInPrivateBrowsing();
244 return principalMetadata;
247 Result<PrincipalMetadata, nsresult> GetInfoFromWindow(
248 nsPIDOMWindowOuter* aWindow) {
249 MOZ_ASSERT(NS_IsMainThread());
250 MOZ_ASSERT(aWindow);
252 nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
253 QM_TRY(OkIf(sop), Err(NS_ERROR_FAILURE));
255 nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
256 QM_TRY(OkIf(principal), Err(NS_ERROR_FAILURE));
258 return GetInfoFromPrincipal(principal);
261 Result<nsAutoCString, nsresult> GetOriginFromPrincipal(
262 nsIPrincipal* aPrincipal) {
263 MOZ_ASSERT(NS_IsMainThread());
264 MOZ_ASSERT(aPrincipal);
266 if (aPrincipal->IsSystemPrincipal()) {
267 return nsAutoCString{GetOriginForChrome()};
270 if (aPrincipal->GetIsNullPrincipal()) {
271 NS_WARNING("IndexedDB not supported from this principal!");
272 return Err(NS_ERROR_FAILURE);
275 QM_TRY_UNWRAP(const auto origin, MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(
276 nsAutoCString, aPrincipal, GetOrigin));
278 if (origin.EqualsLiteral(kChromeOrigin)) {
279 NS_WARNING("Non-chrome principal can't use chrome origin!");
280 return Err(NS_ERROR_FAILURE);
283 return origin;
286 Result<nsAutoCString, nsresult> GetOriginFromWindow(
287 nsPIDOMWindowOuter* aWindow) {
288 MOZ_ASSERT(NS_IsMainThread());
289 MOZ_ASSERT(aWindow);
291 nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
292 QM_TRY(OkIf(sop), Err(NS_ERROR_FAILURE));
294 nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
295 QM_TRY(OkIf(principal), Err(NS_ERROR_FAILURE));
297 QM_TRY_RETURN(GetOriginFromPrincipal(principal));
300 PrincipalMetadata GetInfoForChrome() {
301 return {{},
302 GetGroupForChrome(),
303 GetOriginForChrome(),
304 GetOriginForChrome(),
305 false};
308 nsLiteralCString GetGroupForChrome() { return nsLiteralCString{kChromeOrigin}; }
310 nsLiteralCString GetOriginForChrome() {
311 return nsLiteralCString{kChromeOrigin};
314 } // namespace mozilla::dom::quota