Title: [273088] trunk
Revision
273088
Author
wilan...@apple.com
Date
2021-02-18 11:44:39 -0800 (Thu, 18 Feb 2021)

Log Message

PCM: Request signature for unlinkable token using attributionSourceNonce
https://bugs.webkit.org/show_bug.cgi?id=222076
<rdar://73581651>

Reviewed by Chris Dumez.

Source/WebCore:

Test: http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html

* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
    Adoption of renamed function PrivateClickMeasurement::attributionReportURL().
* loader/PrivateClickMeasurement.cpp:
(WebCore::PrivateClickMeasurement::tokenSignatureURL const):
(WebCore::PrivateClickMeasurement::tokenSignatureJSON const):
    New functions to facilitate the request for a token signature.
(WebCore::PrivateClickMeasurement::attributionReportURL const):
(WebCore::PrivateClickMeasurement::attributionReportJSON const):
    Renamed functions to make them distinct from their token signing peers.
(WebCore::PrivateClickMeasurement::reportURL const): Deleted.
(WebCore::PrivateClickMeasurement::json const): Deleted.
* loader/PrivateClickMeasurement.h:
(WebCore::PrivateClickMeasurement::encode const):
(WebCore::PrivateClickMeasurement::decode):
(WebCore::PrivateClickMeasurement::EphemeralSourceNonce::encode const):
(WebCore::PrivateClickMeasurement::EphemeralSourceNonce::decode):
    Encode and decode to facilitate transfer over IPC.

Source/WebKit:

This patch makes PrivateClickMeasurementManager::storeUnattributed() look
for incoming source nonces and if found, call the new function
PrivateClickMeasurementManager::getSignedUnlinkableToken().

A new static function generateNetworkResourceLoadParameters() was added
to reuse code between PrivateClickMeasurementManager::getSignedUnlinkableToken()
and the existing PrivateClickMeasurementManager::fireConversionRequest().

To enable testing, there is a new function called
NetworkSession::setPrivateClickMeasurementTokenSignatureURLForTesting() and
function setPrivateClickMeasurementConversionURLForTesting() was renamed
setPrivateClickMeasurementAttributionReportURLForTesting() in NetworkProcess,
NetworkSession, WKPagePrivate, WKWebViewPrivateForTesting, and
PrivateClickMeasurementManager to align with the naming used in other places.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::setPrivateClickMeasurementTokenSignatureURLForTesting):
(WebKit::NetworkProcess::setPrivateClickMeasurementAttributionReportURLForTesting):
(WebKit::NetworkProcess::setPrivateClickMeasurementConversionURLForTesting): Deleted.
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/NetworkSession.cpp:
(WebKit::NetworkSession::setPrivateClickMeasurementTokenSignatureURLForTesting):
(WebKit::NetworkSession::setPrivateClickMeasurementAttributionReportURLForTesting):
(WebKit::NetworkSession::setPrivateClickMeasurementConversionURLForTesting): Deleted.
* NetworkProcess/NetworkSession.h:
* NetworkProcess/PrivateClickMeasurementManager.cpp:
(WebKit::PrivateClickMeasurementManager::storeUnattributed):
(WebKit::generateNetworkResourceLoadParameters):
(WebKit::PrivateClickMeasurementManager::getSignedUnlinkableToken):
(WebKit::PrivateClickMeasurementManager::fireConversionRequest):
(WebKit::PrivateClickMeasurementManager::setTokenSignatureURLForTesting):
(WebKit::PrivateClickMeasurementManager::setAttributionReportURLForTesting):
(WebKit::PrivateClickMeasurementManager::setConversionURLForTesting): Deleted.
* NetworkProcess/PrivateClickMeasurementManager.h:
* UIProcess/API/C/WKPage.cpp:
(WKPageSetPrivateClickMeasurementTokenSignatureURLForTesting):
(WKPageSetPrivateClickMeasurementAttributionReportURLForTesting):
(WKPageSetPrivateClickMeasurementConversionURLForTesting): Deleted.
* UIProcess/API/C/WKPagePrivate.h:
* UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
* UIProcess/API/Cocoa/WKWebViewTesting.mm:
(-[WKWebView _setPrivateClickMeasurementAttributionReportURLForTesting:completionHandler:]):
(-[WKWebView _setPrivateClickMeasurementConversionURLForTesting:completionHandler:]): Deleted.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::setPrivateClickMeasurementTokenSignatureURLForTesting):
(WebKit::WebPageProxy::setPrivateClickMeasurementAttributionReportURLForTesting):
(WebKit::WebPageProxy::setPrivateClickMeasurementConversionURLForTesting): Deleted.
* UIProcess/WebPageProxy.h:

Tools:

The changes to the TestRunner are:
- Rename setPrivateClickMeasurementConversionURLForTesting() to
setPrivateClickMeasurementAttributionReportURLForTesting() to align with other
naming and make it clear that it does.
- Add the new setPrivateClickMeasurementTokenSignatureURLForTesting() used for
testing the token signing request.

The changes to API tests are to adopt renamed functions in
WebCore::PrivateClickMeasurement:
- reportURL() renamed attributionReportURL().
- json() renamed attributionReportJSON().

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm:
(TestWebKitAPI::TEST):
* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setPrivateClickMeasurementTokenSignatureURLForTesting):
(WTR::TestRunner::setPrivateClickMeasurementAttributionReportURLForTesting):
(WTR::TestRunner::setPrivateClickMeasurementConversionURLForTesting): Deleted.
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::setPrivateClickMeasurementTokenSignatureURLForTesting):
(WTR::TestController::setPrivateClickMeasurementAttributionReportURLForTesting):
(WTR::TestController::setPrivateClickMeasurementConversionURLForTesting): Deleted.
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):

LayoutTests:

* http/tests/contentextensions/block-private-click-measurement.html:
    Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
* http/tests/privateClickMeasurement/conversion-disabled-in-ephemeral-session.html:
    Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
* http/tests/privateClickMeasurement/expired-attribution-report-gets-sent-on-session-start.html:
    Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
* http/tests/privateClickMeasurement/resources/getConversionData.php:
    Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
* http/tests/privateClickMeasurement/resources/getTokenSigningData.php: Added.
* http/tests/privateClickMeasurement/resources/signToken.php: Added.
* http/tests/privateClickMeasurement/resources/tokenSigningFilePath.php: Added.
* http/tests/privateClickMeasurement/resources/util.js:
(tearDownAndFinish):
    Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
    Now also calls setPrivateClickMeasurementTokenSignatureURLForTesting().
* http/tests/privateClickMeasurement/send-attribution-conversion-request.html:
    Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
* http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt: Added.
* http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (273087 => 273088)


--- trunk/LayoutTests/ChangeLog	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/LayoutTests/ChangeLog	2021-02-18 19:44:39 UTC (rev 273088)
@@ -1,3 +1,31 @@
+2021-02-18  John Wilander  <wilan...@apple.com>
+
+        PCM: Request signature for unlinkable token using attributionSourceNonce
+        https://bugs.webkit.org/show_bug.cgi?id=222076
+        <rdar://73581651>
+
+        Reviewed by Chris Dumez.
+
+        * http/tests/contentextensions/block-private-click-measurement.html:
+            Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
+        * http/tests/privateClickMeasurement/conversion-disabled-in-ephemeral-session.html:
+            Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
+        * http/tests/privateClickMeasurement/expired-attribution-report-gets-sent-on-session-start.html:
+            Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
+        * http/tests/privateClickMeasurement/resources/getConversionData.php:
+            Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
+        * http/tests/privateClickMeasurement/resources/getTokenSigningData.php: Added.
+        * http/tests/privateClickMeasurement/resources/signToken.php: Added.
+        * http/tests/privateClickMeasurement/resources/tokenSigningFilePath.php: Added.
+        * http/tests/privateClickMeasurement/resources/util.js:
+        (tearDownAndFinish):
+            Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
+            Now also calls setPrivateClickMeasurementTokenSignatureURLForTesting().
+        * http/tests/privateClickMeasurement/send-attribution-conversion-request.html:
+            Adoption of renamed TestRunner function setPrivateClickMeasurementAttributionReportURLForTesting().
+        * http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt: Added.
+        * http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html: Added.
+
 2021-02-18  Michael Saboff  <msab...@apple.com>
 
         [JSC] Implement RegExp Match Indices proposal

Modified: trunk/LayoutTests/http/tests/contentextensions/block-private-click-measurement.html (273087 => 273088)


