Changeset 285967 in webkit
- Timestamp:
- Nov 17, 2021, 5:08:40 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 17 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/tests/privateClickMeasurement/resources/redirectToConversionWithAttributionSource.py (added)
-
LayoutTests/http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive-expected.txt (added)
-
LayoutTests/http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive.html (added)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/URL.cpp (modified) (1 diff)
-
Source/WTF/wtf/URL.h (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/html/HTMLAnchorElement.cpp (modified) (1 diff)
-
Source/WebCore/loader/PrivateClickMeasurement.cpp (modified) (9 diffs)
-
Source/WebCore/loader/PrivateClickMeasurement.h (modified) (7 diffs)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp (modified) (3 diffs)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp (modified) (5 diffs)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h (modified) (2 diffs)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp (modified) (1 diff)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.h (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp (modified) (6 diffs)
-
Tools/TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r285945 r285967 1 2021-11-17 John Wilander <wilander@apple.com> 2 3 PCM: Add capability for click destination to fire triggering event without cross-site requests to the click source 4 https://bugs.webkit.org/show_bug.cgi?id=233173 5 <rdar://79426605> 6 7 Reviewed by Alex Christensen. 8 9 * http/tests/privateClickMeasurement/resources/redirectToConversionWithAttributionSource.py: Added. 10 * http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive-expected.txt: Added. 11 * http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive.html: Added. 12 1 13 2021-11-17 Ryan Haddad <ryanhaddad@apple.com> 2 14 -
trunk/Source/WTF/ChangeLog
r285954 r285967 1 2021-11-17 John Wilander <wilander@apple.com> 2 3 PCM: Add capability for click destination to fire triggering event without cross-site requests to the click source 4 https://bugs.webkit.org/show_bug.cgi?id=233173 5 <rdar://79426605> 6 7 Reviewed by Alex Christensen. 8 9 * wtf/URL.cpp: 10 (WTF::queryParameters): 11 New convenience getter. 12 * wtf/URL.h: 13 1 14 2021-11-17 Chris Dumez <cdumez@apple.com> 2 15 -
trunk/Source/WTF/wtf/URL.cpp
r283522 r285967 1191 1191 #endif 1192 1192 1193 Vector<KeyValuePair<String, String>> queryParameters(const URL& url) 1194 { 1195 return URLParser::parseURLEncodedForm(url.query()); 1196 } 1197 1193 1198 Vector<KeyValuePair<String, String>> differingQueryParameters(const URL& firstURL, const URL& secondURL) 1194 1199 { -
trunk/Source/WTF/wtf/URL.h
r285588 r285967 251 251 WTF_EXPORT_PRIVATE bool protocolHostAndPortAreEqual(const URL&, const URL&); 252 252 WTF_EXPORT_PRIVATE Vector<KeyValuePair<String, String>> differingQueryParameters(const URL&, const URL&); 253 WTF_EXPORT_PRIVATE Vector<KeyValuePair<String, String>> queryParameters(const URL&); 253 254 WTF_EXPORT_PRIVATE bool isEqualIgnoringQueryAndFragments(const URL&, const URL&); 254 255 WTF_EXPORT_PRIVATE void removeQueryParameters(URL&, const HashSet<String>&); -
trunk/Source/WebCore/ChangeLog
r285964 r285967 1 2021-11-17 John Wilander <wilander@apple.com> 2 3 PCM: Add capability for click destination to fire triggering event without cross-site requests to the click source 4 https://bugs.webkit.org/show_bug.cgi?id=233173 5 <rdar://79426605> 6 7 Reviewed by Alex Christensen. 8 9 This patch enables click destination sites a non-JavaScript way to fire triggering 10 events without a requirement to make cross-site requests to source sites. This is 11 referred to as a "same-site pixel API" and has been discussed in W3C Privacy CG: 12 https://github.com/privacycg/private-click-measurement/issues/71 13 14 The reason why some merchants want such an "API" is reluctance to deploy new 15 JavaScript on their sites. In some industries it's even a compliance issue. Legacy 16 "pixels" are however accepted and so a same-site "pixel" can work for them. 17 18 Test: http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive.html 19 20 * html/HTMLAnchorElement.cpp: 21 (WebCore::HTMLAnchorElement::handleClick): 22 This change is because of clarification in naming: 23 - attributionReportSourceURL to attributionReportClickSourceURL 24 * loader/PrivateClickMeasurement.cpp: 25 (WebCore::PrivateClickMeasurement::parseAttributionRequestQuery): 26 New function that parses out query string parameters. 27 (WebCore::PrivateClickMeasurement::parseAttributionRequest): 28 Now calls the new PrivateClickMeasurement::parseAttributionRequestQuery() 29 which handles data coming in in query parameters, in this case 30 the new parameter "attributionSource." 31 (WebCore::PrivateClickMeasurement::attributionReportClickSourceURL const): 32 New name. 33 (WebCore::PrivateClickMeasurement::attributionReportClickDestinationURL const): 34 New name. 35 (WebCore::PrivateClickMeasurement::attributionReportJSON const): 36 Now uses the constant privateClickMeasurementVersion. 37 (WebCore::PrivateClickMeasurement::tokenSignatureJSON const): 38 Now uses the constant privateClickMeasurementVersion. 39 (WebCore::PrivateClickMeasurement::attributionReportSourceURL const): Deleted. 40 Renamed attributionReportClickSourceURL. 41 (WebCore::PrivateClickMeasurement::attributionReportAttributeOnURL const): Deleted. 42 Renamed attributionReportClickDestinationURL. 43 * loader/PrivateClickMeasurement.h: 44 (WebCore::PrivateClickMeasurement::sourceSecretToken const): 45 New name. 46 (WebCore::PrivateClickMeasurement::AttributionTriggerData::encode const): 47 (WebCore::PrivateClickMeasurement::AttributionTriggerData::decode): 48 Encoding and decoding of the new field sourceRegistrableDomain. 49 (WebCore::PrivateClickMeasurement::sourceUnlinkableToken const): Deleted. 50 Renamed sourceSecretToken. 51 Note that it was always the secret token used, just bad renaming earlier. 52 1 53 2021-11-17 Tim Horton <timothy_horton@apple.com> 2 54 -
trunk/Source/WebCore/html/HTMLAnchorElement.cpp
r285224 r285967 535 535 // A matching triggering event needs to happen before an attribution report can be sent. 536 536 // Thus, URLs should be empty for now. 537 ASSERT(!privateClickMeasurement || (privateClickMeasurement->attributionReport SourceURL().isNull() && privateClickMeasurement->attributionReportAttributeOnURL().isNull()));537 ASSERT(!privateClickMeasurement || (privateClickMeasurement->attributionReportClickSourceURL().isNull() && privateClickMeasurement->attributionReportClickDestinationURL().isNull())); 538 538 539 539 frame->loader().changeLocation(completedURL, effectiveTarget, &event, referrerPolicy, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute, systemPreviewInfo, WTFMove(privateClickMeasurement)); -
trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp
r285170 r285967 45 45 const size_t privateClickMeasurementAttributionTriggerDataPathSegmentSize = 2; 46 46 const size_t privateClickMeasurementPriorityPathSegmentSize = 2; 47 const uint8_t privateClickMeasurementVersion = 2; 47 48 48 49 const Seconds PrivateClickMeasurement::maxAge() … … 104 105 } 105 106 107 Expected<PrivateClickMeasurement::AttributionTriggerData, String> PrivateClickMeasurement::parseAttributionRequestQuery(const URL& redirectURL) 108 { 109 if (!redirectURL.hasQuery()) 110 return AttributionTriggerData { }; 111 112 auto parameters = queryParameters(redirectURL); 113 if (!parameters.size()) 114 return makeUnexpected("[Private Click Measurement] Conversion was not accepted because the URL had a query string but it didn't contain supported parameters."_s); 115 116 if (parameters.size() > 1) 117 return makeUnexpected("[Private Click Measurement] Conversion was not accepted because the URL's query string contained unsupported parameters."_s); 118 119 auto parameter = parameters.first(); 120 if (parameter.key == "attributionSource") { 121 if (parameter.value.isEmpty()) 122 return makeUnexpected("[Private Click Measurement] Conversion was not accepted because the URL's attributionSource query parameter had no value."_s); 123 124 auto attributionSourceURL = URL(URL(), parameter.value); 125 if (!attributionSourceURL.isValid() || (attributionSourceURL.hasPath() && attributionSourceURL.path().length() > 1) || attributionSourceURL.hasCredentials() || attributionSourceURL.hasQuery() || attributionSourceURL.hasFragmentIdentifier()) 126 return makeUnexpected("[Private Click Measurement] Conversion was not accepted because the URL's attributionSource query parameter was not a valid URL or was a URL with a path, credentials, query string, or fragment."_s); 127 128 AttributionTriggerData attributionTriggerData; 129 attributionTriggerData.sourceRegistrableDomain = RegistrableDomain { attributionSourceURL }; 130 return attributionTriggerData; 131 } 132 133 return makeUnexpected("[Private Click Measurement] Conversion was not accepted because the URL did not contain an attributionSource query parameter."_s); 134 } 135 106 136 Expected<PrivateClickMeasurement::AttributionTriggerData, String> PrivateClickMeasurement::parseAttributionRequest(const URL& redirectURL) 107 137 { … … 110 140 return makeUnexpected(nullString()); 111 141 112 if (!redirectURL.protocolIs("https") || redirectURL.hasCredentials() || redirectURL.hasQuery() || redirectURL.hasFragmentIdentifier()) 113 return makeUnexpected("[Private Click Measurement] Conversion was not accepted because the URL's protocol is not HTTPS or the URL contains one or more of username, password, query string, and fragment."_s); 114 142 if (!redirectURL.protocolIs("https") || redirectURL.hasCredentials() || redirectURL.hasFragmentIdentifier()) 143 return makeUnexpected("[Private Click Measurement] Conversion was not accepted because the URL's protocol is not HTTPS or the URL contains one or more of username, password, and fragment."_s); 144 145 auto result = parseAttributionRequestQuery(redirectURL); 146 if (!result && !result.error().isEmpty()) 147 return result; 148 auto attributionTriggerData = result.value(); 115 149 116 150 auto prefixLength = sizeof(privateClickMeasurementTriggerAttributionPath) - 1; … … 120 154 return makeUnexpected(makeString("[Private Click Measurement] Conversion was not accepted because the conversion data could not be parsed or was higher than the allowed maximum of "_s, AttributionTriggerData::MaxEntropy, "."_s)); 121 155 122 return AttributionTriggerData { static_cast<uint8_t>(*attributionTriggerDataUInt64), Priority { 0 } }; 156 attributionTriggerData.data = static_cast<uint8_t>(*attributionTriggerDataUInt64); 157 attributionTriggerData.priority = 0; 158 return attributionTriggerData; 123 159 } 124 160 … … 132 168 return makeUnexpected(makeString("[Private Click Measurement] Conversion was not accepted because the priority could not be parsed or was higher than the allowed maximum of "_s, Priority::MaxEntropy, "."_s)); 133 169 134 return AttributionTriggerData { static_cast<uint8_t>(*attributionTriggerDataUInt64), Priority { static_cast<uint8_t>(*attributionPriorityUInt64) } }; 170 attributionTriggerData.data = static_cast<uint8_t>(*attributionTriggerDataUInt64); 171 attributionTriggerData.priority = static_cast<uint8_t>(*attributionPriorityUInt64); 172 return attributionTriggerData; 135 173 } 136 174 … … 190 228 } 191 229 192 URL PrivateClickMeasurement::attributionReport SourceURL() const230 URL PrivateClickMeasurement::attributionReportClickSourceURL() const 193 231 { 194 232 if (!isValid()) … … 198 236 } 199 237 200 URL PrivateClickMeasurement::attributionReport AttributeOnURL() const238 URL PrivateClickMeasurement::attributionReportClickDestinationURL() const 201 239 { 202 240 if (!isValid()) … … 217 255 reportDetails->setString("attributed_on_site"_s, m_destinationSite.registrableDomain.string()); 218 256 reportDetails->setInteger("trigger_data"_s, m_attributionTriggerData->data); 219 reportDetails->setInteger("version"_s, 2);257 reportDetails->setInteger("version"_s, privateClickMeasurementVersion); 220 258 221 259 // This token has been kept secret this far and cannot be linked to the unlinkable token. … … 275 313 // This token can not be linked to the secret token. 276 314 reportDetails->setString("source_unlinkable_token"_s, m_sourceUnlinkableToken.valueBase64URL); 277 reportDetails->setInteger("version"_s, 2);315 reportDetails->setInteger("version"_s, privateClickMeasurementVersion); 278 316 return reportDetails; 279 317 } -
trunk/Source/WebCore/loader/PrivateClickMeasurement.h
r285170 r285967 173 173 174 174 enum class WasSent : bool { No, Yes }; 175 175 176 AttributionTriggerData() = default; 176 177 AttributionTriggerData(uint8_t data, Priority priority, WasSent wasSent = WasSent::No) 177 178 : data { data } … … 189 190 PriorityValue priority; 190 191 WasSent wasSent = WasSent::No; 192 std::optional<RegistrableDomain> sourceRegistrableDomain; 191 193 192 194 template<class Encoder> void encode(Encoder&) const; … … 318 320 WEBCORE_EXPORT AttributionSecondsUntilSendData attributeAndGetEarliestTimeToSend(AttributionTriggerData&&, IsRunningLayoutTest); 319 321 WEBCORE_EXPORT bool hasHigherPriorityThan(const PrivateClickMeasurement&) const; 320 WEBCORE_EXPORT URL attributionReport SourceURL() const;321 WEBCORE_EXPORT URL attributionReport AttributeOnURL() const;322 WEBCORE_EXPORT URL attributionReportClickSourceURL() const; 323 WEBCORE_EXPORT URL attributionReportClickDestinationURL() const; 322 324 WEBCORE_EXPORT Ref<JSON::Object> attributionReportJSON() const; 323 325 const SourceSite& sourceSite() const { return m_sourceSite; }; … … 372 374 373 375 void setSourceUnlinkableTokenValue(const String& value) { m_sourceUnlinkableToken.valueBase64URL = value; } 374 const std::optional<SourceSecretToken>& source UnlinkableToken() const { return m_sourceSecretToken; }376 const std::optional<SourceSecretToken>& sourceSecretToken() const { return m_sourceSecretToken; } 375 377 WEBCORE_EXPORT void setSourceSecretToken(SourceSecretToken&&); 376 378 … … 381 383 382 384 private: 385 static Expected<AttributionTriggerData, String> parseAttributionRequestQuery(const URL&); 383 386 bool isValid() const; 384 387 … … 506 509 void PrivateClickMeasurement::AttributionTriggerData::encode(Encoder& encoder) const 507 510 { 508 encoder << data << priority << wasSent ;511 encoder << data << priority << wasSent << sourceRegistrableDomain; 509 512 } 510 513 … … 527 530 return std::nullopt; 528 531 529 return AttributionTriggerData { WTFMove(*data), Priority { *priority }, *wasSent }; 532 std::optional<std::optional<RegistrableDomain>> sourceRegistrableDomain; 533 decoder >> sourceRegistrableDomain; 534 if (!sourceRegistrableDomain) 535 return std::nullopt; 536 537 AttributionTriggerData attributionTriggerData { WTFMove(*data), Priority { *priority }, *wasSent }; 538 attributionTriggerData.sourceRegistrableDomain = WTFMove(*sourceRegistrableDomain); 539 return attributionTriggerData; 530 540 } 531 541 -
trunk/Source/WebKit/ChangeLog
r285966 r285967 1 2021-11-17 John Wilander <wilander@apple.com> 2 3 PCM: Add capability for click destination to fire triggering event without cross-site requests to the click source 4 https://bugs.webkit.org/show_bug.cgi?id=233173 5 <rdar://79426605> 6 7 Reviewed by Alex Christensen. 8 9 This patch enables click destination sites a non-JavaScript way to fire triggering 10 events without a requirement to make cross-site requests to source sites. This is 11 referred to as a "same-site pixel API" and has been discussed in W3C Privacy CG: 12 https://github.com/privacycg/private-click-measurement/issues/71 13 14 The reason why some merchants want such an "API" is reluctance to deploy new 15 JavaScript on their sites. In some industries it's even a compliance issue. Legacy 16 "pixels" are however accepted and so a same-site "pixel" can work for them. 17 18 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp: 19 (WebKit::PCM::Database::insertPrivateClickMeasurement): 20 These changes are just a correction of a function name: 21 - sourceUnlinkableToken() to sourceSecretToken() 22 Note that it was always the secret token used, just bad renaming earlier. 23 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp: 24 (WebKit::PrivateClickMeasurementManager::handleAttribution): 25 Now checks if the incoming WebCore::PrivateClickMeasurement::AttributionTriggerData 26 carries a sourceRegistrableDomain. If so, it accepts that domain as the source site 27 for attribution if the triggering event was same-site as the first-party. 28 (WebKit::PrivateClickMeasurementManager::attribute): 29 (WebKit::PrivateClickMeasurementManager::fireConversionRequest): 30 These changes are just a correction of a function name: 31 - sourceUnlinkableToken() to sourceSecretToken() 32 Note that it was always the secret token used, just bad renaming earlier. 33 (WebKit::PrivateClickMeasurementManager::fireConversionRequestImpl): 34 These changes are because of clarification in naming: 35 - attributionReportSourceURL to attributionReportClickSourceURL 36 - attributionReportAttributeOnURL to attributionReportClickDestinationURL 37 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h: 38 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp: 39 (WebKit::PCM::Store::attributePrivateClickMeasurement): 40 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.h: 41 1 42 2021-11-17 Wenson Hsieh <wenson_hsieh@apple.com> 2 43 -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp
r285170 r285967 176 176 return; 177 177 178 auto& source UnlinkableToken = attribution.sourceUnlinkableToken();178 auto& sourceSecretToken = attribution.sourceSecretToken(); 179 179 if (attributionType == PrivateClickMeasurementAttributionType::Attributed) { 180 180 auto attributionTriggerData = attribution.attributionTriggerData() ? attribution.attributionTriggerData().value().data : -1; … … 195 195 || statement->bindDouble(6, attribution.timeOfAdClick().secondsSinceEpoch().value()) != SQLITE_OK 196 196 || statement->bindDouble(7, sourceEarliestTimeToSend) != SQLITE_OK 197 || statement->bindText(8, source UnlinkableToken ? sourceUnlinkableToken->tokenBase64URL : emptyString()) != SQLITE_OK198 || statement->bindText(9, source UnlinkableToken ? sourceUnlinkableToken->signatureBase64URL : emptyString()) != SQLITE_OK199 || statement->bindText(10, source UnlinkableToken ? sourceUnlinkableToken->keyIDBase64URL : emptyString()) != SQLITE_OK197 || statement->bindText(8, sourceSecretToken ? sourceSecretToken->tokenBase64URL : emptyString()) != SQLITE_OK 198 || statement->bindText(9, sourceSecretToken ? sourceSecretToken->signatureBase64URL : emptyString()) != SQLITE_OK 199 || statement->bindText(10, sourceSecretToken ? sourceSecretToken->keyIDBase64URL : emptyString()) != SQLITE_OK 200 200 || statement->bindDouble(11, destinationEarliestTimeToSend) != SQLITE_OK 201 201 || statement->bindText(12, attribution.sourceApplicationBundleID()) != SQLITE_OK … … 215 215 || statement->bindInt(3, attribution.sourceID().id) != SQLITE_OK 216 216 || statement->bindDouble(4, attribution.timeOfAdClick().secondsSinceEpoch().value()) != SQLITE_OK 217 || statement->bindText(5, source UnlinkableToken ? sourceUnlinkableToken->tokenBase64URL : emptyString()) != SQLITE_OK218 || statement->bindText(6, source UnlinkableToken ? sourceUnlinkableToken->signatureBase64URL : emptyString()) != SQLITE_OK219 || statement->bindText(7, source UnlinkableToken ? sourceUnlinkableToken->keyIDBase64URL : emptyString()) != SQLITE_OK217 || statement->bindText(5, sourceSecretToken ? sourceSecretToken->tokenBase64URL : emptyString()) != SQLITE_OK 218 || statement->bindText(6, sourceSecretToken ? sourceSecretToken->signatureBase64URL : emptyString()) != SQLITE_OK 219 || statement->bindText(7, sourceSecretToken ? sourceSecretToken->keyIDBase64URL : emptyString()) != SQLITE_OK 220 220 || statement->bindText(8, attribution.sourceApplicationBundleID()) != SQLITE_OK 221 221 || statement->step() != SQLITE_DONE) { -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp
r285170 r285967 249 249 } 250 250 251 RegistrableDomain sourceDomain; 251 252 if (redirectDomain.matches(firstPartyURL)) { 252 m_client->broadcastConsoleMessage(MessageLevel::Warning, "[Private Click Measurement] Triggering event was not accepted because it was requested in an HTTP redirect that is same-site as the first-party."_s); 253 return; 254 } 253 if (!attributionTriggerData.sourceRegistrableDomain) { 254 m_client->broadcastConsoleMessage(MessageLevel::Warning, "[Private Click Measurement] Triggering event was not accepted because it was requested in an HTTP redirect that is same-site as the first-party and no attributionSource query parameter was provided."_s); 255 return; 256 } 257 sourceDomain = *attributionTriggerData.sourceRegistrableDomain; 258 } else if (attributionTriggerData.sourceRegistrableDomain) { 259 m_client->broadcastConsoleMessage(MessageLevel::Warning, "[Private Click Measurement] Triggering event was not accepted because it was requested in an HTTP redirect that is cross-site from the first-party but an attributionSource query parameter was still provided."_s); 260 return; 261 } else 262 sourceDomain = WTFMove(redirectDomain); 255 263 256 264 m_client->broadcastConsoleMessage(MessageLevel::Log, "[Private Click Measurement] Triggering event accepted."_s); 257 265 258 attribute(SourceSite { WTFMove( redirectDomain) }, AttributionDestinationSite { firstPartyURL }, WTFMove(attributionTriggerData), m_privateClickMeasurementAppBundleIDForTesting ? *m_privateClickMeasurementAppBundleIDForTesting : applicationBundleIdentifier);266 attribute(SourceSite { WTFMove(sourceDomain) }, AttributionDestinationSite { firstPartyURL }, WTFMove(attributionTriggerData), m_privateClickMeasurementAppBundleIDForTesting ? *m_privateClickMeasurementAppBundleIDForTesting : applicationBundleIdentifier); 259 267 } 260 268 … … 277 285 } 278 286 279 void PrivateClickMeasurementManager::attribute( const SourceSite& sourceSite, const AttributionDestinationSite& destinationSite, AttributionTriggerData&& attributionTriggerData, const ApplicationBundleIdentifier& applicationBundleIdentifier)280 { 281 if (!featureEnabled()) 282 return; 283 284 store().attributePrivateClickMeasurement( sourceSite, destinationSite, applicationBundleIdentifier, WTFMove(attributionTriggerData), m_isRunningTest ? WebCore::PrivateClickMeasurement::IsRunningLayoutTest::Yes : WebCore::PrivateClickMeasurement::IsRunningLayoutTest::No, [this, weakThis = WeakPtr { *this }] (auto attributionSecondsUntilSendData, auto debugInfo) {287 void PrivateClickMeasurementManager::attribute(SourceSite&& sourceSite, AttributionDestinationSite&& destinationSite, AttributionTriggerData&& attributionTriggerData, const ApplicationBundleIdentifier& applicationBundleIdentifier) 288 { 289 if (!featureEnabled()) 290 return; 291 292 store().attributePrivateClickMeasurement(WTFMove(sourceSite), WTFMove(destinationSite), applicationBundleIdentifier, WTFMove(attributionTriggerData), m_isRunningTest ? WebCore::PrivateClickMeasurement::IsRunningLayoutTest::Yes : WebCore::PrivateClickMeasurement::IsRunningLayoutTest::No, [this, weakThis = WeakPtr { *this }] (auto attributionSecondsUntilSendData, auto debugInfo) { 285 293 if (!weakThis) 286 294 return; … … 320 328 return; 321 329 322 if (!attribution.source UnlinkableToken()) {330 if (!attribution.sourceSecretToken()) { 323 331 fireConversionRequestImpl(attribution, attributionReportEndpoint); 324 332 return; … … 340 348 341 349 auto keyID = base64URLEncodeToString(publicKeyDataHash.data(), publicKeyDataHash.size()); 342 if (keyID != attribution.source UnlinkableToken()->keyIDBase64URL)350 if (keyID != attribution.sourceSecretToken()->keyIDBase64URL) 343 351 return; 344 352 … … 352 360 switch (attributionReportEndpoint) { 353 361 case PrivateClickMeasurement::AttributionReportEndpoint::Source: 354 attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReport SourceURL : attribution.attributionReportSourceURL();362 attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReportClickSourceURL : attribution.attributionReportClickSourceURL(); 355 363 break; 356 364 case PrivateClickMeasurement::AttributionReportEndpoint::Destination: 357 attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReport AttributeOnURL : attribution.attributionReportAttributeOnURL();365 attributionURL = m_attributionReportTestConfig ? m_attributionReportTestConfig->attributionReportClickDestinationURL : attribution.attributionReportClickDestinationURL(); 358 366 } 359 367 -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h
r285170 r285967 77 77 void insertPrivateClickMeasurement(PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType, CompletionHandler<void()>&&); 78 78 void clearSentAttribution(PrivateClickMeasurement&&, PrivateClickMeasurement::AttributionReportEndpoint); 79 void attribute( const SourceSite&, const AttributionDestinationSite&, AttributionTriggerData&&, const ApplicationBundleIdentifier&);79 void attribute(SourceSite&&, AttributionDestinationSite&&, AttributionTriggerData&&, const ApplicationBundleIdentifier&); 80 80 void fireConversionRequest(const PrivateClickMeasurement&, PrivateClickMeasurement::AttributionReportEndpoint); 81 81 void fireConversionRequestImpl(const PrivateClickMeasurement&, PrivateClickMeasurement::AttributionReportEndpoint); … … 95 95 96 96 struct AttributionReportTestConfig { 97 URL attributionReport SourceURL;98 URL attributionReport AttributeOnURL;97 URL attributionReportClickSourceURL; 98 URL attributionReportClickDestinationURL; 99 99 }; 100 100 -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp
r285170 r285967 95 95 } 96 96 97 void Store::attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite& sourceSite, const WebCore::PrivateClickMeasurement::AttributionDestinationSite& destinationSite, const ApplicationBundleIdentifier& applicationBundleIdentifier, WebCore::PrivateClickMeasurement::AttributionTriggerData&& attributionTriggerData, WebCore::PrivateClickMeasurement::IsRunningLayoutTest isRunningTest, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>&&, DebugInfo&&)>&& completionHandler)97 void Store::attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&& sourceSite, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&& destinationSite, const ApplicationBundleIdentifier& applicationBundleIdentifier, WebCore::PrivateClickMeasurement::AttributionTriggerData&& attributionTriggerData, WebCore::PrivateClickMeasurement::IsRunningLayoutTest isRunningTest, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>&&, DebugInfo&&)>&& completionHandler) 98 98 { 99 99 postTask([this, protectedThis = Ref { *this }, sourceSite = sourceSite.isolatedCopy(), destinationSite = destinationSite.isolatedCopy(), applicationBundleIdentifier = applicationBundleIdentifier.isolatedCopy(), attributionTriggerData = WTFMove(attributionTriggerData), isRunningTest, completionHandler = WTFMove(completionHandler)] () mutable { -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.h
r285170 r285967 54 54 55 55 void insertPrivateClickMeasurement(WebCore::PrivateClickMeasurement&&, WebKit::PrivateClickMeasurementAttributionType, CompletionHandler<void()>&&); 56 void attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite& , const WebCore::PrivateClickMeasurement::AttributionDestinationSite&, const ApplicationBundleIdentifier&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&, WebCore::PrivateClickMeasurement::IsRunningLayoutTest, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>&&, DebugInfo&&)>&&);56 void attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&&, const ApplicationBundleIdentifier&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&, WebCore::PrivateClickMeasurement::IsRunningLayoutTest, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>&&, DebugInfo&&)>&&); 57 57 58 58 void privateClickMeasurementToStringForTesting(CompletionHandler<void(String)>&&) const; -
trunk/Tools/ChangeLog
r285963 r285967 1 2021-11-17 John Wilander <wilander@apple.com> 2 3 PCM: Add capability for click destination to fire triggering event without cross-site requests to the click source 4 https://bugs.webkit.org/show_bug.cgi?id=233173 5 <rdar://79426605> 6 7 Reviewed by Alex Christensen. 8 9 These changes are just a correction of a function name: 10 sourceUnlinkableToken() to sourceSecretToken() 11 12 * TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp: 13 (TestWebKitAPI::TEST): 14 * TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm: 15 (TestWebKitAPI::TEST): 16 1 17 2021-11-17 Ryan Haddad <ryanhaddad@apple.com> 2 18 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp
r285170 r285967 48 48 attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(min6BitValue, PrivateClickMeasurement::Priority(min6BitValue)), WebCore::PrivateClickMeasurement::IsRunningLayoutTest::No); 49 49 50 auto attributionSourceURL = attribution.attributionReport SourceURL();50 auto attributionSourceURL = attribution.attributionReportClickSourceURL(); 51 51 ASSERT_EQ(attributionSourceURL.string(), "https://webkit.org/.well-known/private-click-measurement/report-attribution/"); 52 auto attributionAttributeOnURL = attribution.attributionReport AttributeOnURL();52 auto attributionAttributeOnURL = attribution.attributionReportClickDestinationURL(); 53 53 ASSERT_EQ(attributionAttributeOnURL.string(), "https://example.com/.well-known/private-click-measurement/report-attribution/"); 54 54 } … … 138 138 attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)), WebCore::PrivateClickMeasurement::IsRunningLayoutTest::No); 139 139 140 ASSERT_TRUE(attribution.attributionReport SourceURL().isEmpty());141 ASSERT_TRUE(attribution.attributionReport AttributeOnURL().isEmpty());140 ASSERT_TRUE(attribution.attributionReportClickSourceURL().isEmpty()); 141 ASSERT_TRUE(attribution.attributionReportClickDestinationURL().isEmpty()); 142 142 } 143 143 … … 147 147 attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)), WebCore::PrivateClickMeasurement::IsRunningLayoutTest::No); 148 148 149 ASSERT_TRUE(attribution.attributionReport SourceURL().isEmpty());150 ASSERT_TRUE(attribution.attributionReport AttributeOnURL().isEmpty());149 ASSERT_TRUE(attribution.attributionReportClickSourceURL().isEmpty()); 150 ASSERT_TRUE(attribution.attributionReportClickDestinationURL().isEmpty()); 151 151 } 152 152 … … 156 156 attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData((PrivateClickMeasurement::AttributionTriggerData::MaxEntropy + 1), PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)), WebCore::PrivateClickMeasurement::IsRunningLayoutTest::No); 157 157 158 ASSERT_TRUE(attribution.attributionReport SourceURL().isEmpty());159 ASSERT_TRUE(attribution.attributionReport AttributeOnURL().isEmpty());158 ASSERT_TRUE(attribution.attributionReportClickSourceURL().isEmpty()); 159 ASSERT_TRUE(attribution.attributionReportClickDestinationURL().isEmpty()); 160 160 } 161 161 … … 165 165 attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy + 1)), WebCore::PrivateClickMeasurement::IsRunningLayoutTest::No); 166 166 167 ASSERT_TRUE(attribution.attributionReport SourceURL().isEmpty());168 ASSERT_TRUE(attribution.attributionReport AttributeOnURL().isEmpty());167 ASSERT_TRUE(attribution.attributionReportClickSourceURL().isEmpty()); 168 ASSERT_TRUE(attribution.attributionReportClickDestinationURL().isEmpty()); 169 169 } 170 170 … … 173 173 PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributionDestinationSite { exampleURL }, "test.bundle.identifier", WallTime::now(), WebCore::PrivateClickMeasurement::AttributionEphemeral::No }; 174 174 175 ASSERT_TRUE(attribution.attributionReport SourceURL().isEmpty());176 ASSERT_TRUE(attribution.attributionReport AttributeOnURL().isEmpty());175 ASSERT_TRUE(attribution.attributionReportClickSourceURL().isEmpty()); 176 ASSERT_TRUE(attribution.attributionReportClickDestinationURL().isEmpty()); 177 177 ASSERT_FALSE(attribution.timesToSend().sourceEarliestTimeToSend && attribution.timesToSend().destinationEarliestTimeToSend); 178 178 } -
trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm
r284890 r285967 95 95 errorMessage = pcm.calculateAndUpdateSourceSecretToken(base64URLEncodeToString([blindedSignature bytes], [blindedSignature length])); 96 96 EXPECT_FALSE(errorMessage); 97 auto& persistentToken = pcm.source UnlinkableToken();97 auto& persistentToken = pcm.sourceSecretToken(); 98 98 EXPECT_TRUE(persistentToken); 99 99 EXPECT_FALSE(persistentToken->tokenBase64URL.isEmpty());
Note:
See TracChangeset
for help on using the changeset viewer.