Title: [236842] trunk
Revision
236842
Author
[email protected]
Date
2018-10-04 12:32:14 -0700 (Thu, 04 Oct 2018)

Log Message

[WebAuthN] Move time out control from WebProcess to UIProcess
https://bugs.webkit.org/show_bug.cgi?id=189642
<rdar://problem/44476765>

Reviewed by Chris Dumez.

Source/WebCore:

Since now the control unit of WebAuthN has been moved to UI Process, i.e. AuthenticatorManager,
the time out timer should move to UI Process as well.

Tests: http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html
       http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html

* Modules/webauthn/AuthenticatorCoordinator.cpp:
(WebCore::AuthenticatorCoordinator::create const):
(WebCore::AuthenticatorCoordinator::discoverFromExternalSource const):
(WebCore::AuthenticatorCoordinatorInternal::initTimeoutTimer): Deleted.
(WebCore::AuthenticatorCoordinatorInternal::didTimeoutTimerFire): Deleted.
* Modules/webauthn/PublicKeyCredentialCreationOptions.h:
(WebCore::PublicKeyCredentialCreationOptions::encode const):
(WebCore::PublicKeyCredentialCreationOptions::decode):
* Modules/webauthn/PublicKeyCredentialRequestOptions.h:
(WebCore::PublicKeyCredentialRequestOptions::encode const):
(WebCore::PublicKeyCredentialRequestOptions::decode):

Source/WebKit:

Besides adding a time out timer in the AuthenticatorManager, this patch also adds a new
option in MockWebAuthenticationConfiguration to turn on silent failure which is the
default policy of treating authenticators' error as suggested by spec.

* UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreSetWebAuthenticationMockConfiguration):
* UIProcess/WebAuthentication/AuthenticatorManager.cpp:
(WebKit::AuthenticatorManagerInternal::collectTransports):
(WebKit::AuthenticatorManager::makeCredential):
(WebKit::AuthenticatorManager::getAssertion):
(WebKit::AuthenticatorManager::respondReceived):
(WebKit::AuthenticatorManager::initTimeOutTimer):
* UIProcess/WebAuthentication/AuthenticatorManager.h:
(WebKit::AuthenticatorManager::requestTimeOutTimer):
* UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp:
(WebKit::MockAuthenticatorManager::respondReceivedInternal):
* UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h:

Tools:

* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setWebAuthenticationMockConfiguration):

LayoutTests:

This patch also fixes some flaky behaviours regarding to the dirty ASN.1 decoder.

* http/wpt/webauthn/public-key-credential-create-failure-local-silent.https-expected.txt: Added.
* http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html: Copied from LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html.
* http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt:
* http/wpt/webauthn/public-key-credential-create-failure-local.https.html:
* http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt:
* http/wpt/webauthn/public-key-credential-create-failure.https.html:
* http/wpt/webauthn/public-key-credential-get-failure-local-silent.https-expected.txt: Added.
* http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html: Copied from LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html.
* http/wpt/webauthn/public-key-credential-get-failure-local.https-expected.txt:
* http/wpt/webauthn/public-key-credential-get-failure-local.https.html:
* http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt:
* http/wpt/webauthn/public-key-credential-get-failure.https.html:
* http/wpt/webauthn/resources/util.js:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (236841 => 236842)


--- trunk/LayoutTests/ChangeLog	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/ChangeLog	2018-10-04 19:32:14 UTC (rev 236842)
@@ -1,3 +1,27 @@
+2018-10-04  Jiewen Tan  <[email protected]>
+
+        [WebAuthN] Move time out control from WebProcess to UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=189642
+        <rdar://problem/44476765>
+
+        Reviewed by Chris Dumez.
+
+        This patch also fixes some flaky behaviours regarding to the dirty ASN.1 decoder.
+
+        * http/wpt/webauthn/public-key-credential-create-failure-local-silent.https-expected.txt: Added.
+        * http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html: Copied from LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html.
+        * http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt:
+        * http/wpt/webauthn/public-key-credential-create-failure-local.https.html:
+        * http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt:
+        * http/wpt/webauthn/public-key-credential-create-failure.https.html:
+        * http/wpt/webauthn/public-key-credential-get-failure-local-silent.https-expected.txt: Added.
+        * http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html: Copied from LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html.
+        * http/wpt/webauthn/public-key-credential-get-failure-local.https-expected.txt:
+        * http/wpt/webauthn/public-key-credential-get-failure-local.https.html:
+        * http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt:
+        * http/wpt/webauthn/public-key-credential-get-failure.https.html:
+        * http/wpt/webauthn/resources/util.js:
+
 2018-10-04  Chris Dumez  <[email protected]>
 
         Regression(r236779): Crash when changing the input element type from inside an 'input' event listener