--- trunk/LayoutTests/http/tests/contentextensions/block-private-click-measurement.html	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/LayoutTests/http/tests/contentextensions/block-private-click-measurement.html	2021-02-18 19:44:39 UTC (rev 273088)
@@ -15,7 +15,7 @@
 
     if (window.testRunner) {
         testRunner.setPrivateClickMeasurementOverrideTimerForTesting(true);
-        testRunner.setPrivateClickMeasurementConversionURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php");
+        testRunner.setPrivateClickMeasurementAttributionReportURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php");
     }
 
     function activateElement(elementID) {

Modified: trunk/LayoutTests/http/tests/privateClickMeasurement/conversion-disabled-in-ephemeral-session.html (273087 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/conversion-disabled-in-ephemeral-session.html	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/conversion-disabled-in-ephemeral-session.html	2021-02-18 19:44:39 UTC (rev 273088)
@@ -18,7 +18,7 @@
     prepareTest();
 
     if (window.testRunner)
-        testRunner.setPrivateClickMeasurementConversionURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php?nonce=" + nonce);
+        testRunner.setPrivateClickMeasurementAttributionReportURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php?nonce=" + nonce);
 
     function activateElement(elementID) {
         var element = document.getElementById(elementID);

Modified: trunk/LayoutTests/http/tests/privateClickMeasurement/expired-attribution-report-gets-sent-on-session-start.html (273087 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/expired-attribution-report-gets-sent-on-session-start.html	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/expired-attribution-report-gets-sent-on-session-start.html	2021-02-18 19:44:39 UTC (rev 273088)
@@ -18,7 +18,7 @@
     prepareTest();
 
     if (window.testRunner) {
-        testRunner.setPrivateClickMeasurementConversionURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php?nonce=" + nonce);
+        testRunner.setPrivateClickMeasurementAttributionReportURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php?nonce=" + nonce);
     }
 
     function activateElement(elementID) {

Modified: trunk/LayoutTests/http/tests/privateClickMeasurement/resources/getConversionData.php (273087 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/resources/getConversionData.php	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/resources/getConversionData.php	2021-02-18 19:44:39 UTC (rev 273088)
@@ -45,7 +45,7 @@
     echo "if (window.testRunner) {";
     echo "    testRunner.notifyDone();";
     echo "    testRunner.setPrivateClickMeasurementOverrideTimerForTesting(false);";
-    echo "    testRunner.setPrivateClickMeasurementConversionURLForTesting('');";
+    echo "    testRunner.setPrivateClickMeasurementAttributionReportURLForTesting('');";
     echo "}";
     echo "</script>";
 }

Copied: trunk/LayoutTests/http/tests/privateClickMeasurement/resources/getTokenSigningData.php (from rev 273087, trunk/LayoutTests/http/tests/privateClickMeasurement/resources/getConversionData.php) (0 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/resources/getTokenSigningData.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/resources/getTokenSigningData.php	2021-02-18 19:44:39 UTC (rev 273088)
@@ -0,0 +1,54 @@
+<?php
+require_once 'tokenSigningFilePath.php';
+
+$noTimeout = True;
+$timeoutMsecs = 0;
+if (isset($_GET['timeout_ms'])) {
+    $noTimeout = False;
+    $timeoutMsecs = (int) $_GET['timeout_ms'];
+}
+
+$tokenSigningFileFound = False;
+while ($noTimeout || $timeoutMsecs > 0) {
+    if (file_exists($tokenSigningFilePath)) {
+        $tokenSigningFileFound = True;
+        break;
+    }
+    $sleepMsecs = 10;
+    usleep($sleepMsecs * 1000);
+    if (!$noTimeout) {
+        $timeoutMsecs -= $sleepMsecs;
+    }
+    // file_exists() caches results, we want to invalidate the cache.
+    clearstatcache();
+}
+
+
+echo "<html><body>\n";
+
+if ($tokenSigningFileFound) {
+    echo "Token signing request received.";
+    $tokenSigningFile = fopen($tokenSigningFilePath, 'r');
+    while ($line = fgets($tokenSigningFile)) {
+        echo "<br>";
+        echo trim($line);
+    }
+    echo "<br>";
+    fclose($tokenSigningFile);
+    unlink($tokenSigningFilePath);
+} else {
+    echo "Token signing request not received - timed out.<br>";
+}
+
+if (isset($_GET['endTest'])) {
+    echo "<script>";
+    echo "if (window.testRunner) {";
+    echo "    testRunner.setPrivateClickMeasurementOverrideTimerForTesting(false);";
+    echo "    testRunner.setPrivateClickMeasurementTokenSignatureURLForTesting('');";
+    echo "    testRunner.notifyDone();";
+    echo "}";
+    echo "</script>";
+}
+
+echo "</body></html>";
+?>

Added: trunk/LayoutTests/http/tests/privateClickMeasurement/resources/signToken.php (0 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/resources/signToken.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/resources/signToken.php	2021-02-18 19:44:39 UTC (rev 273088)
@@ -0,0 +1,44 @@
+<?php
+require_once "tokenSigningFilePath.php";
+
+$tokenSigningFile = fopen($tokenSigningFilePath . ".tmp", 'w');
+$httpHeaders = $_SERVER;
+$cookiesFound = false;
+
+if ($value = $httpHeaders["HTTP_HOST"]) {
+    fwrite($tokenSigningFile, "HTTP_HOST: $value\n");
+}
+
+if ($value = $httpHeaders["HTTP_COOKIE"]) {
+    fwrite($tokenSigningFile, "Cookies in token signing request: $value\n");
+    $cookiesFound = true;
+}
+
+if ($value = $httpHeaders["CONTENT_TYPE"]) {
+    fwrite($tokenSigningFile, "Content type: $value\n");
+}
+
+if ($value = $httpHeaders["REQUEST_URI"]) {
+    $value = $httpHeaders["REQUEST_URI"];
+    $positionOfDummy = strpos($value, "?dummy=");
+    if ($positionOfDummy === false)
+        $outputURL = $value;
+    else
+        $outputURL = substr($value, 0, $positionOfDummy);
+    fwrite($tokenSigningFile, "REQUEST_URI: $outputURL\n");
+}
+
+if (!$cookiesFound) {
+    fwrite($tokenSigningFile, "No cookies in token signing request.\n");
+}
+
+$requestBody = file_get_contents("php://input");
+fwrite($tokenSigningFile, "Request body:\n$requestBody\n");
+
+fclose($tokenSigningFile);
+rename($tokenSigningFilePath . ".tmp", $tokenSigningFilePath);
+
+header("HTTP/1.1 201 Created");
+setcookie("cookieSetInTokenSigningResponse", "1", 0, "/");
+
+?>

Added: trunk/LayoutTests/http/tests/privateClickMeasurement/resources/tokenSigningFilePath.php (0 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/resources/tokenSigningFilePath.php	                        (rev 0)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/resources/tokenSigningFilePath.php	2021-02-18 19:44:39 UTC (rev 273088)
@@ -0,0 +1,9 @@
+<?php
+require_once '../../resources/portabilityLayer.php';
+
+if (isset($_GET["dummy"]))
+    $tokenSigningFileName = "/privateClickMeasurementTokenSigningRequest" . $_GET["dummy"] . ".txt";
+else
+    $tokenSigningFileName = "/privateClickMeasurementTokenSigningRequest.txt";
+$tokenSigningFilePath = sys_get_temp_dir() . $tokenSigningFileName;
+?>

Modified: trunk/LayoutTests/http/tests/privateClickMeasurement/resources/util.js (273087 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/resources/util.js	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/resources/util.js	2021-02-18 19:44:39 UTC (rev 273088)
@@ -11,7 +11,8 @@
     if (window.testRunner) {
         testRunner.setAllowsAnySSLCertificate(false);
         testRunner.setPrivateClickMeasurementOverrideTimerForTesting(false);
-        testRunner.setPrivateClickMeasurementConversionURLForTesting("");
+        testRunner.setPrivateClickMeasurementAttributionReportURLForTesting("");
+        testRunner.setPrivateClickMeasurementTokenSignatureURLForTesting("");
         testRunner.notifyDone();
     }
 }

Modified: trunk/LayoutTests/http/tests/privateClickMeasurement/send-attribution-conversion-request.html (273087 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/send-attribution-conversion-request.html	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/send-attribution-conversion-request.html	2021-02-18 19:44:39 UTC (rev 273088)
@@ -19,7 +19,6 @@
 
     if (window.testRunner) {
         testRunner.setPrivateClickMeasurementOverrideTimerForTesting(true);
-        testRunner.setPrivateClickMeasurementConversionURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php?nonce=" + nonce);
     }
 
     function activateElement(elementID) {
@@ -60,6 +59,7 @@
     function runTest() {
         if (window.testRunner) {
             if (window.location.search === "?stepTwo") {
+                testRunner.setPrivateClickMeasurementAttributionReportURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/conversionReport.php?nonce=" + nonce);
                 let imageElement = document.createElement("img");
                 imageElement.src = "" + nonce;
                 imageElement.id = "pixel";

Added: trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt (0 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce-expected.txt	2021-02-18 19:44:39 UTC (rev 273088)
@@ -0,0 +1,21 @@
+Tests that the presence of a source nonce triggers a token signing request.
+
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+Token signing request received.
+HTTP_HOST: 127.0.0.1:8000
+Content type: application/json
+REQUEST_URI: /privateClickMeasurement/resources/signToken.php
+No cookies in token signing request.
+Request body:
+{"source_engagement_type":"click","source_nonce":"ABCDEFabcdef0123456789","unlinkable_token":"TODO","version":2}
+
+Unattributed Private Click Measurements:
+WebCore::PrivateClickMeasurement 1
+Source site: 127.0.0.1
+Attribute on site: localhost
+Source ID: 3
+No attribution trigger data.

Copied: trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html (from rev 273087, trunk/LayoutTests/http/tests/contentextensions/block-private-click-measurement.html) (0 => 273088)


--- trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html	2021-02-18 19:44:39 UTC (rev 273088)
@@ -0,0 +1,66 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true PrivateClickMeasurementFraudPreventionEnabled=true ] -->
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+    <script src=""
+    <script src=""
+</head>
+<body _onload_="setTimeout(runTest, 0)">
+<div id="description">Tests that the presence of a source nonce triggers a token signing request.</div>
+<a id="targetLink" attributionsourceid="3" attributeon="http://localhost:8000" attributionsourcenonce="ABCDEFabcdef0123456789">Link</a><br>
+<div id="output"></div>
+<script>
+    if (!window.location.search)
+        prepareTest();
+
+    function activateElement(elementID) {
+        var element = document.getElementById(elementID);
+        var centerX = element.offsetLeft + element.offsetWidth / 2;
+        var centerY = element.offsetTop + element.offsetHeight / 2;
+        UIHelper.activateAt(centerX, centerY).then(
+            function () {
+            },
+            function () {
+                document.getElementById("output").innerText = "FAIL Promise rejected.";
+                tearDownAndFinish();
+            }
+        );
+    }
+
+    function appendIframe(url, onloadCallback) {
+        let iframeElement = document.createElement("iframe");
+        iframeElement.src = ""
+        if (onloadCallback)
+            iframeElement._onload_ = onloadCallback;
+        document.body.appendChild(iframeElement);
+    }
+
+    function appendTokenSignatureIframeAndFinish(dummy) {
+        appendIframe("http://127.0.0.1:8000/privateClickMeasurement/resources/getTokenSigningData.php?timeout_ms=4000&dummy=" + dummy, function() {
+            testRunner.dumpPrivateClickMeasurement();
+            document.body.removeChild(document.getElementById("targetLink"));
+            tearDownAndFinish();
+        });
+    }
+
+    function runTest() {
+        if (window.testRunner) {
+            if (!window.location.search) {
+                const currentTimeMillis = (new Date()).getTime();
+                const highEntropyBits = currentTimeMillis - (Math.floor(currentTimeMillis / 1000000) * 1000000);
+                const dummy = highEntropyBits + "" + Math.floor(Math.random() * 100);
+                testRunner.setPrivateClickMeasurementTokenSignatureURLForTesting("http://127.0.0.1:8000/privateClickMeasurement/resources/signToken.php?dummy=" + dummy);
+                targetLink.href = "" + dummy;
+                activateElement("targetLink");
+            } else {
+                let params = new URLSearchParams(window.location.search);
+                appendTokenSignatureIframeAndFinish(params.get("dummy"));
+            }
+        } else {
+            document.getElementById("output").innerText = "FAIL No testRunner.";
+        }
+    }
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (273087 => 273088)


--- trunk/Source/WebCore/ChangeLog	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebCore/ChangeLog	2021-02-18 19:44:39 UTC (rev 273088)
@@ -1,3 +1,32 @@
+2021-02-18  John Wilander  <wilan...@apple.com>
+
+        PCM: Request signature for unlinkable token using attributionSourceNonce
+        https://bugs.webkit.org/show_bug.cgi?id=222076
+        <rdar://73581651>
+
+        Reviewed by Chris Dumez.
+
+        Test: http/tests/privateClickMeasurement/store-private-click-measurement-with-source-nonce.html
+
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::handleClick):
+            Adoption of renamed function PrivateClickMeasurement::attributionReportURL().
+        * loader/PrivateClickMeasurement.cpp:
+        (WebCore::PrivateClickMeasurement::tokenSignatureURL const):
+        (WebCore::PrivateClickMeasurement::tokenSignatureJSON const):
+            New functions to facilitate the request for a token signature.
+        (WebCore::PrivateClickMeasurement::attributionReportURL const):
+        (WebCore::PrivateClickMeasurement::attributionReportJSON const):
+            Renamed functions to make them distinct from their token signing peers.
+        (WebCore::PrivateClickMeasurement::reportURL const): Deleted.
+        (WebCore::PrivateClickMeasurement::json const): Deleted.
+        * loader/PrivateClickMeasurement.h:
+        (WebCore::PrivateClickMeasurement::encode const):
+        (WebCore::PrivateClickMeasurement::decode):
+        (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::encode const):
+        (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::decode):
+            Encode and decode to facilitate transfer over IPC.
+
 2021-02-18  Michael Catanzaro  <mcatanz...@gnome.org>
 
         [GTK] Remove all Google user agent quirks except for Google Docs

Modified: trunk/Source/WebCore/html/HTMLAnchorElement.cpp (273087 => 273088)


--- trunk/Source/WebCore/html/HTMLAnchorElement.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -527,7 +527,7 @@
     auto privateClickMeasurement = parsePrivateClickMeasurement();
     // A matching conversion event needs to happen before the complete private click measurement
     // URL can be created. Thus, it should be empty for now.
-    ASSERT(!privateClickMeasurement || privateClickMeasurement->reportURL().isNull());
+    ASSERT(!privateClickMeasurement || privateClickMeasurement->attributionReportURL().isNull());
     
     frame->loader().changeLocation(completedURL, effectiveTarget, &event, referrerPolicy, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute, systemPreviewInfo, WTFMove(privateClickMeasurement));
 

Modified: trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp (273087 => 273088)


--- trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -37,6 +37,7 @@
 namespace WebCore {
 
 static const char privateClickMeasurementTriggerAttributionPath[] = "/.well-known/private-click-measurement/trigger-attribution/";
+static const char privateClickMeasurementTokenSignaturePath[] = "/.well-known/private-click-measurement/sign-unlinkable-token/";
 static const char privateClickMeasurementReportAttributionPath[] = "/.well-known/private-click-measurement/report-attribution/";
 const size_t privateClickMeasurementAttributionTriggerDataPathSegmentSize = 2;
 const size_t privateClickMeasurementPriorityPathSegmentSize = 2;
@@ -114,8 +115,38 @@
     return m_attributionTriggerData->priority > other.m_attributionTriggerData->priority;
 }
 
-URL PrivateClickMeasurement::reportURL() const
+URL PrivateClickMeasurement::tokenSignatureURL() const
 {
+    if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
+        return URL();
+
+    StringBuilder builder;
+    builder.appendLiteral("https://");
+    builder.append(m_sourceSite.registrableDomain.string());
+    builder.appendLiteral(privateClickMeasurementTokenSignaturePath);
+
+    URL url { URL(), builder.toString() };
+    if (url.isValid())
+        return url;
+
+    return URL();
+}
+
+Ref<JSON::Object> PrivateClickMeasurement::tokenSignatureJSON() const
+{
+    auto reportDetails = JSON::Object::create();
+    if (!m_ephemeralSourceNonce || !m_ephemeralSourceNonce->isValid())
+        return reportDetails;
+
+    reportDetails->setString("source_engagement_type"_s, "click"_s);
+    reportDetails->setString("source_nonce"_s, m_ephemeralSourceNonce->nonce);
+    reportDetails->setString("unlinkable_token"_s, "TODO"_s);
+    reportDetails->setInteger("version"_s, 2);
+    return reportDetails;
+}
+
+URL PrivateClickMeasurement::attributionReportURL() const
+{
     if (!isValid())
         return URL();
 
@@ -131,7 +162,7 @@
     return URL();
 }
 
-Ref<JSON::Object> PrivateClickMeasurement::json() const
+Ref<JSON::Object> PrivateClickMeasurement::attributionReportJSON() const
 {
     auto reportDetails = JSON::Object::create();
     if (!m_attributionTriggerData || !isValid())

Modified: trunk/Source/WebCore/loader/PrivateClickMeasurement.h (273087 => 273088)


--- trunk/Source/WebCore/loader/PrivateClickMeasurement.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebCore/loader/PrivateClickMeasurement.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -221,6 +221,9 @@
         }
 
         String nonce;
+
+        template<class Encoder> void encode(Encoder&) const;
+        template<class Decoder> static Optional<EphemeralSourceNonce> decode(Decoder&);
     };
 
     struct Priority {
@@ -274,8 +277,10 @@
     WEBCORE_EXPORT static Expected<AttributionTriggerData, String> parseAttributionRequest(const URL& redirectURL);
     WEBCORE_EXPORT Optional<Seconds> attributeAndGetEarliestTimeToSend(AttributionTriggerData&&);
     WEBCORE_EXPORT bool hasHigherPriorityThan(const PrivateClickMeasurement&) const;
-    WEBCORE_EXPORT URL reportURL() const;
-    WEBCORE_EXPORT Ref<JSON::Object> json() const;
+    WEBCORE_EXPORT URL tokenSignatureURL() const;
+    WEBCORE_EXPORT Ref<JSON::Object> tokenSignatureJSON() const;
+    WEBCORE_EXPORT URL attributionReportURL() const;
+    WEBCORE_EXPORT Ref<JSON::Object> attributionReportJSON() const;
     const SourceSite& sourceSite() const { return m_sourceSite; };
     const AttributeOnSite& attributeOnSite() const { return m_attributeOnSite; };
     void setEphemeralSourceNonce(EphemeralSourceNonce&& nonce) { m_ephemeralSourceNonce = WTFMove(nonce); };
@@ -318,6 +323,7 @@
         << m_sourceDescription
         << m_purchaser
         << m_timeOfAdClick
+        << m_ephemeralSourceNonce
         << m_attributionTriggerData
         << m_earliestTimeToSend;
 }
@@ -354,7 +360,12 @@
     decoder >> timeOfAdClick;
     if (!timeOfAdClick)
         return WTF::nullopt;
-    
+
+    Optional<Optional<EphemeralSourceNonce>> ephemeralSourceNonce;
+    decoder >> ephemeralSourceNonce;
+    if (!ephemeralSourceNonce)
+        return WTF::nullopt;
+
     Optional<Optional<AttributionTriggerData>> attributionTriggerData;
     decoder >> attributionTriggerData;
     if (!attributionTriggerData)
@@ -373,6 +384,7 @@
         WTFMove(*purchaser),
         WTFMove(*timeOfAdClick)
     };
+    attribution.m_ephemeralSourceNonce = WTFMove(*ephemeralSourceNonce);
     attribution.m_attributionTriggerData = WTFMove(*attributionTriggerData);
     attribution.m_earliestTimeToSend = WTFMove(*earliestTimeToSend);
     
@@ -380,6 +392,23 @@
 }
 
 template<class Encoder>
+void PrivateClickMeasurement::EphemeralSourceNonce::encode(Encoder& encoder) const
+{
+    encoder << nonce;
+}
+
+template<class Decoder>
+Optional<PrivateClickMeasurement::EphemeralSourceNonce> PrivateClickMeasurement::EphemeralSourceNonce::decode(Decoder& decoder)
+{
+    Optional<String> nonce;
+    decoder >> nonce;
+    if (!nonce)
+        return WTF::nullopt;
+    
+    return EphemeralSourceNonce { WTFMove(*nonce) };
+}
+
+template<class Encoder>
 void PrivateClickMeasurement::AttributionTriggerData::encode(Encoder& encoder) const
 {
     encoder << data << priority << wasSent;

Modified: trunk/Source/WebKit/ChangeLog (273087 => 273088)


--- trunk/Source/WebKit/ChangeLog	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/ChangeLog	2021-02-18 19:44:39 UTC (rev 273088)
@@ -1,3 +1,61 @@
+2021-02-18  John Wilander  <wilan...@apple.com>
+
+        PCM: Request signature for unlinkable token using attributionSourceNonce
+        https://bugs.webkit.org/show_bug.cgi?id=222076
+        <rdar://73581651>
+
+        Reviewed by Chris Dumez.
+
+        This patch makes PrivateClickMeasurementManager::storeUnattributed() look
+        for incoming source nonces and if found, call the new function
+        PrivateClickMeasurementManager::getSignedUnlinkableToken().
+
+        A new static function generateNetworkResourceLoadParameters() was added
+        to reuse code between PrivateClickMeasurementManager::getSignedUnlinkableToken()
+        and the existing PrivateClickMeasurementManager::fireConversionRequest().
+
+        To enable testing, there is a new function called
+        NetworkSession::setPrivateClickMeasurementTokenSignatureURLForTesting() and
+        function setPrivateClickMeasurementConversionURLForTesting() was renamed
+        setPrivateClickMeasurementAttributionReportURLForTesting() in NetworkProcess,
+        NetworkSession, WKPagePrivate, WKWebViewPrivateForTesting, and
+        PrivateClickMeasurementManager to align with the naming used in other places.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::setPrivateClickMeasurementTokenSignatureURLForTesting):
+        (WebKit::NetworkProcess::setPrivateClickMeasurementAttributionReportURLForTesting):
+        (WebKit::NetworkProcess::setPrivateClickMeasurementConversionURLForTesting): Deleted.
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/NetworkSession.cpp:
+        (WebKit::NetworkSession::setPrivateClickMeasurementTokenSignatureURLForTesting):
+        (WebKit::NetworkSession::setPrivateClickMeasurementAttributionReportURLForTesting):
+        (WebKit::NetworkSession::setPrivateClickMeasurementConversionURLForTesting): Deleted.
+        * NetworkProcess/NetworkSession.h:
+        * NetworkProcess/PrivateClickMeasurementManager.cpp:
+        (WebKit::PrivateClickMeasurementManager::storeUnattributed):
+        (WebKit::generateNetworkResourceLoadParameters):
+        (WebKit::PrivateClickMeasurementManager::getSignedUnlinkableToken):
+        (WebKit::PrivateClickMeasurementManager::fireConversionRequest):
+        (WebKit::PrivateClickMeasurementManager::setTokenSignatureURLForTesting):
+        (WebKit::PrivateClickMeasurementManager::setAttributionReportURLForTesting):
+        (WebKit::PrivateClickMeasurementManager::setConversionURLForTesting): Deleted.
+        * NetworkProcess/PrivateClickMeasurementManager.h:
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPrivateClickMeasurementTokenSignatureURLForTesting):
+        (WKPageSetPrivateClickMeasurementAttributionReportURLForTesting):
+        (WKPageSetPrivateClickMeasurementConversionURLForTesting): Deleted.
+        * UIProcess/API/C/WKPagePrivate.h:
+        * UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
+        * UIProcess/API/Cocoa/WKWebViewTesting.mm:
+        (-[WKWebView _setPrivateClickMeasurementAttributionReportURLForTesting:completionHandler:]):
+        (-[WKWebView _setPrivateClickMeasurementConversionURLForTesting:completionHandler:]): Deleted.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::setPrivateClickMeasurementTokenSignatureURLForTesting):
+        (WebKit::WebPageProxy::setPrivateClickMeasurementAttributionReportURLForTesting):
+        (WebKit::WebPageProxy::setPrivateClickMeasurementConversionURLForTesting): Deleted.
+        * UIProcess/WebPageProxy.h:
+
 2021-02-18  Michael Catanzaro  <mcatanz...@gnome.org>
 
         [WPE][GTK] Avoid another child setup function in process launcher code

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (273087 => 273088)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -2607,14 +2607,22 @@
     completionHandler();
 }
 
-void NetworkProcess::setPrivateClickMeasurementConversionURLForTesting(PAL::SessionID sessionID, URL&& url, CompletionHandler<void()>&& completionHandler)
+void NetworkProcess::setPrivateClickMeasurementTokenSignatureURLForTesting(PAL::SessionID sessionID, URL&& url, CompletionHandler<void()>&& completionHandler)
 {
     if (auto* session = networkSession(sessionID))
-        session->setPrivateClickMeasurementConversionURLForTesting(WTFMove(url));
+        session->setPrivateClickMeasurementTokenSignatureURLForTesting(WTFMove(url));
     
     completionHandler();
 }
 
+void NetworkProcess::setPrivateClickMeasurementAttributionReportURLForTesting(PAL::SessionID sessionID, URL&& url, CompletionHandler<void()>&& completionHandler)
+{
+    if (auto* session = networkSession(sessionID))
+        session->setPrivateClickMeasurementAttributionReportURLForTesting(WTFMove(url));
+    
+    completionHandler();
+}
+
 void NetworkProcess::markPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
 {
     if (auto* session = networkSession(sessionID))

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (273087 => 273088)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -342,7 +342,8 @@
     void setPrivateClickMeasurementOverrideTimerForTesting(PAL::SessionID, bool value, CompletionHandler<void()>&&);
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID, CompletionHandler<void()>&&);
     void simulateResourceLoadStatisticsSessionRestart(PAL::SessionID, CompletionHandler<void()>&&);
-    void setPrivateClickMeasurementConversionURLForTesting(PAL::SessionID, URL&&, CompletionHandler<void()>&&);
+    void setPrivateClickMeasurementTokenSignatureURLForTesting(PAL::SessionID, URL&&, CompletionHandler<void()>&&);
+    void setPrivateClickMeasurementAttributionReportURLForTesting(PAL::SessionID, URL&&, CompletionHandler<void()>&&);
     void markPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID, CompletionHandler<void()>&&);
 
     RefPtr<WebCore::StorageQuotaManager> storageQuotaManager(PAL::SessionID, const WebCore::ClientOrigin&);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (273087 => 273088)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2021-02-18 19:44:39 UTC (rev 273088)
@@ -167,7 +167,8 @@
     SetPrivateClickMeasurementOverrideTimerForTesting(PAL::SessionID sessionID, bool value) -> () Async
     MarkAttributedPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID sessionID) -> () Async
     SimulateResourceLoadStatisticsSessionRestart(PAL::SessionID sessionID) -> () Async
-    SetPrivateClickMeasurementConversionURLForTesting(PAL::SessionID sessionID, URL url) -> () Async
+    SetPrivateClickMeasurementTokenSignatureURLForTesting(PAL::SessionID sessionID, URL url) -> () Async
+    SetPrivateClickMeasurementAttributionReportURLForTesting(PAL::SessionID sessionID, URL url) -> () Async
     MarkPrivateClickMeasurementsAsExpiredForTesting(PAL::SessionID sessionID) -> () Async
     GetLocalStorageOriginDetails(PAL::SessionID sessionID) -> (Vector<WebKit::LocalStorageDatabaseTracker::OriginDetails> details) Async
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (273087 => 273088)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -338,11 +338,16 @@
     privateClickMeasurement().markAttributedPrivateClickMeasurementsAsExpiredForTesting(WTFMove(completionHandler));
 }
 
-void NetworkSession::setPrivateClickMeasurementConversionURLForTesting(URL&& url)
+void NetworkSession::setPrivateClickMeasurementTokenSignatureURLForTesting(URL&& url)
 {
-    privateClickMeasurement().setConversionURLForTesting(WTFMove(url));
+    privateClickMeasurement().setTokenSignatureURLForTesting(WTFMove(url));
 }
 
+void NetworkSession::setPrivateClickMeasurementAttributionReportURLForTesting(URL&& url)
+{
+    privateClickMeasurement().setAttributionReportURLForTesting(WTFMove(url));
+}
+
 void NetworkSession::markPrivateClickMeasurementsAsExpiredForTesting()
 {
     privateClickMeasurement().markAllUnattributedAsExpiredForTesting();

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (273087 => 273088)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -123,7 +123,8 @@
     void clearPrivateClickMeasurementForRegistrableDomain(WebCore::RegistrableDomain&&);
     void setPrivateClickMeasurementOverrideTimerForTesting(bool value);
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
-    void setPrivateClickMeasurementConversionURLForTesting(URL&&);
+    void setPrivateClickMeasurementTokenSignatureURLForTesting(URL&&);
+    void setPrivateClickMeasurementAttributionReportURLForTesting(URL&&);
     void markPrivateClickMeasurementsAsExpiredForTesting();
     void firePrivateClickMeasurementTimerImmediately();
 

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp (273087 => 273088)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -47,6 +47,7 @@
 using SourceSite = PrivateClickMeasurement::SourceSite;
 using AttributeOnSite = PrivateClickMeasurement::AttributeOnSite;
 using AttributionTriggerData = PrivateClickMeasurement::AttributionTriggerData;
+using EphemeralSourceNonce = PrivateClickMeasurement::EphemeralSourceNonce;
 
 constexpr Seconds debugModeSecondsUntilSend { 10_s };
 
@@ -73,6 +74,9 @@
 
     clearExpired();
 
+    if (attribution.ephemeralSourceNonce())
+        getSignedUnlinkableToken(attribution);
+
     m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] Storing an ad click."_s);
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
@@ -81,6 +85,67 @@
 #endif
 }
 
+static NetworkResourceLoadParameters generateNetworkResourceLoadParameters(URL&& url, Ref<JSON::Object> jsonPayload, PrivateClickMeasurement::PcmDataCarried dataTypeCarried)
+{
+    static uint64_t identifier = 0;
+    
+    ResourceRequest request { WTFMove(url) };
+    request.setHTTPMethod("POST"_s);
+    request.setHTTPHeaderField(HTTPHeaderName::CacheControl, WebCore::HTTPHeaderValues::maxAge0());
+    request.setHTTPContentType(WebCore::HTTPHeaderValues::applicationJSONContentType());
+    request.setHTTPBody(WebCore::FormData::create(jsonPayload->toJSONString().utf8().data()));
+
+    FetchOptions options;
+    options.credentials = FetchOptions::Credentials::Omit;
+    options.redirect = FetchOptions::Redirect::Error;
+
+    NetworkResourceLoadParameters loadParameters;
+    loadParameters.identifier = ++identifier;
+    loadParameters.request = request;
+    loadParameters.parentPID = presentingApplicationPID();
+    loadParameters.storedCredentialsPolicy = StoredCredentialsPolicy::EphemeralStateless;
+    loadParameters.options = options;
+    loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = true;
+    loadParameters.shouldRestrictHTTPResponseAccess = false;
+    loadParameters.pcmDataCarried = dataTypeCarried;
+    
+    return loadParameters;
+}
+
+void PrivateClickMeasurementManager::getSignedUnlinkableToken(const PrivateClickMeasurement& attribution)
+{
+    if (!featureEnabled())
+        return;
+
+    auto tokenSignatureURL = attribution.tokenSignatureURL();
+    auto pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::PersonallyIdentifiable;
+    if (m_tokenSignatureURLForTesting) {
+        tokenSignatureURL = *m_tokenSignatureURLForTesting;
+        pcmDataCarried = PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable;
+    }
+
+    if (tokenSignatureURL.isEmpty() || !tokenSignatureURL.isValid())
+        return;
+
+    auto loadParameters = generateNetworkResourceLoadParameters(WTFMove(tokenSignatureURL), attribution.tokenSignatureJSON(), pcmDataCarried);
+
+    RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire a unlinkable token signing request.");
+    m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire a unlinkable token signing request."_s);
+
+    m_pingLoadFunction(WTFMove(loadParameters), [weakThis = makeWeakPtr(*this)](const WebCore::ResourceError& error, const WebCore::ResourceResponse& response) {
+        if (!weakThis)
+            return;
+
+        if (!error.isNull()) {
+            weakThis->m_networkProcess->broadcastConsoleMessage(weakThis->m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Error, makeString("[Private Click Measurement] Received error: '"_s, error.localizedDescription(), "' for unlinkable token signing request."_s));
+            return;
+        }
+        
+        // FIXME: Receive and store the signed unlinkable token, rdar://73582032.
+    });
+
+}
+
 void PrivateClickMeasurementManager::handleAttribution(AttributionTriggerData&& attributionTriggerData, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest)
 {
     if (!featureEnabled())
@@ -138,34 +203,12 @@
     if (!featureEnabled())
         return;
 
-    auto attributionURL = m_attributionBaseURLForTesting ? *m_attributionBaseURLForTesting : attribution.reportURL();
+    auto attributionURL = m_attributionReportBaseURLForTesting ? *m_attributionReportBaseURLForTesting : attribution.attributionReportURL();
     if (attributionURL.isEmpty() || !attributionURL.isValid())
         return;
 
-    ResourceRequest request { WTFMove(attributionURL) };
-    
-    request.setHTTPMethod("POST"_s);
-    request.setHTTPHeaderField(HTTPHeaderName::CacheControl, WebCore::HTTPHeaderValues::maxAge0());
+    auto loadParameters = generateNetworkResourceLoadParameters(WTFMove(attributionURL), attribution.attributionReportJSON(), PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable);
 
-    request.setHTTPContentType(WebCore::HTTPHeaderValues::applicationJSONContentType());
-    request.setHTTPBody(WebCore::FormData::create(attribution.json()->toJSONString().utf8().data()));
-
-    FetchOptions options;
-    options.credentials = FetchOptions::Credentials::Omit;
-    options.redirect = FetchOptions::Redirect::Error;
-
-    static uint64_t identifier = 0;
-    
-    NetworkResourceLoadParameters loadParameters;
-    loadParameters.identifier = ++identifier;
-    loadParameters.request = request;
-    loadParameters.parentPID = presentingApplicationPID();
-    loadParameters.storedCredentialsPolicy = StoredCredentialsPolicy::EphemeralStateless;
-    loadParameters.options = options;
-    loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = true;
-    loadParameters.shouldRestrictHTTPResponseAccess = false;
-    loadParameters.pcmDataCarried = WebCore::PrivateClickMeasurement::PcmDataCarried::NonPersonallyIdentifiable;
-
     RELEASE_LOG_INFO(PrivateClickMeasurement, "About to fire an attribution request.");
     m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, MessageLevel::Log, "[Private Click Measurement] About to fire an attribution request."_s);
 
@@ -293,14 +336,22 @@
     completionHandler("\nNo stored Private Click Measurement data.\n"_s);
 }
 
-void PrivateClickMeasurementManager::setConversionURLForTesting(URL&& testURL)
+void PrivateClickMeasurementManager::setTokenSignatureURLForTesting(URL&& testURL)
 {
     if (testURL.isEmpty())
-        m_attributionBaseURLForTesting = { };
+        m_tokenSignatureURLForTesting = { };
     else
-        m_attributionBaseURLForTesting = WTFMove(testURL);
+        m_tokenSignatureURLForTesting = WTFMove(testURL);
 }
 
+void PrivateClickMeasurementManager::setAttributionReportURLForTesting(URL&& testURL)
+{
+    if (testURL.isEmpty())
+        m_attributionReportBaseURLForTesting = { };
+    else
+        m_attributionReportBaseURLForTesting = WTFMove(testURL);
+}
+
 void PrivateClickMeasurementManager::markAllUnattributedAsExpiredForTesting()
 {
 #if ENABLE(RESOURCE_LOAD_STATISTICS)

Modified: trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h (273087 => 273088)


--- trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -61,12 +61,14 @@
     void toString(CompletionHandler<void(String)>&&) const;
     void setPingLoadFunction(Function<void(NetworkResourceLoadParameters&&, CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&&)>&& pingLoadFunction) { m_pingLoadFunction = WTFMove(pingLoadFunction); }
     void setOverrideTimerForTesting(bool value) { m_isRunningTest = value; }
-    void setConversionURLForTesting(URL&&);
+    void setTokenSignatureURLForTesting(URL&&);
+    void setAttributionReportURLForTesting(URL&&);
     void markAllUnattributedAsExpiredForTesting();
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
     void startTimer(Seconds);
 
 private:
+    void getSignedUnlinkableToken(const PrivateClickMeasurement&);
     void clearSentAttribution(PrivateClickMeasurement&&);
     void attribute(const SourceSite&, const AttributeOnSite&, AttributionTriggerData&&);
     void fireConversionRequest(const PrivateClickMeasurement&);
@@ -77,7 +79,8 @@
 
     WebCore::Timer m_firePendingAttributionRequestsTimer;
     bool m_isRunningTest { false };
-    Optional<URL> m_attributionBaseURLForTesting;
+    Optional<URL> m_tokenSignatureURLForTesting;
+    Optional<URL> m_attributionReportBaseURLForTesting;
     WeakPtr<NetworkSession> m_networkSession;
     Ref<NetworkProcess> m_networkProcess;
     PAL::SessionID m_sessionID;

Modified: trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp (273087 => 273088)


--- trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -2945,13 +2945,20 @@
     });
 }
 
