tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PrivateAttribution.cpp (4377B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      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/. */
      6 
      7 #include "PrivateAttribution.h"
      8 
      9 #include "mozilla/Components.h"
     10 #include "mozilla/StaticPrefs_datareporting.h"
     11 #include "mozilla/dom/BindingUtils.h"
     12 #include "mozilla/dom/ContentChild.h"
     13 #include "mozilla/dom/PrivateAttributionBinding.h"
     14 #include "nsIGlobalObject.h"
     15 #include "nsIPrivateAttributionService.h"
     16 #include "nsURLHelper.h"
     17 #include "nsXULAppAPI.h"
     18 
     19 namespace mozilla::dom {
     20 
     21 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PrivateAttribution, mOwner)
     22 
     23 PrivateAttribution::PrivateAttribution(nsIGlobalObject* aGlobal)
     24    : mOwner(aGlobal) {
     25  MOZ_ASSERT(aGlobal);
     26 }
     27 
     28 JSObject* PrivateAttribution::WrapObject(JSContext* aCx,
     29                                         JS::Handle<JSObject*> aGivenProto) {
     30  return PrivateAttribution_Binding::Wrap(aCx, this, aGivenProto);
     31 }
     32 
     33 PrivateAttribution::~PrivateAttribution() = default;
     34 
     35 bool PrivateAttribution::ShouldRecord() {
     36 #ifdef MOZ_TELEMETRY_REPORTING
     37  return (StaticPrefs::dom_private_attribution_submission_enabled() &&
     38          StaticPrefs::datareporting_healthreport_uploadEnabled());
     39 #else
     40  return false;
     41 #endif
     42 }
     43 
     44 bool PrivateAttribution::GetSourceHostIfNonPrivate(nsACString& aSourceHost,
     45                                                   ErrorResult& aRv) {
     46  MOZ_ASSERT(mOwner);
     47  nsIPrincipal* prin = mOwner->PrincipalOrNull();
     48  if (!prin || NS_FAILED(prin->GetHost(aSourceHost))) {
     49    aRv.ThrowInvalidStateError("Couldn't get source host");
     50    return false;
     51  }
     52  return !prin->GetIsInPrivateBrowsing();
     53 }
     54 
     55 [[nodiscard]] static bool ValidateHost(const nsACString& aHost,
     56                                       ErrorResult& aRv) {
     57  if (!net_IsValidDNSHost(aHost)) {
     58    aRv.ThrowSyntaxError(aHost + " is not a valid host name"_ns);
     59    return false;
     60  }
     61  return true;
     62 }
     63 
     64 void PrivateAttribution::SaveImpression(
     65    const PrivateAttributionImpressionOptions& aOptions, ErrorResult& aRv) {
     66  nsAutoCString source;
     67  if (!GetSourceHostIfNonPrivate(source, aRv)) {
     68    return;
     69  }
     70 
     71  if (!ValidateHost(aOptions.mTarget, aRv)) {
     72    return;
     73  }
     74 
     75  if (!ShouldRecord()) {
     76    return;
     77  }
     78 
     79  if (XRE_IsParentProcess()) {
     80    nsCOMPtr<nsIPrivateAttributionService> pa =
     81        components::PrivateAttribution::Service();
     82    if (NS_WARN_IF(!pa)) {
     83      return;
     84    }
     85    pa->OnAttributionEvent(source, GetEnumString(aOptions.mType),
     86                           aOptions.mIndex, aOptions.mAd, aOptions.mTarget);
     87    return;
     88  }
     89 
     90  auto* content = ContentChild::GetSingleton();
     91  if (NS_WARN_IF(!content)) {
     92    return;
     93  }
     94  content->SendAttributionEvent(source, aOptions.mType, aOptions.mIndex,
     95                                aOptions.mAd, aOptions.mTarget);
     96 }
     97 
     98 void PrivateAttribution::MeasureConversion(
     99    const PrivateAttributionConversionOptions& aOptions, ErrorResult& aRv) {
    100  nsAutoCString source;
    101  if (!GetSourceHostIfNonPrivate(source, aRv)) {
    102    return;
    103  }
    104  for (const nsACString& host : aOptions.mSources) {
    105    if (!ValidateHost(host, aRv)) {
    106      return;
    107    }
    108  }
    109 
    110  if (!ShouldRecord()) {
    111    return;
    112  }
    113 
    114  if (XRE_IsParentProcess()) {
    115    nsCOMPtr<nsIPrivateAttributionService> pa =
    116        components::PrivateAttribution::Service();
    117    if (NS_WARN_IF(!pa)) {
    118      return;
    119    }
    120    pa->OnAttributionConversion(
    121        source, aOptions.mTask, aOptions.mHistogramSize,
    122        aOptions.mLookbackDays.WasPassed() ? aOptions.mLookbackDays.Value() : 0,
    123        aOptions.mImpression.WasPassed()
    124            ? GetEnumString(aOptions.mImpression.Value())
    125            : EmptyCString(),
    126        aOptions.mAds, aOptions.mSources);
    127    return;
    128  }
    129 
    130  auto* content = ContentChild::GetSingleton();
    131  if (NS_WARN_IF(!content)) {
    132    return;
    133  }
    134  content->SendAttributionConversion(
    135      source, aOptions.mTask, aOptions.mHistogramSize,
    136      aOptions.mLookbackDays.WasPassed() ? Some(aOptions.mLookbackDays.Value())
    137                                         : Nothing(),
    138      aOptions.mImpression.WasPassed() ? Some(aOptions.mImpression.Value())
    139                                       : Nothing(),
    140      aOptions.mAds, aOptions.mSources);
    141 }
    142 
    143 }  // namespace mozilla::dom