1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
content / services / auction_worklet / set_bid_bindings.h [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_SERVICES_AUCTION_WORKLET_SET_BID_BINDINGS_H_
#define CONTENT_SERVICES_AUCTION_WORKLET_SET_BID_BINDINGS_H_
#include <optional>
#include <utility>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "content/common/content_export.h"
#include "content/services/auction_worklet/auction_v8_helper.h"
#include "content/services/auction_worklet/context_recycler.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom-forward.h"
#include "content/services/auction_worklet/public/mojom/reject_reason.mojom.h"
#include "content/services/auction_worklet/webidl_compat.h"
#include "third_party/blink/public/common/interest_group/ad_auction_currencies.h"
#include "third_party/blink/public/common/interest_group/interest_group.h"
#include "url/gurl.h"
#include "v8/include/v8-forward.h"
namespace auction_worklet {
// Class to manage bindings for setting a bidding result. Expected to be used
// for a context managed by ContextRecycler.
class CONTENT_EXPORT SetBidBindings : public Bindings {
public:
// Bid plus information needed to filter subset of component ads to given
// target #, considering k-anonymity. This is done entirely by the worklet,
// and isn't in the Mojo bid type. This also includes the reporting ids
// needed to enforce k-anonymity for reporting on bids that include a
// `selectedBuyerAndSellerReportingId`.
struct CONTENT_EXPORT BidAndWorkletOnlyMetadata {
BidAndWorkletOnlyMetadata();
BidAndWorkletOnlyMetadata(BidAndWorkletOnlyMetadata&&);
BidAndWorkletOnlyMetadata(const BidAndWorkletOnlyMetadata&) = delete;
~BidAndWorkletOnlyMetadata();
BidAndWorkletOnlyMetadata& operator=(BidAndWorkletOnlyMetadata&&);
BidAndWorkletOnlyMetadata& operator=(const BidAndWorkletOnlyMetadata&) =
delete;
mojom::BidderWorkletBidPtr bid;
// Only this many ad components will actually be kept, anything beyond is
// contingency for k-anonymity.
std::optional<size_t> target_num_ad_components;
// This many ad components from the beginning of the array absolutely must
// be there and k-anonymous. Only used if `target_num_ad_components` is set.
size_t num_mandatory_ad_components = 0;
// The buyerReportingId from the InterestGroup.ad, if provided.
std::optional<std::string> buyer_reporting_id;
// The buyerAndSellerReportingId from the InterestGroup.ad, if provided.
std::optional<std::string> buyer_and_seller_reporting_id;
};
explicit SetBidBindings(AuctionV8Helper* v8_helper);
SetBidBindings(const SetBidBindings&) = delete;
SetBidBindings& operator=(const SetBidBindings&) = delete;
~SetBidBindings() override;
// This must be called before every time this is used.
// bidder_worklet_non_shared_params->ads.has_value() must be true.
void ReInitialize(
base::TimeTicks start,
bool has_top_level_seller_origin,
const mojom::BidderWorkletNonSharedParams*
bidder_worklet_non_shared_params,
const std::optional<blink::AdCurrency>& per_buyer_currency,
uint16_t multi_bid_limit,
base::RepeatingCallback<bool(const std::string&)> is_ad_excluded,
base::RepeatingCallback<bool(const std::string&)>
is_component_ad_excluded,
base::RepeatingCallback<bool(const std::string&,
base::optional_ref<const std::string>,
base::optional_ref<const std::string>,
base::optional_ref<const std::string>)>
is_reporting_id_set_excluded);
void AttachToContext(v8::Local<v8::Context> context) override;
void Reset() override;
bool has_bids() const { return !bids_.empty(); }
// Note that returned bids do not have their role filled in correctly,
// it's always kUnenforcedKAnon.
std::vector<BidAndWorkletOnlyMetadata> TakeBids();
mojom::RejectReason reject_reason() const { return reject_reason_; }
// Overwrites the set bids with however many are in `bid_value`, and returns
// if any errors occurred.
IdlConvert::Status SetBidImpl(v8::Local<v8::Value> bid_value,
std::string error_prefix);
private:
struct GenerateBidOutput;
static void SetBid(const v8::FunctionCallbackInfo<v8::Value>& args);
// Attempts to convert a single bid from JS to IDL, returning either the IDL
// type or a failing status.
//
// `error_prefix` is the base prefix for errors, `render_prefix` is one for
// errors in render field, and `components_prefix` is for errors in the
// adComponents array.
base::expected<GenerateBidOutput, IdlConvert::Status> ConvertBidToIDL(
AuctionV8Helper::TimeLimitScope& time_limit_scope,
v8::Local<v8::Value> input,
const std::string& error_prefix,
const std::string& render_prefix,
const std::string& components_prefix);
// Tries to semantically check the bid in `idl`, and convert it to
// mojom::BidderWorkletBid.
//
// Note that a valid value that results in no bid is not considered an error.
// In case of an error, may also set `reject_reason_`.
//
// `error_prefix` is the base prefix for errors, `render_prefix` is one for
// errors in render field, and `components_prefix` is for errors in the
// adComponents array.
base::expected<BidAndWorkletOnlyMetadata, IdlConvert::Status>
SemanticCheckBid(AuctionV8Helper::TimeLimitScope& time_limit_scope,
const GenerateBidOutput& idl,
const std::string& error_prefix,
const std::string& render_prefix,
const std::string& components_prefix);
// Verifies if the selectedBuyerAndSellerReportingId is present within the
// matching ad's selectableBuyerAndSellerReportingId array, and that (for
// the k-anon restricted run), the reporting ids, collectively, are
// k-anonymous for reporting, as indicated by the
// `is_reporting_id_set_excluded_` callback.
bool IsSelectedReportingIdValid(
const blink::InterestGroup::Ad& ad,
const std::string& selected_buyer_and_seller_reporting_id);
const raw_ptr<AuctionV8Helper> v8_helper_;
base::TimeTicks start_;
bool has_top_level_seller_origin_ = false;
mojom::RejectReason reject_reason_ = mojom::RejectReason::kNotAvailable;
raw_ptr<const mojom::BidderWorkletNonSharedParams>
bidder_worklet_non_shared_params_ = nullptr;
std::optional<blink::AdCurrency> per_buyer_currency_;
uint16_t multi_bid_limit_ = 1;
const bool support_multi_bid_ = false;
// Callbacks set by ReInitialize and cleared by Reset which tell if an ad URL
// can be used in a valid bid. Used to check the bid for non-k-anonymous ads.
base::RepeatingCallback<bool(const std::string&)> is_ad_excluded_;
base::RepeatingCallback<bool(const std::string&)> is_component_ad_excluded_;
base::RepeatingCallback<bool(const std::string&,
base::optional_ref<const std::string>,
base::optional_ref<const std::string>,
base::optional_ref<const std::string>)>
is_reporting_id_set_excluded_;
std::vector<BidAndWorkletOnlyMetadata> bids_;
};
} // namespace auction_worklet
#endif // CONTENT_SERVICES_AUCTION_WORKLET_SET_BID_BINDINGS_H_