-void WKPageSetPrivateClickMeasurementConversionURLForTesting(WKPageRef page, WKURLRef URLRef, WKPageSetPrivateClickMeasurementConversionURLForTestingFunction callback, void* callbackContext)
+void WKPageSetPrivateClickMeasurementTokenSignatureURLForTesting(WKPageRef page, WKURLRef URLRef, WKPageSetPrivateClickMeasurementTokenSignatureURLForTestingFunction callback, void* callbackContext)
 {
-    toImpl(page)->setPrivateClickMeasurementConversionURLForTesting(URL(URL(), toWTFString(URLRef)), [callbackContext, callback] () {
+    toImpl(page)->setPrivateClickMeasurementTokenSignatureURLForTesting(URL(URL(), toWTFString(URLRef)), [callbackContext, callback] () {
         callback(callbackContext);
     });
 }
 
+void WKPageSetPrivateClickMeasurementAttributionReportURLForTesting(WKPageRef page, WKURLRef URLRef, WKPageSetPrivateClickMeasurementAttributionReportURLForTestingFunction callback, void* callbackContext)
+{
+    toImpl(page)->setPrivateClickMeasurementAttributionReportURLForTesting(URL(URL(), toWTFString(URLRef)), [callbackContext, callback] () {
+        callback(callbackContext);
+    });
+}
+
 void WKPageMarkPrivateClickMeasurementsAsExpiredForTesting(WKPageRef page, WKPageMarkPrivateClickMeasurementsAsExpiredForTestingFunction callback, void* callbackContext)
 {
     toImpl(page)->markPrivateClickMeasurementsAsExpiredForTesting([callbackContext, callback] () {

Modified: trunk/Source/WebKit/UIProcess/API/C/WKPagePrivate.h (273087 => 273088)


--- trunk/Source/WebKit/UIProcess/API/C/WKPagePrivate.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPagePrivate.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -179,8 +179,10 @@
 WK_EXPORT void WKPageMarkAttributedPrivateClickMeasurementsAsExpiredForTesting(WKPageRef page, WKPageMarkAttributedPrivateClickMeasurementsAsExpiredForTestingFunction callback, void* callbackContext);
 typedef void (*WKPageSimulateResourceLoadStatisticsSessionRestartFunction)(void* functionContext);
 WK_EXPORT void WKPageSimulateResourceLoadStatisticsSessionRestart(WKPageRef page, WKPageSimulateResourceLoadStatisticsSessionRestartFunction callback, void* callbackContext);
-typedef void (*WKPageSetPrivateClickMeasurementConversionURLForTestingFunction)(void* functionContext);
-WK_EXPORT void WKPageSetPrivateClickMeasurementConversionURLForTesting(WKPageRef page, WKURLRef urlString, WKPageSetPrivateClickMeasurementConversionURLForTestingFunction callback, void* callbackContext);
+typedef void (*WKPageSetPrivateClickMeasurementTokenSignatureURLForTestingFunction)(void* functionContext);
+WK_EXPORT void WKPageSetPrivateClickMeasurementTokenSignatureURLForTesting(WKPageRef page, WKURLRef urlString, WKPageSetPrivateClickMeasurementTokenSignatureURLForTestingFunction callback, void* callbackContext);
+typedef void (*WKPageSetPrivateClickMeasurementAttributionReportURLForTestingFunction)(void* functionContext);
+WK_EXPORT void WKPageSetPrivateClickMeasurementAttributionReportURLForTesting(WKPageRef page, WKURLRef urlString, WKPageSetPrivateClickMeasurementAttributionReportURLForTestingFunction callback, void* callbackContext);
 typedef void (*WKPageMarkPrivateClickMeasurementsAsExpiredForTestingFunction)(void* functionContext);
 WK_EXPORT void WKPageMarkPrivateClickMeasurementsAsExpiredForTesting(WKPageRef page, WKPageMarkPrivateClickMeasurementsAsExpiredForTestingFunction callback, void* callbackContext);
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h (273087 => 273088)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -85,6 +85,6 @@
 - (NSNumber *)_suspendMediaPlaybackCounter WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (void)_setPrivateClickMeasurementOverrideTimerForTesting:(BOOL)overrideTimer completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
-- (void)_setPrivateClickMeasurementConversionURLForTesting:(NSURL *)url completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_setPrivateClickMeasurementAttributionReportURLForTesting:(NSURL *)url completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm (273087 => 273088)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2021-02-18 19:44:39 UTC (rev 273088)
@@ -302,9 +302,9 @@
     });
 }
 
-- (void)_setPrivateClickMeasurementConversionURLForTesting:(NSURL *)url completionHandler:(void(^)(void))completionHandler
+- (void)_setPrivateClickMeasurementAttributionReportURLForTesting:(NSURL *)url completionHandler:(void(^)(void))completionHandler
 {
-    _page->setPrivateClickMeasurementConversionURLForTesting(url, [completionHandler = makeBlockPtr(completionHandler)] {
+    _page->setPrivateClickMeasurementAttributionReportURLForTesting(url, [completionHandler = makeBlockPtr(completionHandler)] {
         completionHandler();
     });
 }

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (273087 => 273088)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -10019,11 +10019,16 @@
     websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::SimulateResourceLoadStatisticsSessionRestart(m_websiteDataStore->sessionID()), WTFMove(completionHandler));
 }
 
-void WebPageProxy::setPrivateClickMeasurementConversionURLForTesting(const URL& url, CompletionHandler<void()>&& completionHandler)
+void WebPageProxy::setPrivateClickMeasurementTokenSignatureURLForTesting(const URL& url, CompletionHandler<void()>&& completionHandler)
 {
-    websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::SetPrivateClickMeasurementConversionURLForTesting(m_websiteDataStore->sessionID(), url), WTFMove(completionHandler));
+    websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::SetPrivateClickMeasurementTokenSignatureURLForTesting(m_websiteDataStore->sessionID(), url), WTFMove(completionHandler));
 }
 