Added: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https-expected.txt (0 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https-expected.txt	2018-10-04 19:32:14 UTC (rev 236842)
@@ -0,0 +1,8 @@
+
+PASS PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 
+PASS PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 2 
+PASS PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 3 
+PASS PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 4 
+PASS PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 5 
+PASS PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 6 
+

Copied: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html (from rev 236841, trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html) (0 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html	2018-10-04 19:32:14 UTC (rev 236842)
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<title>Web Authentication API: PublicKeyCredential's [[create]] silent failure cases with a mock local authenticator.</title>
+<script src=""
+<script src=""
+<script src=""
+<script>
+    // Default mock configuration. Tests need to override if they need different configuration.
+    if (window.testRunner)
+        testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false } });
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: Base64URL.parse(testUserhandleBase64),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -35 }, { type: "public-key", alg: -257 }], // ES384, RS256
+                timeout: 10
+            }
+        };
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator.");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: Base64URL.parse(testUserhandleBase64),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+                excludeCredentials: [{ type: "public-key", id: Base64URL.parse(testCredentialIdBase64) }],
+                timeout: 10
+            }
+        };
+        if (window.testRunner)
+            testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => {
+            if (window.testRunner)
+                testRunner.cleanUpKeychain(testRpId);
+        });
+    }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 2");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: Base64URL.parse(testUserhandleBase64),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+                excludeCredentials: [
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] }
+                ],
+                timeout: 10
+            }
+        };
+        if (window.testRunner)
+            testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => {
+            if (window.testRunner)
+                testRunner.cleanUpKeychain(testRpId);
+        });
+    }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 3");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: Base64URL.parse(testUserhandleBase64),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+                timeout: 10
+            }
+        };
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 4");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: Base64URL.parse(testUserhandleBase64),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+                timeout: 10
+            }
+        };
+        if (window.testRunner)
+            testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: true, acceptAttestation: false } });
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 5");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: Base64URL.parse(testUserhandleBase64),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+                timeout: 10
+            }
+        };
+        if (window.testRunner) {
+            testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: true, acceptAttestation: false } });
+            testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);
+        }
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.").then(() => {
+            if (window.testRunner)
+                assert_false(testRunner.keyExistsInKeychain(testRpId, testUserhandleBase64));
+        });
+    }, "PublicKeyCredential's [[create]] with silent failure in a mock local authenticator. 6");
+</script>

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https-expected.txt	2018-10-04 19:32:14 UTC (rev 236842)
@@ -5,4 +5,5 @@
 PASS PublicKeyCredential's [[create]] without user consent in a mock local authenticator. 
 PASS PublicKeyCredential's [[create]] without attestation in a mock local authenticator. 
 PASS PublicKeyCredential's [[create]] deleting old credential in a mock local authenticator. 
+PASS PublicKeyCredential's [[create]] with timeout in a mock local authenticator. 
 

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html	2018-10-04 19:32:14 UTC (rev 236842)
@@ -141,4 +141,27 @@
                 assert_false(testRunner.keyExistsInKeychain(testRpId, testUserhandleBase64));
         });
     }, "PublicKeyCredential's [[create]] deleting old credential in a mock local authenticator.");
+
+    promise_test(function(t) {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: asciiToUint8Array("123456"),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+                timeout: 10,
+                authenticatorSelection: { authenticatorAttachment: "cross-platform" }
+            }
+        };
+
+        if (window.testRunner)
+            testRunner.setWebAuthenticationMockConfiguration({ local: { acceptAuthentication: false, acceptAttestation: false } });
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[create]] with timeout in a mock local authenticator.");
 </script>

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https-expected.txt	2018-10-04 19:32:14 UTC (rev 236842)
@@ -1,4 +1,5 @@
 
+PASS PublicKeyCredential's [[create]] with timeout 
 PASS PublicKeyCredential's [[create]] with a mismatched RP ID 
 PASS PublicKeyCredential's [[create]] with an empty pubKeyCredParams 
 

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure.https.html	2018-10-04 19:32:14 UTC (rev 236842)
@@ -8,28 +8,27 @@
     if (window.testRunner)
         testRunner.setWebAuthenticationMockConfiguration({ });
 
