Add cache support to the AuctionWorkletService Mojo scoring signals API
Version 2 of the Protected Audiences trusted signals API uses encrypted requests to and responses from a TEE, which cannot be cached using HTTP semantics because of the layer of encryption on top of HTTPS. To solve this, we're implementing a browser side cache which the worklet service can pull directly from. This CL plumbs through the IDs needed to access the cache through the ScoreAd() calls. These IDs are passed through (already wired up) pipes to fetch the signals needed for each score ad call. These pipes are origin bound, so the browser-side can detect if a worklet is requesting signals not bound to it. Additionally, this CL adds a Mojo API allowing the seller to indicate when the browser process can request signals, in the case the signals URL is cross-origin to the seller. To get this information, the worklet process requests the script it will run, and parses a special HTTP header to determine what origins it can receive signals from, compares it against the trusted signals URL, and returns whether the origin of the trusted scoring signals URL appears in that list of origins. This needs to be done before the ScoreAd() call, so a new pipe is passed in to handle returning this information, passed in when a seller worklet is constructed. Bug: 333445540 Change-Id: I9eed83b4dc6f71183ca442b4c4be29d45a454f44 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5996171 Commit-Queue: mmenke <mmenke@chromium.org> Reviewed-by: Dominic Farolino <dom@chromium.org> Reviewed-by: Russ Hamilton <behamilton@google.com> Cr-Commit-Position: refs/heads/main@{#1382489}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
f6031918d8
commit
dd984fd6ea
content
browser
interest_group
services
@ -168,7 +168,9 @@ class TestAuctionProcessManager
|
||||
auction_worklet::mojom::AuctionWorkletPermissionsPolicyStatePtr
|
||||
permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_id,
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key) override {
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
trusted_signals_url_allowed) override {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
|
@ -613,7 +613,9 @@ void AuctionWorkletManager::WorkletOwner::LoadWorkletIfReady(
|
||||
GetAuctionWorkletPermissionsPolicyState(delegate->GetFrame(),
|
||||
worklet_info_.script_url),
|
||||
worklet_info_.experiment_group_id,
|
||||
std::move(trusted_signals_kvv2_public_key_));
|
||||
std::move(trusted_signals_kvv2_public_key_),
|
||||
mojo::PendingRemote<
|
||||
auction_worklet::mojom::LoadSellerWorkletClient>());
|
||||
seller_worklet_.set_disconnect_with_reason_handler(base::BindOnce(
|
||||
&WorkletOwner::OnWorkletDisconnected, base::Unretained(this)));
|
||||
break;
|
||||
|
@ -384,6 +384,8 @@ class MockSellerWorklet : public auction_worklet::mojom::SellerWorklet {
|
||||
const std::optional<blink::AdCurrency>& bid_currency,
|
||||
const blink::AuctionConfig::NonSharedParams&
|
||||
auction_ad_config_non_shared_params,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr
|
||||
trusted_signals_cache_key,
|
||||
const std::optional<GURL>& direct_from_seller_seller_signals,
|
||||
const std::optional<std::string>&
|
||||
direct_from_seller_seller_signals_header_ad_slot,
|
||||
@ -654,9 +656,17 @@ class MockAuctionProcessManager
|
||||
auction_worklet::mojom::AuctionWorkletPermissionsPolicyStatePtr
|
||||
permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_group_id,
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key) override {
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client) override {
|
||||
DCHECK(!seller_worklet_);
|
||||
|
||||
if (load_seller_worklet_client) {
|
||||
mojo::Remote<auction_worklet::mojom::LoadSellerWorkletClient>(
|
||||
std::move(load_seller_worklet_client))
|
||||
->SellerWorkletLoaded(/*trusted_signals_url_allowed=*/true);
|
||||
}
|
||||
|
||||
// Make sure this request came over the right pipe.
|
||||
EXPECT_EQ(receiver_set_.current_context().worklet_type,
|
||||
AuctionProcessManager::WorkletType::kSeller);
|
||||
|
@ -5462,7 +5462,9 @@ void InterestGroupAuction::ScoreBid(std::unique_ptr<Bid> bid) {
|
||||
seller_worklet_handle_->AuthorizeSubresourceUrls(*url_builder);
|
||||
seller_worklet_handle_->GetSellerWorklet()->ScoreAd(
|
||||
bid_raw->ad_metadata, bid_raw->bid, bid_raw->bid_currency,
|
||||
config_->non_shared_params, GetDirectFromSellerSellerSignals(url_builder),
|
||||
config_->non_shared_params,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
GetDirectFromSellerSellerSignals(url_builder),
|
||||
GetDirectFromSellerSellerSignalsHeaderAdSlot(
|
||||
*direct_from_seller_signals_header_ad_slot_),
|
||||
GetDirectFromSellerAuctionSignals(url_builder),
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "base/time/time.h"
|
||||
#include "content/browser/interest_group/auction_process_manager.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom-forward.h"
|
||||
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
|
||||
@ -407,6 +406,7 @@ void MockSellerWorklet::ScoreAd(
|
||||
const std::optional<blink::AdCurrency>& bid_currency,
|
||||
const blink::AuctionConfig::NonSharedParams&
|
||||
auction_ad_config_non_shared_params,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr trusted_signals_cache_key,
|
||||
const std::optional<GURL>& direct_from_seller_seller_signals,
|
||||
const std::optional<std::string>&
|
||||
direct_from_seller_seller_signals_header_ad_slot,
|
||||
@ -629,9 +629,17 @@ void MockAuctionProcessManager::LoadSellerWorklet(
|
||||
auction_worklet::mojom::AuctionWorkletPermissionsPolicyStatePtr
|
||||
permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_group_id,
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key) {
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client) {
|
||||
EXPECT_EQ(0u, seller_worklets_.count(script_source_url));
|
||||
|
||||
if (load_seller_worklet_client) {
|
||||
mojo::Remote<auction_worklet::mojom::LoadSellerWorkletClient>(
|
||||
std::move(load_seller_worklet_client))
|
||||
->SellerWorkletLoaded(/*trusted_signals_url_allowed=*/true);
|
||||
}
|
||||
|
||||
// Make sure this request came over the right pipe, if the WorkletProcess
|
||||
// hasn't been destroyed yet. Can't grab the origin on creation, as the origin
|
||||
// may change in the case of processes that have not yet been bound to an
|
||||
|
@ -292,6 +292,8 @@ class MockSellerWorklet : public auction_worklet::mojom::SellerWorklet {
|
||||
const std::optional<blink::AdCurrency>& bid_currency,
|
||||
const blink::AuctionConfig::NonSharedParams&
|
||||
auction_ad_config_non_shared_params,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr
|
||||
trusted_signals_cache_key,
|
||||
const std::optional<GURL>& direct_from_seller_seller_signals,
|
||||
const std::optional<std::string>&
|
||||
direct_from_seller_seller_signals_header_ad_slot,
|
||||
@ -472,7 +474,9 @@ class MockAuctionProcessManager
|
||||
auction_worklet::mojom::AuctionWorkletPermissionsPolicyStatePtr
|
||||
permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_group_id,
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key) override;
|
||||
auction_worklet::mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client) override;
|
||||
|
||||
// Set the expected timeout for an interest group with the specified name,
|
||||
// when it's received by a bidder worklet's FinishGenerateBid() method. Must
|
||||
|
@ -339,7 +339,9 @@ void AuctionWorkletServiceImpl::LoadSellerWorklet(
|
||||
const url::Origin& top_window_origin,
|
||||
mojom::AuctionWorkletPermissionsPolicyStatePtr permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_group_id,
|
||||
mojom::TrustedSignalsPublicKeyPtr public_key) {
|
||||
mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
std::vector<scoped_refptr<AuctionV8Helper>> v8_helpers;
|
||||
for (size_t i = 0; i < auction_seller_v8_helper_holders_.size(); ++i) {
|
||||
@ -357,7 +359,8 @@ void AuctionWorkletServiceImpl::LoadSellerWorklet(
|
||||
std::move(public_key),
|
||||
base::BindRepeating(
|
||||
&AuctionWorkletServiceImpl::GetNextSellerWorkletThreadIndex,
|
||||
base::Unretained(this)));
|
||||
base::Unretained(this)),
|
||||
std::move(load_seller_worklet_client));
|
||||
auto* seller_worklet_ptr = seller_worklet.get();
|
||||
|
||||
mojo::ReceiverId receiver_id = seller_worklets_.Add(
|
||||
|
@ -99,7 +99,9 @@ class CONTENT_EXPORT AuctionWorkletServiceImpl
|
||||
const url::Origin& top_window_origin,
|
||||
mojom::AuctionWorkletPermissionsPolicyStatePtr permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_group_id,
|
||||
mojom::TrustedSignalsPublicKeyPtr public_key) override;
|
||||
mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client) override;
|
||||
|
||||
// Returns an index in the seller thread pool, where the corresponding V8
|
||||
// thread will be used to execute the next task.
|
||||
|
@ -37,6 +37,17 @@ struct TrustedSignalsPublicKey {
|
||||
uint8 id;
|
||||
};
|
||||
|
||||
// Client interface for receiving a notification when a requested seller worklet
|
||||
// finished loading. Use a client interface instead of a callback because that
|
||||
// allows not invoking the callback.
|
||||
interface LoadSellerWorkletClient {
|
||||
// Invoked once the SellerWorklet has been loaded. Indicates if the response
|
||||
// for the requested script URL indicated that the passed in trusted scoring
|
||||
// signals URL may be requested. It's always true if the trusted scoring
|
||||
// signals URL is same origin to the script URL.
|
||||
SellerWorkletLoaded(bool trusted_signals_url_allowed);
|
||||
};
|
||||
|
||||
// Used by the browser to load and run FLEDGE worklets. This can run in a
|
||||
// sandboxed utility process (non-Android) or inside a regular renderer
|
||||
// (Android).
|
||||
@ -154,9 +165,9 @@ interface AuctionWorkletService {
|
||||
// SellerWorklet pipe.
|
||||
//
|
||||
// `shared_storage_hosts` The pipes for the SellerWorklet threads to send
|
||||
// shared storage requests to the browser process. Will all be null if the
|
||||
// `kSharedStorageAPI` feature or the "shared-storage" permissions policy is
|
||||
// disabled.
|
||||
// shared storage requests to the browser process. Will all be null if the
|
||||
// `kSharedStorageAPI` feature or the "shared-storage" permissions policy is
|
||||
// disabled.
|
||||
//
|
||||
// `pause_for_debugger_on_start` If this is true, the worklet should not
|
||||
// commence any work until it gets a Runtime.runIfWaitingForDebugger debugger
|
||||
@ -176,7 +187,19 @@ interface AuctionWorkletService {
|
||||
// `permissions_policy_state` The permissions policy state of the worklet.
|
||||
//
|
||||
// `experiment_group_id`: An optional parameter to pass to trusted signals
|
||||
// server and as part of AuctionConfig.
|
||||
// server and as part of AuctionConfig.
|
||||
//
|
||||
// `load_seller_worklet_client` may be passed in to get a notification when
|
||||
// the `script_source_url` has been loaded, and is passed whether
|
||||
// `trusted_scoring_signals_url` may be requested. It's needed when
|
||||
// `trusted_scoring_signals_url` is non-null and is cross-origin to
|
||||
// `script_source_url`, and the trusted signals cache is in use. In that
|
||||
// case, the browser process will be responsible for starting and managing
|
||||
// signals fetches, so needs to know if the seller script's headers have
|
||||
// provided permissions for signals to be requested from the scoring signals'
|
||||
// origin. In other cases, the notification is not needed, since the worklet
|
||||
// process itself is responsible for respecting those permissions, and the
|
||||
// worklet API may be used before the script URL has finished loading.
|
||||
LoadSellerWorklet(
|
||||
pending_receiver<SellerWorklet> seller_worklet,
|
||||
array<pending_remote<AuctionSharedStorageHost>?> shared_storage_hosts,
|
||||
@ -188,5 +211,6 @@ interface AuctionWorkletService {
|
||||
url.mojom.Origin top_window_origin,
|
||||
AuctionWorkletPermissionsPolicyState permissions_policy_state,
|
||||
uint16? experiment_group_id,
|
||||
TrustedSignalsPublicKey? public_key);
|
||||
TrustedSignalsPublicKey? public_key,
|
||||
pending_remote<LoadSellerWorkletClient>? load_seller_worklet_client);
|
||||
};
|
||||
|
@ -7,6 +7,7 @@ module auction_worklet.mojom;
|
||||
import "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom";
|
||||
import "content/services/auction_worklet/public/mojom/real_time_reporting.mojom";
|
||||
import "content/services/auction_worklet/public/mojom/reject_reason.mojom";
|
||||
import "content/services/auction_worklet/public/mojom/trusted_signals_cache.mojom";
|
||||
import "mojo/public/mojom/base/time.mojom";
|
||||
import "services/network/public/mojom/url_loader_factory.mojom";
|
||||
import "third_party/blink/public/mojom/devtools/devtools_agent.mojom";
|
||||
@ -180,6 +181,15 @@ interface SellerWorklet {
|
||||
// `auction_ad_config_non_shared_params` Values in an AuctionConfig that can
|
||||
// vary between auctions that can share a SellerWorklet.
|
||||
//
|
||||
// `key_value_signals_cache_key`: When using version two of the trusted
|
||||
// signals key value protocol, this contains information needed to retrieve
|
||||
// the fetched signals for the call from the browser process through the
|
||||
// TrustedSignalsCache API. When the browser-side cache is disabled and
|
||||
// fetching is done by the worklet service directly, this should be null.
|
||||
// SetTrustedSignalsCache() must have already been called on the parent
|
||||
// AuctionWorkletService before creating the SellerWorklet if passing in
|
||||
// a non-null value.
|
||||
//
|
||||
// `direct_from_seller_seller_signals` The subresource URL of the
|
||||
// DirectFromSellerSignals for the seller, as produced by concatenating the
|
||||
// `directFromSellerSignals` URL prefix field passed from runAdAuction() with
|
||||
@ -239,14 +249,14 @@ interface SellerWorklet {
|
||||
// timing information passed to an untrusted process.
|
||||
//
|
||||
// `browser_signal_render_size` is the size associated with the `renderUrl`
|
||||
// returned by the BidderWorklet making the bid. This argument is optional.
|
||||
// When there is no size associated with the `renderUrl`, it will be a
|
||||
// nullopt.
|
||||
// See explainer: https://github.com/WICG/turtledove/blob/main/FLEDGE.md#32-on-device-bidding
|
||||
// returned by the BidderWorklet making the bid. This argument is optional.
|
||||
// When there is no size associated with the `renderUrl`, it will be a
|
||||
// nullopt.
|
||||
// See explainer: https://github.com/WICG/turtledove/blob/main/FLEDGE.md#32-on-device-bidding
|
||||
//
|
||||
// `browser_signal_for_debugging_only_in_cooldown_or_lockout` Whether the
|
||||
// browser is under lockout or the seller's origin is under cooldown for
|
||||
// sending forDebuggingOnly reports.
|
||||
// browser is under lockout or the seller's origin is under cooldown for
|
||||
// sending forDebuggingOnly reports.
|
||||
//
|
||||
// `seller_timeout` Restrict the runtime of the seller's scoring script. Any
|
||||
// timeout higher than 500 ms will be clamped to 500 ms before passing in as
|
||||
@ -257,12 +267,13 @@ interface SellerWorklet {
|
||||
// to use with tracing calls.
|
||||
//
|
||||
// `score_ad_client` When the ScoreAd completes, successfully or not, its
|
||||
// OnScoreAdComplete() method will be invoked with the results.
|
||||
// OnScoreAdComplete() method will be invoked with the results.
|
||||
ScoreAd(string ad_metadata_json,
|
||||
double bid,
|
||||
blink.mojom.AdCurrency? bid_currency,
|
||||
blink.mojom.AuctionAdConfigNonSharedParams
|
||||
auction_ad_config_non_shared_params,
|
||||
TrustedSignalsCacheKey? key_value_signals_cache_key,
|
||||
url.mojom.Url? direct_from_seller_seller_signals,
|
||||
string? direct_from_seller_seller_signals_header_ad_slot,
|
||||
url.mojom.Url? direct_from_seller_auction_signals,
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "content/services/auction_worklet/public/cpp/auction_network_events_delegate.h"
|
||||
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/seller_worklet.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/trusted_signals_cache.mojom.h"
|
||||
#include "content/services/auction_worklet/real_time_reporting_bindings.h"
|
||||
#include "content/services/auction_worklet/register_ad_beacon_bindings.h"
|
||||
#include "content/services/auction_worklet/report_bindings.h"
|
||||
@ -433,7 +434,9 @@ SellerWorklet::SellerWorklet(
|
||||
mojom::AuctionWorkletPermissionsPolicyStatePtr permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_group_id,
|
||||
mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
GetNextThreadIndexCallback get_next_thread_index_callback)
|
||||
GetNextThreadIndexCallback get_next_thread_index_callback,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client)
|
||||
: url_loader_factory_(std::move(pending_url_loader_factory)),
|
||||
script_source_url_(decision_logic_url),
|
||||
trusted_scoring_signals_origin_(
|
||||
@ -443,7 +446,8 @@ SellerWorklet::SellerWorklet(
|
||||
auction_network_events_handler_(
|
||||
std::move(auction_network_events_handler)),
|
||||
get_next_thread_index_callback_(
|
||||
std::move(get_next_thread_index_callback)) {
|
||||
std::move(get_next_thread_index_callback)),
|
||||
load_seller_worklet_client_(std::move(load_seller_worklet_client)) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(user_sequence_checker_);
|
||||
|
||||
DCHECK(!v8_helpers.empty());
|
||||
@ -510,6 +514,7 @@ void SellerWorklet::ScoreAd(
|
||||
const std::optional<blink::AdCurrency>& bid_currency,
|
||||
const blink::AuctionConfig::NonSharedParams&
|
||||
auction_ad_config_non_shared_params,
|
||||
mojom::TrustedSignalsCacheKeyPtr trusted_signals_cache_key,
|
||||
const std::optional<GURL>& direct_from_seller_seller_signals,
|
||||
const std::optional<std::string>&
|
||||
direct_from_seller_seller_signals_header_ad_slot,
|
||||
@ -1916,6 +1921,15 @@ void SellerWorklet::OnDownloadComplete(
|
||||
|
||||
DCHECK_NE(trusted_signals_relation_,
|
||||
SignalsOriginRelation::kUnknownPermissionCrossOriginSignals);
|
||||
if (load_seller_worklet_client_) {
|
||||
mojo::Remote<mojom::LoadSellerWorkletClient>(
|
||||
std::move(load_seller_worklet_client_))
|
||||
->SellerWorkletLoaded(
|
||||
trusted_signals_relation_ ==
|
||||
SignalsOriginRelation::kSameOriginSignals ||
|
||||
trusted_signals_relation_ ==
|
||||
SignalsOriginRelation::kPermittedCrossOriginSignals);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < v8_runners_.size(); ++i) {
|
||||
v8_runners_[i]->PostTask(
|
||||
|
@ -102,7 +102,9 @@ class CONTENT_EXPORT SellerWorklet : public mojom::SellerWorklet {
|
||||
mojom::AuctionWorkletPermissionsPolicyStatePtr permissions_policy_state,
|
||||
std::optional<uint16_t> experiment_group_id,
|
||||
mojom::TrustedSignalsPublicKeyPtr public_key,
|
||||
GetNextThreadIndexCallback next_thread_index_callback);
|
||||
GetNextThreadIndexCallback next_thread_index_callback,
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client);
|
||||
|
||||
explicit SellerWorklet(const SellerWorklet&) = delete;
|
||||
SellerWorklet& operator=(const SellerWorklet&) = delete;
|
||||
@ -127,6 +129,7 @@ class CONTENT_EXPORT SellerWorklet : public mojom::SellerWorklet {
|
||||
const std::optional<blink::AdCurrency>& bid_currency,
|
||||
const blink::AuctionConfig::NonSharedParams&
|
||||
auction_ad_config_non_shared_params,
|
||||
mojom::TrustedSignalsCacheKeyPtr trusted_signals_cache_key,
|
||||
const std::optional<GURL>& direct_from_seller_seller_signals,
|
||||
const std::optional<std::string>&
|
||||
direct_from_seller_seller_signals_header_ad_slot,
|
||||
@ -663,6 +666,9 @@ class CONTENT_EXPORT SellerWorklet : public mojom::SellerWorklet {
|
||||
|
||||
GetNextThreadIndexCallback get_next_thread_index_callback_;
|
||||
|
||||
mojo::PendingRemote<auction_worklet::mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client_;
|
||||
|
||||
SEQUENCE_CHECKER(user_sequence_checker_);
|
||||
|
||||
// Used when posting callbacks back from V8State.
|
||||
|
@ -35,11 +35,11 @@
|
||||
#include "content/services/auction_worklet/public/cpp/cbor_test_util.h"
|
||||
#include "content/services/auction_worklet/public/cpp/real_time_reporting.h"
|
||||
#include "content/services/auction_worklet/public/mojom/auction_network_events_handler.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom-forward.h"
|
||||
#include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/private_aggregation_request.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/real_time_reporting.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/seller_worklet.mojom.h"
|
||||
#include "content/services/auction_worklet/public/mojom/trusted_signals_cache.mojom.h"
|
||||
#include "content/services/auction_worklet/worklet_devtools_debug_test_util.h"
|
||||
#include "content/services/auction_worklet/worklet_test_util.h"
|
||||
#include "content/services/auction_worklet/worklet_v8_debug_test_util.h"
|
||||
@ -222,7 +222,8 @@ class TestScoreAdClient : public mojom::ScoreAdClient {
|
||||
ScoreAdCompleteCallback score_ad_complete_callback_;
|
||||
};
|
||||
|
||||
class SellerWorkletTest : public testing::Test {
|
||||
class SellerWorkletTest : public testing::Test,
|
||||
public mojom::LoadSellerWorkletClient {
|
||||
public:
|
||||
explicit SellerWorkletTest(
|
||||
base::test::TaskEnvironment::TimeSource time_mode =
|
||||
@ -426,6 +427,7 @@ class SellerWorkletTest : public testing::Test {
|
||||
base::OnceClosure done_closure) {
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
/*key_value_signals_cache_key=*/nullptr,
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -527,6 +529,7 @@ class SellerWorkletTest : public testing::Test {
|
||||
mojom::SellerWorklet* seller_worklet) {
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -792,6 +795,10 @@ class SellerWorkletTest : public testing::Test {
|
||||
|
||||
CHECK_EQ(v8_helpers_.size(), shared_storage_hosts_.size());
|
||||
|
||||
mojo::PendingRemote<mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client;
|
||||
load_seller_worklet_client_receivers_.Add(
|
||||
this, load_seller_worklet_client.InitWithNewPipeAndPassReceiver());
|
||||
mojo::Remote<mojom::SellerWorklet> seller_worklet;
|
||||
auto seller_worklet_impl = std::make_unique<SellerWorklet>(
|
||||
v8_helpers_, std::move(shared_storage_hosts_),
|
||||
@ -801,7 +808,8 @@ class SellerWorkletTest : public testing::Test {
|
||||
permissions_policy_state_.Clone(), experiment_group_id_,
|
||||
public_key_ ? public_key_.Clone() : nullptr,
|
||||
base::BindRepeating(&SellerWorkletTest::GetNextThreadIndex,
|
||||
base::Unretained(this)));
|
||||
base::Unretained(this)),
|
||||
std::move(load_seller_worklet_client));
|
||||
|
||||
shared_storage_hosts_.resize(NumThreads());
|
||||
|
||||
@ -862,6 +870,11 @@ class SellerWorkletTest : public testing::Test {
|
||||
}
|
||||
}
|
||||
|
||||
// LoadSellerWorkletClient implementation:
|
||||
void SellerWorkletLoaded(bool trusted_signals_url_allowed) override {
|
||||
trusted_signals_url_allowed_ = trusted_signals_url_allowed;
|
||||
}
|
||||
|
||||
base::test::TaskEnvironment task_environment_;
|
||||
|
||||
// Extra headers to append to replies for JavaScript resources.
|
||||
@ -925,10 +938,16 @@ class SellerWorkletTest : public testing::Test {
|
||||
|
||||
size_t next_thread_index_ = 0;
|
||||
|
||||
// Value received through the last call to the LoadSellerWorkletClient
|
||||
// interface.
|
||||
std::optional<bool> trusted_signals_url_allowed_;
|
||||
|
||||
// Owns all created seller worklets - having a ReceiverSet allows them to have
|
||||
// a ClosePipeCallback which behaves just like the one in
|
||||
// AuctionWorkletServiceImpl, to better match production behavior.
|
||||
mojo::UniqueReceiverSet<mojom::SellerWorklet> seller_worklets_;
|
||||
mojo::ReceiverSet<mojom::LoadSellerWorkletClient>
|
||||
load_seller_worklet_client_receivers_;
|
||||
};
|
||||
|
||||
class SellerWorkletTwoThreadsTest : public SellerWorkletTest {
|
||||
@ -2171,6 +2190,7 @@ TEST_F(SellerWorkletTest, ScoreAdJsFetchLatency) {
|
||||
base::RunLoop run_loop;
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -4083,6 +4103,7 @@ TEST_P(SellerWorkletMultiThreadingTest, ScriptIsolation) {
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_,
|
||||
auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -4185,6 +4206,7 @@ TEST_F(SellerWorkletTest,
|
||||
base::RunLoop run_loop;
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -4290,6 +4312,7 @@ TEST_F(
|
||||
base::RunLoop run_loop;
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -4402,6 +4425,7 @@ TEST_F(
|
||||
->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_,
|
||||
auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -4520,6 +4544,7 @@ TEST_F(SellerWorkletTwoThreadsTest,
|
||||
base::RunLoop run_loop;
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -4582,6 +4607,7 @@ TEST_F(SellerWorkletTest, ContextReuseDoesNotCrashLazyFiller) {
|
||||
base::RunLoop run_loop;
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -4628,6 +4654,7 @@ TEST_F(SellerWorkletTest, DeleteBeforeScoreAdCallback) {
|
||||
base::WaitableEvent* event_handle = WedgeV8Thread(v8_helper().get());
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -5656,6 +5683,7 @@ TEST_F(SellerWorkletTest, Cancelation) {
|
||||
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -5722,6 +5750,7 @@ TEST_F(SellerWorkletTest, CancelBeforeFetch) {
|
||||
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, bid_, bid_currency_, auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -6760,6 +6789,7 @@ TEST_F(SellerWorkletBiddingAndScoringDebugReportingAPIEnabledTest,
|
||||
seller_worklet->ScoreAd(
|
||||
ad_metadata_, i + 1, bid_currency_,
|
||||
auction_ad_config_non_shared_params_,
|
||||
auction_worklet::mojom::TrustedSignalsCacheKeyPtr(),
|
||||
direct_from_seller_seller_signals_,
|
||||
direct_from_seller_seller_signals_header_ad_slot_,
|
||||
direct_from_seller_auction_signals_,
|
||||
@ -7476,6 +7506,9 @@ TEST_F(SellerWorkletTest, SameOrigin) {
|
||||
"crossOriginTrustedSignals === null ? 1 : 0", 1,
|
||||
/*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/5);
|
||||
load_seller_worklet_client_receivers_.FlushForTesting();
|
||||
EXPECT_TRUE(*trusted_signals_url_allowed_);
|
||||
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
"arguments.length", 7,
|
||||
/*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
@ -7521,8 +7554,12 @@ TEST_F(SellerWorkletTest, ForbiddenCrossOrigin) {
|
||||
extra_js_headers_ = std::nullopt;
|
||||
}
|
||||
|
||||
trusted_signals_url_allowed_.reset();
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
"crossOriginTrustedSignals === null ? 1 : 0", 1, expected_errors);
|
||||
load_seller_worklet_client_receivers_.FlushForTesting();
|
||||
EXPECT_FALSE(*trusted_signals_url_allowed_);
|
||||
|
||||
RunScoreAdWithReturnValueExpectingResult("arguments.length", 7,
|
||||
expected_errors);
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
@ -7594,11 +7631,14 @@ TEST_F(SellerWorkletTest, ForbiddenCrossOriginNoFetch) {
|
||||
EXPECT_EQ(1, url_loader_factory_.NumPending());
|
||||
EXPECT_TRUE(url_loader_factory_.IsPending(decision_logic_url_.spec()));
|
||||
|
||||
trusted_signals_url_allowed_.reset();
|
||||
AddJavascriptResponse(&url_loader_factory_, decision_logic_url_,
|
||||
CreateScoreAdScript(kScoreExpr), extra_js_headers_);
|
||||
run_loop.Run();
|
||||
// We didn't just time out the signals fetch, it didn't happen at all.
|
||||
EXPECT_THAT(saw_urls, testing::ElementsAre(decision_logic_url_));
|
||||
load_seller_worklet_client_receivers_.FlushForTesting();
|
||||
EXPECT_FALSE(*trusted_signals_url_allowed_);
|
||||
|
||||
// Also check the histograms.
|
||||
histogram_tester.ExpectTotalCount(
|
||||
@ -7646,10 +7686,13 @@ TEST_F(SellerWorkletTest, AllowedCrossOrigin) {
|
||||
throw actual + "!" + expected;
|
||||
)";
|
||||
|
||||
trusted_signals_url_allowed_.reset();
|
||||
RunScoreAdWithJavascriptExpectingResult(
|
||||
CreateScoreAdScript("3", kValidate), 7,
|
||||
/*expected_errors=*/{}, mojom::ComponentAuctionModifiedBidParamsPtr(),
|
||||
/*expected_data_version=*/5);
|
||||
load_seller_worklet_client_receivers_.FlushForTesting();
|
||||
EXPECT_TRUE(*trusted_signals_url_allowed_);
|
||||
|
||||
// Versions in crossOriginDataVersion, and passed out of worklet.
|
||||
RunScoreAdWithReturnValueExpectingResult(
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "content/services/auction_worklet/trusted_signals.h"
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@ -28,6 +29,7 @@
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "url/gurl.h"
|
||||
#include "url/origin.h"
|
||||
#include "v8/include/v8-context.h"
|
||||
#include "v8/include/v8-forward.h"
|
||||
|
||||
|
Reference in New Issue
Block a user