+void WebPageProxy::setPrivateClickMeasurementAttributionReportURLForTesting(const URL& url, CompletionHandler<void()>&& completionHandler)
+{
+    websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::SetPrivateClickMeasurementAttributionReportURLForTesting(m_websiteDataStore->sessionID(), url), WTFMove(completionHandler));
+}
+
 void WebPageProxy::markPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&& completionHandler)
 {
     websiteDataStore().networkProcess().sendWithAsyncReply(Messages::NetworkProcess::MarkPrivateClickMeasurementsAsExpiredForTesting(m_websiteDataStore->sessionID()), WTFMove(completionHandler));

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (273087 => 273088)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -1691,7 +1691,8 @@
     void setPrivateClickMeasurementOverrideTimerForTesting(bool value, CompletionHandler<void()>&&);
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
     void simulateResourceLoadStatisticsSessionRestart(CompletionHandler<void()>&&);
-    void setPrivateClickMeasurementConversionURLForTesting(const URL&, CompletionHandler<void()>&&);
+    void setPrivateClickMeasurementTokenSignatureURLForTesting(const URL&, CompletionHandler<void()>&&);
+    void setPrivateClickMeasurementAttributionReportURLForTesting(const URL&, CompletionHandler<void()>&&);
     void markPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&);
 
 #if ENABLE(SPEECH_SYNTHESIS)