-    // FIXME(189642): Re-enable the following test.
-    // promise_test(function(t) {
-    //     const options = {
-    //         publicKey: {
-    //             rp: {
-    //                 name: "example.com"
-    //             },
-    //             user: {
-    //                 name: "John Appleseed",
-    //                 id: asciiToUint8Array("123456"),
-    //                 displayName: "John",
-    //             },
-    //             challenge: asciiToUint8Array("123456"),
-    //             pubKeyCredParams: [{ type: "public-key", alg: -7 }],
-    //             timeout: 0,
-    //         }
-    //     };
-    //
-    //     return promiseRejects(t, "NotAllowedError",
-    //         navigator.credentials.create(options), "Operation timed out.");
-    // }, "PublicKeyCredential's [[create]] with timeout");
+    promise_test(function(t) {
+        const options = {
+            publicKey: {
+                rp: {
+                    name: "example.com"
+                },
+                user: {
+                    name: "John Appleseed",
+                    id: asciiToUint8Array("123456"),
+                    displayName: "John",
+                },
+                challenge: asciiToUint8Array("123456"),
+                pubKeyCredParams: [{ type: "public-key", alg: -7 }],
+                timeout: 10,
+            }
+        };
 
+        return promiseRejects(t, "NotAllowedError",
+            navigator.credentials.create(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[create]] with timeout");
+
     promise_test(function(t) {
         const options = {
             publicKey: {

Added: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https-expected.txt (0 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https-expected.txt	2018-10-04 19:32:14 UTC (rev 236842)
@@ -0,0 +1,5 @@
+
+PASS PublicKeyCredential's [[get]] with silent failure in a mock local authenticator. 
+PASS PublicKeyCredential's [[get]] with silent failure in a mock local authenticator. 2 
+PASS PublicKeyCredential's [[get]] with silent failure in a mock local authenticator. 3 
+

Copied: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html (from rev 236841, trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html) (0 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html	2018-10-04 19:32:14 UTC (rev 236842)
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<title>Web Authentication API: PublicKeyCredential's [[get]] failure cases.</title>
+<script src=""
+<script src=""
+<script src=""
+<script>
+    // Default mock configuration. Tests need to override if they need different configuration.
+    if (window.testRunner)
+        testRunner.setWebAuthenticationMockConfiguration({ silentFailure: true, local: { acceptAuthentication: false, acceptAttestation: false } });
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                challenge: asciiToUint8Array("123456"),
+                allowCredentials: [
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["internal"] }
+                ],
+                timeout: 10
+            }
+        };
+
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[get]] with silent failure in a mock local authenticator.");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                challenge: asciiToUint8Array("123456"),
+                allowCredentials: [
+                    { type: "public-key", id: Base64URL.parse(testUserhandleBase64) }
+                ],
+                timeout: 10
+            }
+        };
+
+        if (window.testRunner)
+            testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out.").then(() => {
+                if (window.testRunner)
+                    testRunner.cleanUpKeychain(testRpId);
+            });
+    }, "PublicKeyCredential's [[get]] with silent failure in a mock local authenticator. 2");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                challenge: asciiToUint8Array("123456"),
+                timeout: 10
+            }
+        };
+
+        if (window.testRunner)
+            testRunner.addTestKeyToKeychain(testES256PrivateKeyBase64, testRpId, testUserhandleBase64);
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out.").then(() => {
+            if (window.testRunner)
+                testRunner.cleanUpKeychain(testRpId);
+        });
+    }, "PublicKeyCredential's [[get]] with silent failure in a mock local authenticator. 3");
+</script>

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https-expected.txt (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https-expected.txt	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https-expected.txt	2018-10-04 19:32:14 UTC (rev 236842)
@@ -2,4 +2,5 @@
 PASS PublicKeyCredential's [[get]] with no matched credentials in a mock local authenticator. 
 PASS PublicKeyCredential's [[get]] with no matched credentials in a mock local authenticator. 2nd 
 PASS PublicKeyCredential's [[get]] without user consent in a mock local authenticator. 
+PASS PublicKeyCredential's [[get]] with timeout in a mock local authenticator. 
 

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html	2018-10-04 19:32:14 UTC (rev 236842)
@@ -56,4 +56,20 @@
                 testRunner.cleanUpKeychain(testRpId);
         });
     }, "PublicKeyCredential's [[get]] without user consent in a mock local authenticator.");
+
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                challenge: asciiToUint8Array("123456"),
+                allowCredentials: [
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["usb"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["nfc"] },
+                    { type: "public-key", id: Base64URL.parse(testCredentialIdBase64), transports: ["ble"] }
+                ],
+                timeout: 10
+            }
+        };
+
+        return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[get]] with timeout in a mock local authenticator.");
 </script>

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https-expected.txt	2018-10-04 19:32:14 UTC (rev 236842)
@@ -1,3 +1,4 @@
 
+PASS PublicKeyCredential's [[get]] with timeout 
 PASS PublicKeyCredential's [[get]] with a mismatched RP ID 
 

