From a95fb737fdf99e3a895f4fecd28a4047c45b7a79 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari <ehsan@mozilla.com> Date: Mon, 9 Mar 2020 18:12:35 +0000 Subject: [PATCH] Bug 1620322 - Part 6: Refactor the code related to user interactions out of AntiTrackingCommon.cpp; r=baku Differential Revision: https://phabricator.services.mozilla.com/D65819 --HG-- extra : moz-landing-system : lando --- dom/base/Document.cpp | 5 +- dom/ipc/ContentParent.cpp | 3 +- .../permissions/nsPermissionManager.cpp | 2 +- .../antitracking/AntiTrackingCommon.cpp | 69 +-------------- .../antitracking/AntiTrackingCommon.h | 6 -- .../AntiTrackingRedirectHeuristic.cpp | 3 +- .../ContentBlockingUserInteraction.cpp | 84 +++++++++++++++++++ .../ContentBlockingUserInteraction.h | 29 +++++++ .../antitracking/SettingsChangeObserver.cpp | 2 +- toolkit/components/antitracking/moz.build | 2 + 10 files changed, 127 insertions(+), 78 deletions(-) create mode 100644 toolkit/components/antitracking/ContentBlockingUserInteraction.cpp create mode 100644 toolkit/components/antitracking/ContentBlockingUserInteraction.h diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 55e35795cbbf..24d4affb78cb 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -17,6 +17,7 @@ #include "mozilla/AutoRestore.h" #include "mozilla/BinarySearch.h" #include "mozilla/ContentBlockingAllowList.h" +#include "mozilla/ContentBlockingUserInteraction.h" #include "mozilla/CSSEnabledState.h" #include "mozilla/DebugOnly.h" #include "mozilla/EditorCommands.h" @@ -15167,7 +15168,7 @@ class UserIntractionTimer final : public Runnable, // If the document is not gone, let's reset its timer flag. nsCOMPtr<Document> document = do_QueryReferent(mDocument); if (document) { - AntiTrackingCommon::StoreUserInteractionFor(mPrincipal); + ContentBlockingUserInteraction::Observe(mPrincipal); document->ResetUserInteractionTimer(); } } @@ -15213,7 +15214,7 @@ void Document::MaybeStoreUserInteractionAsPermission() { if (!mUserHasInteracted) { // First interaction, let's store this info now. - AntiTrackingCommon::StoreUserInteractionFor(NodePrincipal()); + ContentBlockingUserInteraction::Observe(NodePrincipal()); return; } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 7bd19d2a1d1d..cbb6e9d67617 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -43,6 +43,7 @@ #include "mozilla/AntiTrackingCommon.h" #include "mozilla/BasePrincipal.h" #include "mozilla/BenchmarkStorageParent.h" +#include "mozilla/ContentBlockingUserInteraction.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/Components.h" #include "mozilla/DataStorage.h" @@ -5837,7 +5838,7 @@ ContentParent::RecvFirstPartyStorageAccessGrantedForOrigin( mozilla::ipc::IPCResult ContentParent::RecvStoreUserInteractionAsPermission( const Principal& aPrincipal) { - AntiTrackingCommon::StoreUserInteractionFor(aPrincipal); + ContentBlockingUserInteraction::Observe(aPrincipal); return IPC_OK(); } diff --git a/extensions/permissions/nsPermissionManager.cpp b/extensions/permissions/nsPermissionManager.cpp index 02f18c7f13c5..6709c5342789 100644 --- a/extensions/permissions/nsPermissionManager.cpp +++ b/extensions/permissions/nsPermissionManager.cpp @@ -5,9 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Attributes.h" -#include "mozilla/AntiTrackingCommon.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/BasePrincipal.h" +#include "mozilla/ContentBlockingUserInteraction.h" #include "mozilla/ContentPrincipal.h" #include "mozilla/DebugOnly.h" #include "mozilla/Pair.h" diff --git a/toolkit/components/antitracking/AntiTrackingCommon.cpp b/toolkit/components/antitracking/AntiTrackingCommon.cpp index c1f331659212..37f150d0066a 100644 --- a/toolkit/components/antitracking/AntiTrackingCommon.cpp +++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp @@ -9,6 +9,7 @@ #include "AntiTrackingUtils.h" #include "mozilla/ContentBlockingAllowList.h" +#include "mozilla/ContentBlockingUserInteraction.h" #include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/CanonicalBrowsingContext.h" #include "mozilla/dom/ContentChild.h" @@ -45,7 +46,6 @@ #include "nsPIDOMWindow.h" #include "nsPrintfCString.h" #include "nsScriptSecurityManager.h" -#include "prtime.h" namespace mozilla { @@ -573,7 +573,8 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor( "privacy.restrict3rdpartystorage." "userInteractionRequiredForHosts", &isInPrefList); - if (isInPrefList && !HasUserInteraction(trackingPrincipal)) { + if (isInPrefList && + !ContentBlockingUserInteraction::Exists(trackingPrincipal)) { LOG_PRIN(("Tracking principal (%s) hasn't been interacted with before, " "refusing to add a first-party storage permission to access it", _spec), @@ -1296,67 +1297,3 @@ bool AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor( parentPrincipal, type, nsContentUtils::IsInPrivateBrowsing(parentDocument), nullptr, 0); } - -/* static */ -void AntiTrackingCommon::StoreUserInteractionFor(nsIPrincipal* aPrincipal) { - if (!aPrincipal) { - // The content process may have sent us garbage data. - return; - } - - if (XRE_IsParentProcess()) { - LOG_PRIN(("Saving the userInteraction for %s", _spec), aPrincipal); - - nsPermissionManager* permManager = nsPermissionManager::GetInstance(); - if (NS_WARN_IF(!permManager)) { - LOG(("Permission manager is null, bailing out early")); - return; - } - - // Remember that this pref is stored in seconds! - uint32_t expirationType = nsIPermissionManager::EXPIRE_TIME; - uint32_t expirationTime = - StaticPrefs::privacy_userInteraction_expiration() * 1000; - int64_t when = (PR_Now() / PR_USEC_PER_MSEC) + expirationTime; - - uint32_t privateBrowsingId = 0; - nsresult rv = aPrincipal->GetPrivateBrowsingId(&privateBrowsingId); - if (!NS_WARN_IF(NS_FAILED(rv)) && privateBrowsingId > 0) { - // If we are coming from a private window, make sure to store a - // session-only permission which won't get persisted to disk. - expirationType = nsIPermissionManager::EXPIRE_SESSION; - when = 0; - } - - rv = permManager->AddFromPrincipal(aPrincipal, USER_INTERACTION_PERM, - nsIPermissionManager::ALLOW_ACTION, - expirationType, when); - Unused << NS_WARN_IF(NS_FAILED(rv)); - return; - } - - ContentChild* cc = ContentChild::GetSingleton(); - MOZ_ASSERT(cc); - - LOG_PRIN(("Asking the parent process to save the user-interaction for us: %s", - _spec), - aPrincipal); - cc->SendStoreUserInteractionAsPermission(IPC::Principal(aPrincipal)); -} - -/* static */ -bool AntiTrackingCommon::HasUserInteraction(nsIPrincipal* aPrincipal) { - nsPermissionManager* permManager = nsPermissionManager::GetInstance(); - if (NS_WARN_IF(!permManager)) { - return false; - } - - uint32_t result = 0; - nsresult rv = permManager->TestPermissionWithoutDefaultsFromPrincipal( - aPrincipal, USER_INTERACTION_PERM, &result); - if (NS_WARN_IF(NS_FAILED(rv))) { - return false; - } - - return result == nsIPermissionManager::ALLOW_ACTION; -} diff --git a/toolkit/components/antitracking/AntiTrackingCommon.h b/toolkit/components/antitracking/AntiTrackingCommon.h index 8426d6e3e885..ed0456f23083 100644 --- a/toolkit/components/antitracking/AntiTrackingCommon.h +++ b/toolkit/components/antitracking/AntiTrackingCommon.h @@ -13,8 +13,6 @@ #include "mozilla/RefPtr.h" #include "mozilla/StaticPrefs_privacy.h" -#define USER_INTERACTION_PERM NS_LITERAL_CSTRING("storageAccessAPI") - class nsIChannel; class nsICookieJarSettings; class nsIPermission; @@ -101,10 +99,6 @@ class AntiTrackingCommon final { ContentBlockingNotifier::StorageAccessGrantedReason aReason, const PerformFinalChecks& aPerformFinalChecks = nullptr); - static void StoreUserInteractionFor(nsIPrincipal* aPrincipal); - - static bool HasUserInteraction(nsIPrincipal* aPrincipal); - // For IPC only. typedef MozPromise<nsresult, bool, true> FirstPartyStorageAccessGrantPromise; static RefPtr<FirstPartyStorageAccessGrantPromise> diff --git a/toolkit/components/antitracking/AntiTrackingRedirectHeuristic.cpp b/toolkit/components/antitracking/AntiTrackingRedirectHeuristic.cpp index c1ea54eb3f24..64b18bea372b 100644 --- a/toolkit/components/antitracking/AntiTrackingRedirectHeuristic.cpp +++ b/toolkit/components/antitracking/AntiTrackingRedirectHeuristic.cpp @@ -8,6 +8,7 @@ #include "AntiTrackingRedirectHeuristic.h" #include "AntiTrackingCommon.h" #include "ContentBlockingAllowList.h" +#include "ContentBlockingUserInteraction.h" #include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/Document.h" @@ -136,7 +137,7 @@ void AntiTrackingRedirectHeuristic(nsIChannel* aOldChannel, nsIURI* aOldURI, return; } - if (!AntiTrackingCommon::HasUserInteraction(trackingPrincipal)) { + if (!ContentBlockingUserInteraction::Exists(trackingPrincipal)) { LOG_SPEC2(("Ignoring redirect for %s to %s because no user-interaction on " "tracker", _spec1, _spec2), diff --git a/toolkit/components/antitracking/ContentBlockingUserInteraction.cpp b/toolkit/components/antitracking/ContentBlockingUserInteraction.cpp new file mode 100644 index 000000000000..c8b60e8b34c2 --- /dev/null +++ b/toolkit/components/antitracking/ContentBlockingUserInteraction.cpp @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "AntiTrackingLog.h" +#include "ContentBlockingUserInteraction.h" +#include "AntiTrackingCommon.h" +#include "AntiTrackingUtils.h" + +#include "mozilla/dom/ContentChild.h" +#include "nsIPrincipal.h" +#include "nsPermissionManager.h" +#include "nsXULAppAPI.h" +#include "prtime.h" + +namespace mozilla { + +/* static */ +void ContentBlockingUserInteraction::Observe(nsIPrincipal* aPrincipal) { + if (!aPrincipal) { + // The content process may have sent us garbage data. + return; + } + + if (XRE_IsParentProcess()) { + LOG_PRIN(("Saving the userInteraction for %s", _spec), aPrincipal); + + nsPermissionManager* permManager = nsPermissionManager::GetInstance(); + if (NS_WARN_IF(!permManager)) { + LOG(("Permission manager is null, bailing out early")); + return; + } + + // Remember that this pref is stored in seconds! + uint32_t expirationType = nsIPermissionManager::EXPIRE_TIME; + uint32_t expirationTime = + StaticPrefs::privacy_userInteraction_expiration() * 1000; + int64_t when = (PR_Now() / PR_USEC_PER_MSEC) + expirationTime; + + uint32_t privateBrowsingId = 0; + nsresult rv = aPrincipal->GetPrivateBrowsingId(&privateBrowsingId); + if (!NS_WARN_IF(NS_FAILED(rv)) && privateBrowsingId > 0) { + // If we are coming from a private window, make sure to store a + // session-only permission which won't get persisted to disk. + expirationType = nsIPermissionManager::EXPIRE_SESSION; + when = 0; + } + + rv = permManager->AddFromPrincipal(aPrincipal, USER_INTERACTION_PERM, + nsIPermissionManager::ALLOW_ACTION, + expirationType, when); + Unused << NS_WARN_IF(NS_FAILED(rv)); + return; + } + + dom::ContentChild* cc = dom::ContentChild::GetSingleton(); + MOZ_ASSERT(cc); + + LOG_PRIN(("Asking the parent process to save the user-interaction for us: %s", + _spec), + aPrincipal); + cc->SendStoreUserInteractionAsPermission(IPC::Principal(aPrincipal)); +} + +/* static */ +bool ContentBlockingUserInteraction::Exists(nsIPrincipal* aPrincipal) { + nsPermissionManager* permManager = nsPermissionManager::GetInstance(); + if (NS_WARN_IF(!permManager)) { + return false; + } + + uint32_t result = 0; + nsresult rv = permManager->TestPermissionWithoutDefaultsFromPrincipal( + aPrincipal, USER_INTERACTION_PERM, &result); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + + return result == nsIPermissionManager::ALLOW_ACTION; +} + +} // namespace mozilla diff --git a/toolkit/components/antitracking/ContentBlockingUserInteraction.h b/toolkit/components/antitracking/ContentBlockingUserInteraction.h new file mode 100644 index 000000000000..31d105702bac --- /dev/null +++ b/toolkit/components/antitracking/ContentBlockingUserInteraction.h @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_contentblockinguserinteraction_h +#define mozilla_contentblockinguserinteraction_h + +#define USER_INTERACTION_PERM NS_LITERAL_CSTRING("storageAccessAPI") + +class nsIPrincipal; + +namespace mozilla { + +class ContentBlockingUserInteraction final { + public: + // Used to remember that we observed a user interaction that is significant + // for content blocking. + static void Observe(nsIPrincipal* aPrincipal); + + // Used to query whether we've observed a user interaction that is significant + // for content blocking for the given principal in the past. + static bool Exists(nsIPrincipal* aPrincipal); +}; + +} // namespace mozilla + +#endif // mozilla_contentblockinguserinteraction_h diff --git a/toolkit/components/antitracking/SettingsChangeObserver.cpp b/toolkit/components/antitracking/SettingsChangeObserver.cpp index d4bdb2c39711..eb2ba5bbd334 100644 --- a/toolkit/components/antitracking/SettingsChangeObserver.cpp +++ b/toolkit/components/antitracking/SettingsChangeObserver.cpp @@ -5,7 +5,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SettingsChangeObserver.h" -#include "AntiTrackingCommon.h" +#include "ContentBlockingUserInteraction.h" #include "mozilla/Services.h" #include "mozilla/Preferences.h" diff --git a/toolkit/components/antitracking/moz.build b/toolkit/components/antitracking/moz.build index 7078a77d7db1..fa654508bb58 100644 --- a/toolkit/components/antitracking/moz.build +++ b/toolkit/components/antitracking/moz.build @@ -37,6 +37,7 @@ EXPORTS.mozilla = [ 'AntiTrackingUtils.h', 'ContentBlockingAllowList.h', 'ContentBlockingNotifier.h', + 'ContentBlockingUserInteraction.h', 'StorageAccess.h', 'StoragePrincipalHelper.h', 'URLDecorationStripper.h', @@ -48,6 +49,7 @@ UNIFIED_SOURCES += [ 'AntiTrackingUtils.cpp', 'ContentBlockingAllowList.cpp', 'ContentBlockingNotifier.cpp', + 'ContentBlockingUserInteraction.cpp', 'SettingsChangeObserver.cpp', 'StorageAccess.cpp', 'StoragePrincipalHelper.cpp',