Modified: trunk/Tools/ChangeLog (273087 => 273088)


--- trunk/Tools/ChangeLog	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/ChangeLog	2021-02-18 19:44:39 UTC (rev 273088)
@@ -1,3 +1,42 @@
+2021-02-18  John Wilander  <wilan...@apple.com>
+
+        PCM: Request signature for unlinkable token using attributionSourceNonce
+        https://bugs.webkit.org/show_bug.cgi?id=222076
+        <rdar://73581651>
+
+        Reviewed by Chris Dumez.
+
+        The changes to the TestRunner are:
+        - Rename setPrivateClickMeasurementConversionURLForTesting() to
+        setPrivateClickMeasurementAttributionReportURLForTesting() to align with other
+        naming and make it clear that it does.
+        - Add the new setPrivateClickMeasurementTokenSignatureURLForTesting() used for
+        testing the token signing request.
+
+        The changes to API tests are to adopt renamed functions in
+        WebCore::PrivateClickMeasurement:
+        - reportURL() renamed attributionReportURL().
+        - json() renamed attributionReportJSON().
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm:
+        (TestWebKitAPI::TEST):
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setPrivateClickMeasurementTokenSignatureURLForTesting):
+        (WTR::TestRunner::setPrivateClickMeasurementAttributionReportURLForTesting):
+        (WTR::TestRunner::setPrivateClickMeasurementConversionURLForTesting): Deleted.
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::setPrivateClickMeasurementTokenSignatureURLForTesting):
+        (WTR::TestController::setPrivateClickMeasurementAttributionReportURLForTesting):
+        (WTR::TestController::setPrivateClickMeasurementConversionURLForTesting): Deleted.
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2021-02-18  Youenn Fablet  <you...@apple.com>
 
         Set ENABLE_VP9 to 1 on IOS

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (273087 => 273088)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-02-18 19:44:39 UTC (rev 273088)
@@ -2315,6 +2315,7 @@
 		63A61B8A1FAD204D00F06885 /* display-mode.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "display-mode.html"; sourceTree = "<group>"; };
 		63F668201F97C3AA0032EE51 /* ApplicationManifest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ApplicationManifest.mm; sourceTree = "<group>"; };
 		6B0A07F621FA9C2B00D57391 /* PrivateClickMeasurement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurement.cpp; sourceTree = "<group>"; };
+		6B25A75125DC8D4E0070744F /* EventAttribution.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EventAttribution.mm; sourceTree = "<group>"; };
 		6B306105218A372900F5A802 /* ClosingWebView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ClosingWebView.mm; sourceTree = "<group>"; };
 		6B4E861B2220A5520022F389 /* RegistrableDomain.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RegistrableDomain.cpp; sourceTree = "<group>"; };
 		6B9ABE112086952F00D75DE6 /* HTTPParsers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPParsers.cpp; sourceTree = "<group>"; };
@@ -3317,6 +3318,7 @@
 				F46128D6211E489C00D9FADB /* DragAndDropTests.mm */,
 				A15502281E05020B00A24C57 /* DuplicateCompletionHandlerCalls.mm */,
 				F44D06461F395C4D001A0E29 /* EditorStateTests.mm */,