Modified: trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https.html (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https.html	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure.https.html	2018-10-04 19:32:14 UTC (rev 236842)
@@ -8,26 +8,26 @@
     if (window.testRunner)
         testRunner.setWebAuthenticationMockConfiguration({ });
 
-    // FIXME(189642): Re-enable the following test.
-    // promise_test(function(t) {
-    //     const options = {
-    //         publicKey: {
-    //             challenge: asciiToUint8Array("123456"),
-    //             timeout: 0,
-    //         }
-    //     };
-    //
-    //     return promiseRejects(t, "NotAllowedError",
-    //         navigator.credentials.get(options), "Operation timed out.");
-    // }, "PublicKeyCredential's [[get]] with timeout");
+    promise_test(t => {
+        const options = {
+            publicKey: {
+                challenge: asciiToUint8Array("123456"),
+                timeout: 10
+            }
+        };
 
-    promise_test(function(t) {
+        return promiseRejects(t, "NotAllowedError",
+            navigator.credentials.get(options), "Operation timed out.");
+    }, "PublicKeyCredential's [[get]] with timeout");
+
+    promise_test(t => {
         const options = {
             publicKey: {
                 rpId: "example.com",
-                challenge: asciiToUint8Array("123456"),
+                challenge: asciiToUint8Array("123456")
             }
         };
+
         return promiseRejects(t, "SecurityError",
             navigator.credentials.get(options), "The origin of the document is not a registrable domain suffix of the provided RP ID.");
     }, "PublicKeyCredential's [[get]] with a mismatched RP ID");

Modified: trunk/LayoutTests/http/wpt/webauthn/resources/util.js (236841 => 236842)


--- trunk/LayoutTests/http/wpt/webauthn/resources/util.js	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/LayoutTests/http/wpt/webauthn/resources/util.js	2018-10-04 19:32:14 UTC (rev 236842)
@@ -172,10 +172,19 @@
 {
     const signature = new Uint8Array(asn1signature);
     let tmp = new Uint8Array(64);
+
     const rStart =  signature[3] - 32;
-    tmp.set(new Uint8Array(signature.slice(4 + rStart, 36 + rStart)), 0);
+    if (rStart >= 0)
+        tmp.set(new Uint8Array(signature.slice(4 + rStart, 36 + rStart)), 0);
+    else
+        tmp.set(new Uint8Array(signature.slice(4, 36 + rStart)), -rStart);
+
     const sStart =  signature[37 + rStart] - 32;
-    tmp.set(new Uint8Array(signature.slice(38 + rStart + sStart)), 32);
+    if (sStart >= 0)
+        tmp.set(new Uint8Array(signature.slice(38 + rStart + sStart)), 32);
+    else
+        tmp.set(new Uint8Array(signature.slice(38 + rStart)), 32 - sStart);
+
     return tmp.buffer;
 }
 

Modified: trunk/Source/WebCore/ChangeLog (236841 => 236842)


--- trunk/Source/WebCore/ChangeLog	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebCore/ChangeLog	2018-10-04 19:32:14 UTC (rev 236842)
@@ -1,3 +1,29 @@
+2018-10-04  Jiewen Tan  <[email protected]>
+
+        [WebAuthN] Move time out control from WebProcess to UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=189642
+        <rdar://problem/44476765>
+
+        Reviewed by Chris Dumez.
+
+        Since now the control unit of WebAuthN has been moved to UI Process, i.e. AuthenticatorManager,
+        the time out timer should move to UI Process as well.
+
+        Tests: http/wpt/webauthn/public-key-credential-create-failure-local-silent.https.html
+               http/wpt/webauthn/public-key-credential-get-failure-local-silent.https.html
+
+        * Modules/webauthn/AuthenticatorCoordinator.cpp:
+        (WebCore::AuthenticatorCoordinator::create const):
+        (WebCore::AuthenticatorCoordinator::discoverFromExternalSource const):
+        (WebCore::AuthenticatorCoordinatorInternal::initTimeoutTimer): Deleted.
+        (WebCore::AuthenticatorCoordinatorInternal::didTimeoutTimerFire): Deleted.
+        * Modules/webauthn/PublicKeyCredentialCreationOptions.h:
+        (WebCore::PublicKeyCredentialCreationOptions::encode const):
+        (WebCore::PublicKeyCredentialCreationOptions::decode):
+        * Modules/webauthn/PublicKeyCredentialRequestOptions.h:
+        (WebCore::PublicKeyCredentialRequestOptions::encode const):
+        (WebCore::PublicKeyCredentialRequestOptions::decode):
+
 2018-10-04  Chris Dumez  <[email protected]>
 
         Regression(r236779): Crash when changing the input element type from inside an 'input' event listener

Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp (236841 => 236842)


--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp	2018-10-04 19:32:14 UTC (rev 236842)
@@ -38,7 +38,6 @@
 #include "PublicKeyCredentialData.h"
 #include "PublicKeyCredentialRequestOptions.h"
 #include "SecurityOrigin.h"
-#include "Timer.h"
 #include <pal/crypto/CryptoDigest.h>
 #include <wtf/JSONValues.h>
 #include <wtf/NeverDestroyed.h>
@@ -82,29 +81,6 @@
     return crypto->computeHash();
 }
 
-// FIXME(181947): We should probably trim timeOutInMs to some max allowable number.
-static std::unique_ptr<Timer> initTimeoutTimer(std::optional<unsigned long> timeOutInMs, const CredentialPromise& promise)
-{
-    if (!timeOutInMs)
-        return nullptr;
-
-    auto timer = std::make_unique<Timer>([promise = promise] () mutable {
-        promise.reject(Exception { NotAllowedError, "Operation timed out."_s });
-    });
-    timer->startOneShot(Seconds::fromMilliseconds(*timeOutInMs));
-    return timer;
-}
-
-static bool didTimeoutTimerFire(Timer* timer)
-{
-    if (!timer)
-        return false;
-    if (!timer->isActive())
-        return true;
-    timer->stop();
-    return false;
-}
-
 } // namespace AuthenticatorCoordinatorInternal
 
 AuthenticatorCoordinator::AuthenticatorCoordinator(std::unique_ptr<AuthenticatorCoordinatorClient>&& client)
@@ -130,9 +106,6 @@
         return;
     }
 