+				6B25A75125DC8D4E0070744F /* EventAttribution.mm */,
 				CDA29B2820FD2A9900F15CED /* ExitFullscreenOnEnterPiP.mm */,
 				1D12BEBF245BEF85004C0B7A /* ExitPiPOnSuspendVideoElement.mm */,
 				2D8104CB1BEC13E70020DA46 /* FindInPage.mm */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp (273087 => 273088)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -46,11 +46,11 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(min6BitValue), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(min6BitValue, PrivateClickMeasurement::Priority(min6BitValue)));
 
-    auto attributionURL = attribution.reportURL();
+    auto attributionURL = attribution.attributionReportURL();
     
     ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/private-click-measurement/report-attribution/");
 
-    ASSERT_EQ(attribution.json()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":0,\"attributed_on_site\":\"example.com\",\"trigger_data\":0,\"version\":1}");
+    ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":0,\"attributed_on_site\":\"example.com\",\"trigger_data\":0,\"version\":1}");
 }
 
 TEST(PrivateClickMeasurement, ValidMidValues)
@@ -58,11 +58,11 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID((uint32_t)192), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData((uint32_t)9, PrivateClickMeasurement::Priority((uint32_t)22)));
 
-    auto attributionURL = attribution.reportURL();
+    auto attributionURL = attribution.attributionReportURL();
     
     ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/private-click-measurement/report-attribution/");
 
-    ASSERT_EQ(attribution.json()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":192,\"attributed_on_site\":\"example.com\",\"trigger_data\":9,\"version\":1}");
+    ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":192,\"attributed_on_site\":\"example.com\",\"trigger_data\":9,\"version\":1}");
 }
 
 TEST(PrivateClickMeasurement, ValidMaxValues)
@@ -70,11 +70,11 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)));
 
-    auto attributionURL = attribution.reportURL();
+    auto attributionURL = attribution.attributionReportURL();
     
     ASSERT_EQ(attributionURL.string(), "https://webkit.org/.well-known/private-click-measurement/report-attribution/");
 
-    ASSERT_EQ(attribution.json()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":255,\"attributed_on_site\":\"example.com\",\"trigger_data\":15,\"version\":1}");
+    ASSERT_EQ(attribution.attributionReportJSON()->toJSONString(), "{\"source_engagement_type\":\"click\",\"source_site\":\"webkit.org\",\"source_id\":255,\"attributed_on_site\":\"example.com\",\"trigger_data\":15,\"version\":1}");
 }
 
 TEST(PrivateClickMeasurement, EarliestTimeToSendAttributionMinimumDelay)
@@ -136,7 +136,7 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy + 1), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)));
 
-    ASSERT_TRUE(attribution.reportURL().isEmpty());
+    ASSERT_TRUE(attribution.attributionReportURL().isEmpty());
 }
 
 TEST(PrivateClickMeasurement, InvalidSourceHost)
@@ -144,7 +144,7 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy), PrivateClickMeasurement::SourceSite { emptyURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)));
 
-    ASSERT_TRUE(attribution.reportURL().isEmpty());
+    ASSERT_TRUE(attribution.attributionReportURL().isEmpty());
 }
 
 TEST(PrivateClickMeasurement, InvalidDestinationHost)
@@ -152,7 +152,7 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy + 1), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { emptyURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)));
 
-    ASSERT_TRUE(attribution.reportURL().isEmpty());
+    ASSERT_TRUE(attribution.attributionReportURL().isEmpty());
 }
 
 TEST(PrivateClickMeasurement, AttributionTriggerData)
@@ -160,7 +160,7 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData((PrivateClickMeasurement::AttributionTriggerData::MaxEntropy + 1), PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy)));
 