-    // Step 4 & 17.
-    std::unique_ptr<Timer> timeoutTimer = initTimeoutTimer(options.timeout, promise);
-
     // Step 5-7.
     // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
     // Step 6 is therefore skipped. Also, we lack the support to determine whether a domain is a registrable
@@ -156,7 +129,7 @@
     auto clientDataJson = produceClientDataJson(ClientDataType::Create, options.challenge, callerOrigin);
     auto clientDataJsonHash = produceClientDataJsonHash(clientDataJson);
 
-    // Step 18-21.
+    // Step 4, 17-21.
     // Only platform attachments will be supported at this stage. Assuming one authenticator per device.
     // Also, resident keys, user verifications and direct attestation are enforced at this tage.
     // For better performance, transports of options.excludeCredentials are checked in LocalAuthenticator.
@@ -165,9 +138,7 @@
         return;
     }
 
-    auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), timeoutTimer = WTFMove(timeoutTimer), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable {
-        if (didTimeoutTimerFire(timeoutTimer.get()))
-            return;
+    auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable {
         if (abortSignal && abortSignal->aborted()) {
             promise.reject(Exception { AbortError, "Aborted by AbortSignal."_s });
             return;
@@ -198,9 +169,6 @@
         return;
     }
 
-    // Step 4 & 16.
-    std::unique_ptr<Timer> timeoutTimer = initTimeoutTimer(options.timeout, promise);
-
     // Step 5-7.
     // FIXME(181950): We lack fundamental support from SecurityOrigin to determine if a host is a valid domain or not.
     // Step 6 is therefore skipped. Also, we lack the support to determine whether a domain is a registrable
@@ -216,7 +184,7 @@
     auto clientDataJson = produceClientDataJson(ClientDataType::Get, options.challenge, callerOrigin);
     auto clientDataJsonHash = produceClientDataJsonHash(clientDataJson);
 
-    // Step 14-15, 17-19.
+    // Step 4, 14-19.
     // Only platform attachments will be supported at this stage. Assuming one authenticator per device.
     // Also, resident keys, user verifications and direct attestation are enforced at this tage.
     // For better performance, filtering of options.allowCredentials is done in LocalAuthenticator.
@@ -225,9 +193,7 @@
         return;
     }
 
-    auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), timeoutTimer = WTFMove(timeoutTimer), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable {
-        if (didTimeoutTimerFire(timeoutTimer.get()))
-            return;
+    auto completionHandler = [clientDataJson = WTFMove(clientDataJson), promise = WTFMove(promise), abortSignal = WTFMove(abortSignal)] (const WebCore::PublicKeyCredentialData& data, const WebCore::ExceptionData& exception) mutable {
         if (abortSignal && abortSignal->aborted()) {
             promise.reject(Exception { AbortError, "Aborted by AbortSignal."_s });
             return;

Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h (236841 => 236842)


--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialCreationOptions.h	2018-10-04 19:32:14 UTC (rev 236842)
@@ -78,7 +78,7 @@
     BufferSource challenge;
     Vector<Parameters> pubKeyCredParams;
 
-    std::optional<unsigned long> timeout;
+    std::optional<unsigned> timeout;
     Vector<PublicKeyCredentialDescriptor> excludeCredentials;
     std::optional<AuthenticatorSelectionCriteria> authenticatorSelection;
 
@@ -125,7 +125,7 @@
     encoder << rp.id << rp.name << rp.icon;
     encoder << static_cast<uint64_t>(user.id.length());
     encoder.encodeFixedLengthData(user.id.data(), user.id.length(), 1);
-    encoder << user.displayName << user.name << user.icon << pubKeyCredParams << excludeCredentials << authenticatorSelection;
+    encoder << user.displayName << user.name << user.icon << pubKeyCredParams << timeout << excludeCredentials << authenticatorSelection;
 }
 
 template<class Decoder>
@@ -148,6 +148,13 @@
         return std::nullopt;
     if (!decoder.decode(result.pubKeyCredParams))
         return std::nullopt;
+
+    std::optional<std::optional<unsigned>> timeout;
+    decoder >> timeout;
+    if (!timeout)
+        return std::nullopt;
+    result.timeout = WTFMove(*timeout);
+
     if (!decoder.decode(result.excludeCredentials))
         return std::nullopt;
 
@@ -155,7 +162,7 @@
     decoder >> authenticatorSelection;
     if (!authenticatorSelection)
         return std::nullopt;
-    result.authenticatorSelection = WTFMove(authenticatorSelection.value());
+    result.authenticatorSelection = WTFMove(*authenticatorSelection);
 
     return result;
 }

Modified: trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialRequestOptions.h (236841 => 236842)


--- trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialRequestOptions.h	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebCore/Modules/webauthn/PublicKeyCredentialRequestOptions.h	2018-10-04 19:32:14 UTC (rev 236842)
@@ -35,7 +35,7 @@
 
 struct PublicKeyCredentialRequestOptions {
     BufferSource challenge;
-    std::optional<unsigned long> timeout;
+    std::optional<unsigned> timeout;
     mutable String rpId;
     Vector<PublicKeyCredentialDescriptor> allowCredentials;
 
@@ -47,7 +47,7 @@
 template<class Encoder>
 void PublicKeyCredentialRequestOptions::encode(Encoder& encoder) const
 {
-    encoder << rpId << allowCredentials;
+    encoder << timeout << rpId << allowCredentials;
 }
 
 template<class Decoder>
@@ -54,6 +54,13 @@
 std::optional<PublicKeyCredentialRequestOptions> PublicKeyCredentialRequestOptions::decode(Decoder& decoder)
 {
     PublicKeyCredentialRequestOptions result;
+
+    std::optional<std::optional<unsigned>> timeout;
+    decoder >> timeout;
+    if (!timeout)
+        return std::nullopt;
+    result.timeout = WTFMove(*timeout);
+
     if (!decoder.decode(result.rpId))
         return std::nullopt;
     if (!decoder.decode(result.allowCredentials))

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (236841 => 236842)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-10-04 19:32:14 UTC (rev 236842)
@@ -18819,13 +18819,6 @@
 			path = cbor;
 			sourceTree = "<group>";
 		};
-		574F55DD204F3744002948C6 /* cocoa */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = cocoa;
-			sourceTree = "<group>";
-		};
 		57C7A6881E56946D00C67D71 /* credentialmanagement */ = {
 			isa = PBXGroup;
 			children = (
@@ -18867,7 +18860,6 @@
 			isa = PBXGroup;
 			children = (
 				57303BB32006C6ED00355965 /* cbor */,
-				574F55DD204F3744002948C6 /* cocoa */,
 				57303C272009B2FC00355965 /* AuthenticatorAssertionResponse.h */,
 				57303C292009B2FC00355965 /* AuthenticatorAssertionResponse.idl */,
 				57303C1B2009A98600355965 /* AuthenticatorAttestationResponse.h */,

Modified: trunk/Source/WebKit/ChangeLog (236841 => 236842)


--- trunk/Source/WebKit/ChangeLog	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebKit/ChangeLog	2018-10-04 19:32:14 UTC (rev 236842)
@@ -1,3 +1,29 @@
+2018-10-04  Jiewen Tan  <[email protected]>
+
+        [WebAuthN] Move time out control from WebProcess to UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=189642
+        <rdar://problem/44476765>
+
+        Reviewed by Chris Dumez.
+
+        Besides adding a time out timer in the AuthenticatorManager, this patch also adds a new
+        option in MockWebAuthenticationConfiguration to turn on silent failure which is the
+        default policy of treating authenticators' error as suggested by spec.
+
+        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+        (WKWebsiteDataStoreSetWebAuthenticationMockConfiguration):
+        * UIProcess/WebAuthentication/AuthenticatorManager.cpp:
+        (WebKit::AuthenticatorManagerInternal::collectTransports):
+        (WebKit::AuthenticatorManager::makeCredential):
+        (WebKit::AuthenticatorManager::getAssertion):
+        (WebKit::AuthenticatorManager::respondReceived):
+        (WebKit::AuthenticatorManager::initTimeOutTimer):
+        * UIProcess/WebAuthentication/AuthenticatorManager.h:
+        (WebKit::AuthenticatorManager::requestTimeOutTimer):
+        * UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp:
+        (WebKit::MockAuthenticatorManager::respondReceivedInternal):
+        * UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h:
+
 2018-10-04  Yuhan Wu  <[email protected]>
 
         runtime flag and IDL for MediaRecorder

Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp (236841 => 236842)


--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp	2018-10-04 19:32:14 UTC (rev 236842)
@@ -577,6 +577,10 @@
 #if ENABLE(WEB_AUTHN)
     MockWebAuthenticationConfiguration configuration;
 
+    auto silentFailureRef = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("SilentFailure")).get()));
+    if (silentFailureRef)
+        configuration.silentFailure = WKBooleanGetValue(silentFailureRef);
+
     auto localRef = static_cast<WKDictionaryRef>(WKDictionaryGetItemForKey(configurationRef, adoptWK(WKStringCreateWithUTF8CString("Local")).get()));
     if (localRef) {
         MockWebAuthenticationConfiguration::Local local;

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp (236841 => 236842)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp	2018-10-04 19:32:14 UTC (rev 236842)
@@ -38,6 +38,8 @@
 namespace AuthenticatorManagerInternal {
 
 const size_t maxTransportNumber = 1;
+// Suggested by WebAuthN spec as of 7 August 2018.
+const unsigned maxTimeOutValue = 120000;
 
 // FIXME(188623, 188624, 188625): Support USB, NFC and BLE authenticators.
 static AuthenticatorManager::TransportSet collectTransports(const std::optional<PublicKeyCredentialCreationOptions::AuthenticatorSelectionCriteria>& authenticatorSelection)
@@ -49,12 +51,12 @@
         return result;
     }
 
-    if (authenticatorSelection.value().authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::Platform) {
+    if (authenticatorSelection->authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::Platform) {
         auto addResult = result.add(AuthenticatorTransport::Internal);
         ASSERT_UNUSED(addResult, addResult.isNewEntry);
         return result;
     }
-    if (authenticatorSelection.value().authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::CrossPlatform)
+    if (authenticatorSelection->authenticatorAttachment == PublicKeyCredentialCreationOptions::AuthenticatorAttachment::CrossPlatform)
         return result;
 
     ASSERT_NOT_REACHED();
@@ -104,6 +106,7 @@
     // 1. Save request for async operations.
     m_pendingRequestData = { hash, true, options, { } };
     m_pendingCompletionHandler = WTFMove(callback);
+    initTimeOutTimer(options.timeout);
 
     // 2. Get available transports and start discovering authenticators on them.
     startDiscovery(collectTransports(options.authenticatorSelection));
@@ -121,6 +124,7 @@
     // 1. Save request for async operations.
     m_pendingRequestData = { hash, false, { }, options };
     m_pendingCompletionHandler = WTFMove(callback);
+    initTimeOutTimer(options.timeout);
 
     // 2. Get available transports and start discovering authenticators on them.
     ASSERT(m_services.isEmpty());
@@ -147,11 +151,15 @@
 void AuthenticatorManager::respondReceived(Respond&& respond)
 {
     ASSERT(RunLoop::isMain());
+    ASSERT(m_requestTimeOutTimer);
+    if (!m_requestTimeOutTimer->isActive())
+        return;
+
     ASSERT(m_pendingCompletionHandler);
-    // FIXME(189642)
     if (WTF::holds_alternative<PublicKeyCredentialData>(respond)) {
         m_pendingCompletionHandler(WTFMove(respond));
         clearState();
+        m_requestTimeOutTimer->stop();
         return;
     }
     respondReceivedInternal(WTFMove(respond));
@@ -178,6 +186,19 @@
     }
 }
 
+void AuthenticatorManager::initTimeOutTimer(const std::optional<unsigned>& timeOutInMs)
+{
+    using namespace AuthenticatorManagerInternal;
+
+    unsigned timeOutInMsValue = std::min(maxTimeOutValue, timeOutInMs.value_or(maxTimeOutValue));
+
+    m_requestTimeOutTimer = std::make_unique<Timer>([context = this]() mutable {
+        context->m_pendingCompletionHandler((ExceptionData { NotAllowedError, "Operation timed out."_s }));
+        context->clearState();
+    });
+    m_requestTimeOutTimer->startOneShot(Seconds::fromMilliseconds(timeOutInMsValue));
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(WEB_AUTHN)

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h (236841 => 236842)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h	2018-10-04 19:32:14 UTC (rev 236842)
@@ -32,6 +32,7 @@
 #include "WebAuthenticationRequestData.h"
 #include <WebCore/ExceptionData.h>
 #include <WebCore/PublicKeyCredentialData.h>
+#include <WebCore/Timer.h>
 #include <wtf/CompletionHandler.h>
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
@@ -57,6 +58,7 @@
 
 protected:
     Callback& pendingCompletionHandler() { return m_pendingCompletionHandler; }
+    WebCore::Timer* requestTimeOutTimer() { return m_requestTimeOutTimer.get(); }
     void clearState();
 
 private:
@@ -72,10 +74,12 @@
     virtual void respondReceivedInternal(Respond&&);
 
     void startDiscovery(const TransportSet&);
+    void initTimeOutTimer(const std::optional<unsigned>& timeOutInMs);
 
     // Request: We only allow one request per time.
     WebAuthenticationRequestData m_pendingRequestData;
     Callback m_pendingCompletionHandler;
+    std::unique_ptr<WebCore::Timer> m_requestTimeOutTimer;
 
     Vector<UniqueRef<AuthenticatorTransportService>> m_services;
     HashSet<Ref<Authenticator>> m_authenticators;

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp (236841 => 236842)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp	2018-10-04 19:32:14 UTC (rev 236842)
@@ -42,8 +42,12 @@
 
 void MockAuthenticatorManager::respondReceivedInternal(Respond&& respond)
 {
+    if (m_testConfiguration.silentFailure)
+        return;
+
     pendingCompletionHandler()(WTFMove(respond));
     clearState();
+    requestTimeOutTimer()->stop();
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h (236841 => 236842)


--- trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockWebAuthenticationConfiguration.h	2018-10-04 19:32:14 UTC (rev 236842)
@@ -38,6 +38,7 @@
         String intermediateCACertificateBase64;
     };
 
+    bool silentFailure { false };
     std::optional<Local> local;
 };
 

Modified: trunk/Tools/ChangeLog (236841 => 236842)


--- trunk/Tools/ChangeLog	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Tools/ChangeLog	2018-10-04 19:32:14 UTC (rev 236842)
@@ -1,3 +1,14 @@
+2018-10-04  Jiewen Tan  <[email protected]>
+
+        [WebAuthN] Move time out control from WebProcess to UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=189642
+        <rdar://problem/44476765>
+
+        Reviewed by Chris Dumez.
+
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setWebAuthenticationMockConfiguration):
+
 2018-10-04  YUHAN WU  <[email protected]>
 
         Runtime flag and IDL for MediaRecorder

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (236841 => 236842)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2018-10-04 19:31:15 UTC (rev 236841)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp	2018-10-04 19:32:14 UTC (rev 236842)
@@ -2355,9 +2355,19 @@
     Vector<WKRetainPtr<WKStringRef>> configurationKeys;
     Vector<WKRetainPtr<WKTypeRef>> configurationValues;
 
+    JSRetainPtr<JSStringRef> silentFailurePropertyName(Adopt, JSStringCreateWithUTF8CString("silentFailure"));
+    JSValueRef silentFailureValue = JSObjectGetProperty(context, configuration, silentFailurePropertyName.get(), 0);
+    if (!JSValueIsUndefined(context, silentFailureValue)) {
+        if (!JSValueIsBoolean(context, silentFailureValue))
+            return;
+        bool silentFailure = JSValueToBoolean(context, silentFailureValue);
+        configurationKeys.append({ AdoptWK, WKStringCreateWithUTF8CString("SilentFailure") });
+        configurationValues.append(adoptWK(WKBooleanCreate(silentFailure)).get());
+    }
+
     JSRetainPtr<JSStringRef> localPropertyName(Adopt, JSStringCreateWithUTF8CString("local"));
     JSValueRef localValue = JSObjectGetProperty(context, configuration, localPropertyName.get(), 0);
-    if (!JSValueIsNull(context, localValue)) {
+    if (!JSValueIsUndefined(context, localValue) && !JSValueIsNull(context, localValue)) {
         if (!JSValueIsObject(context, localValue))
             return;
         JSObjectRef local = JSValueToObject(context, localValue, 0);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to