-    ASSERT_TRUE(attribution.reportURL().isEmpty());
+    ASSERT_TRUE(attribution.attributionReportURL().isEmpty());
 }
 
 TEST(PrivateClickMeasurement, InvalidPriority)
@@ -168,7 +168,7 @@
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
     attribution.attributeAndGetEarliestTimeToSend(PrivateClickMeasurement::AttributionTriggerData(PrivateClickMeasurement::AttributionTriggerData::MaxEntropy, PrivateClickMeasurement::Priority(PrivateClickMeasurement::Priority::MaxEntropy + 1)));
 
-    ASSERT_TRUE(attribution.reportURL().isEmpty());
+    ASSERT_TRUE(attribution.attributionReportURL().isEmpty());
 }
 
 TEST(PrivateClickMeasurement, InvalidMissingConversion)
@@ -175,7 +175,7 @@
 {
     PrivateClickMeasurement attribution { PrivateClickMeasurement::SourceID(PrivateClickMeasurement::SourceID::MaxEntropy), PrivateClickMeasurement::SourceSite { webKitURL }, PrivateClickMeasurement::AttributeOnSite { exampleURL } };
 
-    ASSERT_TRUE(attribution.reportURL().isEmpty());
+    ASSERT_TRUE(attribution.attributionReportURL().isEmpty());
     ASSERT_FALSE(attribution.earliestTimeToSend());
 }
 

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm (273087 => 273088)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm	2021-02-18 19:44:39 UTC (rev 273088)
@@ -106,7 +106,7 @@
     webView.get()._uiEventAttribution = (UIEventAttribution *)attribution.get();
     [[webView configuration].websiteDataStore _setResourceLoadStatisticsEnabled:YES];
     [[webView configuration].websiteDataStore _allowTLSCertificateChain:@[(id)testCertificate().get()] forHost:serverURL.host];
-    [webView _setPrivateClickMeasurementConversionURLForTesting:serverURL completionHandler:^{
+    [webView _setPrivateClickMeasurementAttributionReportURLForTesting:serverURL completionHandler:^{
         [webView _setPrivateClickMeasurementOverrideTimerForTesting:YES completionHandler:^{
             NSString *html = [NSString stringWithFormat:@"<script>fetch('%@conversionRequestBeforeRedirect',{mode:'no-cors'})</script>", serverURL];
             [webView loadHTMLString:html baseURL:exampleURL];

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (273087 => 273088)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl	2021-02-18 19:44:39 UTC (rev 273088)
@@ -403,7 +403,8 @@
     undefined setPrivateClickMeasurementOverrideTimerForTesting(boolean value);
     undefined markAttributedPrivateClickMeasurementsAsExpiredForTesting();
     undefined simulateResourceLoadStatisticsSessionRestart();
-    undefined setPrivateClickMeasurementConversionURLForTesting(DOMString url);
+    undefined setPrivateClickMeasurementTokenSignatureURLForTesting(DOMString url);
+    undefined setPrivateClickMeasurementAttributionReportURLForTesting(DOMString url);
     undefined markPrivateClickMeasurementsAsExpiredForTesting();
 
     // SpeechRecognition

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (273087 => 273088)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -2025,12 +2025,18 @@
     postSynchronousPageMessage("SimulateResourceLoadStatisticsSessionRestart");
 }
 
-void TestRunner::setPrivateClickMeasurementConversionURLForTesting(JSStringRef urlString)
+void TestRunner::setPrivateClickMeasurementTokenSignatureURLForTesting(JSStringRef urlString)
 {
-    postSynchronousPageMessage("SetPrivateClickMeasurementConversionURLForTesting",
+    postSynchronousPageMessage("SetPrivateClickMeasurementTokenSignatureURLForTesting",
         adoptWK(WKURLCreateWithUTF8CString(toWTFString(urlString).utf8().data())));
 }
 
+void TestRunner::setPrivateClickMeasurementAttributionReportURLForTesting(JSStringRef urlString)
+{
+    postSynchronousPageMessage("SetPrivateClickMeasurementAttributionReportURLForTesting",
+        adoptWK(WKURLCreateWithUTF8CString(toWTFString(urlString).utf8().data())));
+}
+
 void TestRunner::markPrivateClickMeasurementsAsExpiredForTesting()
 {
     postSynchronousPageMessage("MarkPrivateClickMeasurementsAsExpiredForTesting");

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (273087 => 273088)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -512,7 +512,8 @@
     void clearPrivateClickMeasurement();
     void clearPrivateClickMeasurementsThroughWebsiteDataRemoval();
     void setPrivateClickMeasurementOverrideTimerForTesting(bool value);
-    void setPrivateClickMeasurementConversionURLForTesting(JSStringRef);
+    void setPrivateClickMeasurementTokenSignatureURLForTesting(JSStringRef);
+    void setPrivateClickMeasurementAttributionReportURLForTesting(JSStringRef);
     void markPrivateClickMeasurementsAsExpiredForTesting();
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting();
     void simulateResourceLoadStatisticsSessionRestart();

Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (273087 => 273088)


--- trunk/Tools/WebKitTestRunner/TestController.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -3630,13 +3630,20 @@
     runUntil(callbackContext.done, noTimeout);
 }
 
-void TestController::setPrivateClickMeasurementConversionURLForTesting(WKURLRef url)
+void TestController::setPrivateClickMeasurementTokenSignatureURLForTesting(WKURLRef url)
 {
     PrivateClickMeasurementVoidCallbackContext callbackContext(*this);
-    WKPageSetPrivateClickMeasurementConversionURLForTesting(m_mainWebView->page(), url, privateClickMeasurementVoidCallback, &callbackContext);
+    WKPageSetPrivateClickMeasurementTokenSignatureURLForTesting(m_mainWebView->page(), url, privateClickMeasurementVoidCallback, &callbackContext);
     runUntil(callbackContext.done, noTimeout);
 }
 
+void TestController::setPrivateClickMeasurementAttributionReportURLForTesting(WKURLRef url)
+{
+    PrivateClickMeasurementVoidCallbackContext callbackContext(*this);
+    WKPageSetPrivateClickMeasurementAttributionReportURLForTesting(m_mainWebView->page(), url, privateClickMeasurementVoidCallback, &callbackContext);
+    runUntil(callbackContext.done, noTimeout);
+}
+
 void TestController::markPrivateClickMeasurementsAsExpiredForTesting()
 {
     PrivateClickMeasurementVoidCallbackContext callbackContext(*this);

Modified: trunk/Tools/WebKitTestRunner/TestController.h (273087 => 273088)


--- trunk/Tools/WebKitTestRunner/TestController.h	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/WebKitTestRunner/TestController.h	2021-02-18 19:44:39 UTC (rev 273088)
@@ -346,7 +346,8 @@
     void setPrivateClickMeasurementOverrideTimerForTesting(bool value);
     void markAttributedPrivateClickMeasurementsAsExpiredForTesting();
     void simulateResourceLoadStatisticsSessionRestart();
-    void setPrivateClickMeasurementConversionURLForTesting(WKURLRef);
+    void setPrivateClickMeasurementTokenSignatureURLForTesting(WKURLRef);
+    void setPrivateClickMeasurementAttributionReportURLForTesting(WKURLRef);
     void markPrivateClickMeasurementsAsExpiredForTesting();
 
     void didSetAppBoundDomains() const;

Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (273087 => 273088)


--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2021-02-18 19:40:50 UTC (rev 273087)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp	2021-02-18 19:44:39 UTC (rev 273088)
@@ -1338,13 +1338,19 @@
         TestController::singleton().simulateResourceLoadStatisticsSessionRestart();
         return nullptr;
     }
-    
-    if (WKStringIsEqualToUTF8CString(messageName, "SetPrivateClickMeasurementConversionURLForTesting")) {
+
+    if (WKStringIsEqualToUTF8CString(messageName, "SetPrivateClickMeasurementTokenSignatureURLForTesting")) {
         ASSERT(WKGetTypeID(messageBody) == WKURLGetTypeID());
-        TestController::singleton().setPrivateClickMeasurementConversionURLForTesting(static_cast<WKURLRef>(messageBody));
+        TestController::singleton().setPrivateClickMeasurementTokenSignatureURLForTesting(static_cast<WKURLRef>(messageBody));
         return nullptr;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "SetPrivateClickMeasurementAttributionReportURLForTesting")) {
+        ASSERT(WKGetTypeID(messageBody) == WKURLGetTypeID());
+        TestController::singleton().setPrivateClickMeasurementAttributionReportURLForTesting(static_cast<WKURLRef>(messageBody));
+        return nullptr;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "MarkPrivateClickMeasurementsAsExpiredForTesting")) {
         TestController::singleton().markPrivateClickMeasurementsAsExpiredForTesting();
         return nullptr;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to