Changeset 257877 in webkit
- Timestamp:
- Mar 4, 2020 1:42:39 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-create-failure-local.https.html
r257085 r257877 99 99 } 100 100 }; 101 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Couldn't get user consent.");101 return promiseRejects(t, "NotAllowedError", navigator.credentials.create(options), "Couldn't verify user."); 102 102 }, "PublicKeyCredential's [[create]] without user consent in a mock local authenticator."); 103 103 -
trunk/LayoutTests/http/wpt/webauthn/public-key-credential-get-failure-local.https.html
r250940 r257877 56 56 if (window.testRunner) 57 57 testRunner.addTestKeyToKeychain(privateKeyBase64, testRpId, userhandleBase64); 58 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Couldn't get user consent.").then(() => {58 return promiseRejects(t, "NotAllowedError", navigator.credentials.get(options), "Couldn't verify user.").then(() => { 59 59 if (window.testRunner) 60 60 testRunner.cleanUpKeychain(testRpId, userhandleBase64); -
trunk/Source/WebCore/ChangeLog
r257870 r257877 1 2020-03-03 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Implement -[_WKWebAuthenticationPanelDelegate panel:decidePolicyForLocalAuthenticatorWithCompletionHandler:] SPI 4 https://bugs.webkit.org/show_bug.cgi?id=208533 5 <rdar://problem/60010184> 6 7 Reviewed by Alex Christensen. 8 9 Covered by new tests within existing test files. 10 11 * en.lproj/Localizable.strings: 12 * platform/LocalizedStrings.cpp: 13 (WebCore::touchIDPromptTitle): 14 (WebCore::biometricFallbackPromptTitle): 15 * platform/LocalizedStrings.h: 16 Adds localized strings to support the customized LocalAuthentication dialog. 17 1 18 2020-03-04 Antoine Quint <graouts@apple.com> 2 19 -
trunk/Source/WebCore/en.lproj/Localizable.strings
r256086 r257877 311 311 "Enter Full Screen" = "Enter Full Screen"; 312 312 313 /* Use passcode as a fallback to sign into this website */ 314 "Enter passcode to sign into this website." = "Enter passcode to sign into this website."; 315 313 316 /* menu item */ 314 317 "Enter Picture in Picture" = "Enter Picture in Picture"; … … 878 881 "To view this page, you must log in to this area on %@:" = "To view this page, you must log in to this area on %@:"; 879 882 883 /* Use Touch ID to sign into this website */ 884 "Touch ID to sign into this website." = "Touch ID to sign into this website."; 885 880 886 /* Transformations context sub-menu item */ 881 887 "Transformations" = "Transformations"; -
trunk/Source/WebCore/platform/LocalizedStrings.cpp
r254238 r257877 1208 1208 #endif 1209 1209 1210 #if ENABLE(WEB_AUTHN) 1211 String touchIDPromptTitle() 1212 { 1213 return WEB_UI_STRING("Touch ID to sign into this website.", "Use Touch ID to sign into this website"); 1214 } 1215 1216 String biometricFallbackPromptTitle() 1217 { 1218 return WEB_UI_STRING("Enter passcode to sign into this website.", "Use passcode as a fallback to sign into this website"); 1219 } 1220 #endif 1221 1210 1222 } // namespace WebCore -
trunk/Source/WebCore/platform/LocalizedStrings.h
r252181 r257877 340 340 #endif 341 341 342 #if ENABLE(WEB_AUTHN) 343 WEBCORE_EXPORT String touchIDPromptTitle(); 344 WEBCORE_EXPORT String biometricFallbackPromptTitle(); 345 #endif 346 342 347 #if USE(GLIB) && defined(GETTEXT_PACKAGE) 343 348 #define WEB_UI_STRING(string, description) WebCore::localizedString(_(string)) -
trunk/Source/WebKit/ChangeLog
r257876 r257877 1 2020-03-03 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Implement -[_WKWebAuthenticationPanelDelegate panel:decidePolicyForLocalAuthenticatorWithCompletionHandler:] SPI 4 https://bugs.webkit.org/show_bug.cgi?id=208533 5 <rdar://problem/60010184> 6 7 Reviewed by Alex Christensen. 8 9 This patch implements the above SPI to replace -[_WKWebAuthenticationPanelDelegate panel:verifyUserWithAccessControl:completionHandler:]. 10 The original SPI is designed on the premise that Safari is going to highly customize the LocalAuthentication UI, and that is not happening 11 anymore. Therefore, WebKit takes back the invocation of LocalAuthentication and offer a new SPI to tell clients when WebKit is about to 12 show LocalAuthentication UI. Clients then have the trigger to pull at their pleasure. 13 14 This patch implements all plumbings to replace the SPI. Besides that, this patch also: 15 1) enhances the LocalConnection::verifyUser with a slightly customized LocalAuthentication dialog; 16 2) adds the SPI used above into the SPI header; 17 3) makes _WKWebAuthenticationPanelDelegate.transports as a NSSet instead of a NSArray; 18 4) lets LocalService::isAvailable return false if Apple attestation is not available. 19 20 * Platform/spi/Cocoa/LocalAuthenticationSPI.h: 21 * UIProcess/API/APIWebAuthenticationPanelClient.h: 22 (API::WebAuthenticationPanelClient::decidePolicyForLocalAuthenticator const): 23 (API::WebAuthenticationPanelClient::verifyUser const): Deleted. 24 * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h: 25 * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm: 26 (-[_WKWebAuthenticationPanel transports]): 27 * UIProcess/WebAuthentication/Authenticator.h: 28 * UIProcess/WebAuthentication/AuthenticatorManager.cpp: 29 (WebKit::AuthenticatorManager::decidePolicyForLocalAuthenticator): 30 (WebKit::AuthenticatorManager::verifyUser): Deleted. 31 * UIProcess/WebAuthentication/AuthenticatorManager.h: 32 * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h: 33 * UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm: 34 (WebKit::LocalAuthenticator::makeCredential): 35 (WebKit::LocalAuthenticator::continueMakeCredentialAfterDecidePolicy): 36 (WebKit::LocalAuthenticator::continueMakeCredentialAfterUserVerification): 37 (WebKit::LocalAuthenticator::continueMakeCredentialAfterAttested): 38 (WebKit::LocalAuthenticator::getAssertion): 39 (WebKit::LocalAuthenticator::continueGetAssertionAfterResponseSelected): 40 (WebKit::LocalAuthenticator::continueGetAssertionAfterUserVerification): 41 (WebKit::LocalAuthenticator::continueMakeCredentialAfterUserConsented): Deleted. 42 (WebKit::LocalAuthenticator::continueGetAssertionAfterUserConsented): Deleted. 43 * UIProcess/WebAuthentication/Cocoa/LocalConnection.h: 44 * UIProcess/WebAuthentication/Cocoa/LocalConnection.mm: 45 (WebKit::LocalConnection::verifyUser const): 46 (WebKit::LocalConnection::isUnlocked const): Deleted. 47 * UIProcess/WebAuthentication/Cocoa/LocalService.mm: 48 (WebKit::LocalService::isAvailable): 49 * UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.h: 50 * UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm: 51 (WebKit::WebAuthenticationPanelClient::WebAuthenticationPanelClient): 52 (WebKit::localAuthenticatorPolicy): 53 (WebKit::WebAuthenticationPanelClient::decidePolicyForLocalAuthenticator const): 54 (WebKit::WebAuthenticationPanelClient::verifyUser const): Deleted. 55 * UIProcess/WebAuthentication/Mock/MockLocalConnection.h: 56 * UIProcess/WebAuthentication/Mock/MockLocalConnection.mm: 57 (WebKit::MockLocalConnection::verifyUser const): 58 (WebKit::MockLocalConnection::isUnlocked const): Deleted. 59 * UIProcess/WebAuthentication/WebAuthenticationFlags.h: 60 1 61 2020-03-04 Alex Christensen <achristensen@webkit.org> 2 62 -
trunk/Source/WebKit/Platform/spi/Cocoa/LocalAuthenticationSPI.h
r257371 r257877 35 35 36 36 typedef NS_ENUM(NSInteger, LAOption) { 37 LAOptionNotInteractive, 37 LAOptionAuthenticationTitle, 38 LAOptionPasscodeTitle, 38 39 }; 39 40 40 41 @interface LAContext(Private) <NSSecureCoding> 41 42 42 - ( NSDictionary *)evaluatePolicy:(LAPolicy)policy options:(NSDictionary *)options error:(NSError **)error;43 - (void)evaluateAccessControl:(SecAccessControlRef)accessControl operation:(LAAccessControlOperation)operation options:(NSDictionary *)options reply:(void(^)(NSDictionary *result, NSError *error))reply; 43 44 44 45 @end -
trunk/Source/WebKit/UIProcess/API/APIWebAuthenticationPanelClient.h
r257269 r257877 28 28 #if ENABLE(WEB_AUTHN) 29 29 30 #include "WebAuthenticationFlags.h" 30 31 #include <wtf/CompletionHandler.h> 31 32 #include <wtf/HashSet.h> … … 38 39 namespace WebCore { 39 40 class AuthenticatorAssertionResponse; 40 }41 42 namespace WebKit {43 enum class WebAuthenticationStatus : uint8_t;44 enum class WebAuthenticationResult : bool;45 41 } 46 42 … … 56 52 virtual void requestPin(uint64_t, CompletionHandler<void(const WTF::String&)>&& completionHandler) const { completionHandler(emptyString()); } 57 53 virtual void selectAssertionResponse(Vector<Ref<WebCore::AuthenticatorAssertionResponse>>&& responses, CompletionHandler<void(const WebCore::AuthenticatorAssertionResponse&)>&& completionHandler) const { ASSERT(!responses.isEmpty()); completionHandler(responses[0]); } 58 virtual void verifyUser(SecAccessControlRef, CompletionHandler<void(LAContext *)>&& completionHandler) const { completionHandler(nullptr); }54 virtual void decidePolicyForLocalAuthenticator(CompletionHandler<void(WebKit::LocalAuthenticatorPolicy)>&& completionHandler) const { completionHandler(WebKit::LocalAuthenticatorPolicy::Disallow); } 59 55 }; 60 56 -
trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp
r257571 r257877 48 48 #include "APISessionState.h" 49 49 #include "APIUIClient.h" 50 #include "APIWebAuthenticationPanel.h" 51 #include "APIWebAuthenticationPanelClient.h" 50 52 #include "APIWebsitePolicies.h" 51 53 #include "APIWindowFeatures.h" … … 2080 2082 #if ENABLE(WEB_AUTHN) 2081 2083 // The current method is specialized for WebKitTestRunner. 2082 void runWebAuthenticationPanel(WebPageProxy&, API::WebAuthenticationPanel&, WebFrameProxy&, FrameInfoData&&, CompletionHandler<void(WebKit::WebAuthenticationPanelResult)>&& completionHandler) final 2083 { 2084 void runWebAuthenticationPanel(WebPageProxy&, API::WebAuthenticationPanel& panel, WebFrameProxy&, FrameInfoData&&, CompletionHandler<void(WebKit::WebAuthenticationPanelResult)>&& completionHandler) final 2085 { 2086 class PanelClient : public API::WebAuthenticationPanelClient { 2087 public: 2088 void decidePolicyForLocalAuthenticator(CompletionHandler<void(WebKit::LocalAuthenticatorPolicy)>&& completionHandler) const { completionHandler(WebKit::LocalAuthenticatorPolicy::Allow); } 2089 }; 2090 2084 2091 if (!m_client.runWebAuthenticationPanel) { 2085 2092 completionHandler(WebKit::WebAuthenticationPanelResult::Unavailable); 2086 2093 return; 2087 2094 } 2095 2096 panel.setClient(WTF::makeUniqueRef<PanelClient>()); 2088 2097 completionHandler(WebKit::WebAuthenticationPanelResult::Presented); 2089 2098 } -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h
r257269 r257877 69 69 } WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 70 70 71 typedef NS_ENUM(NSInteger, _WKLocalAuthenticatorPolicy) { 72 _WKLocalAuthenticatorPolicyAllow, 73 _WKLocalAuthenticatorPolicyDisallow, 74 } WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 75 71 76 @protocol _WKWebAuthenticationPanelDelegate <NSObject> 72 77 … … 77 82 - (void)panel:(_WKWebAuthenticationPanel *)panel requestPINWithRemainingRetries:(NSUInteger)retries completionHandler:(void (^)(NSString *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 78 83 - (void)panel:(_WKWebAuthenticationPanel *)panel selectAssertionResponse:(NSArray < _WKWebAuthenticationAssertionResponse *> *)responses completionHandler:(void (^)(_WKWebAuthenticationAssertionResponse *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 79 - (void)panel:(_WKWebAuthenticationPanel *)panel verifyUserWithAccessControl:(SecAccessControlRef)accessControl completionHandler:(void (^)(LAContext *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));84 - (void)panel:(_WKWebAuthenticationPanel *)panel decidePolicyForLocalAuthenticatorWithCompletionHandler:(void (^)(_WKLocalAuthenticatorPolicy policy))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 80 85 81 86 @end … … 86 91 @property (nullable, nonatomic, weak) id <_WKWebAuthenticationPanelDelegate> delegate; 87 92 @property (nonatomic, readonly, copy) NSString *relyingPartyID; 88 @property (nonatomic, readonly, copy) NS Array*transports;93 @property (nonatomic, readonly, copy) NSSet *transports; 89 94 @property (nonatomic, readonly) _WKWebAuthenticationType type; 90 95 -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm
r257269 r257877 34 34 #if ENABLE(WEB_AUTHN) 35 35 WeakPtr<WebKit::WebAuthenticationPanelClient> _client; 36 RetainPtr<NSMutable Array> _transports;36 RetainPtr<NSMutableSet> _transports; 37 37 #endif 38 38 } … … 82 82 } 83 83 84 - (NS Array*)transports84 - (NSSet *)transports 85 85 { 86 86 if (_transports) … … 88 88 89 89 auto& transports = _panel->transports(); 90 _transports = [[NSMutable Arrayalloc] initWithCapacity:transports.size()];90 _transports = [[NSMutableSet alloc] initWithCapacity:transports.size()]; 91 91 for (auto& transport : transports) 92 92 [_transports addObject:adoptNS([[NSNumber alloc] initWithInt:wkWebAuthenticationTransport(transport)]).get()]; -
trunk/Source/WebKit/UIProcess/WebAuthentication/Authenticator.h
r257269 r257877 57 57 virtual void requestPin(uint64_t retries, CompletionHandler<void(const WTF::String&)>&&) = 0; 58 58 virtual void selectAssertionResponse(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>&, CompletionHandler<void(const WebCore::AuthenticatorAssertionResponse&)>&&) = 0; 59 virtual void verifyUser(SecAccessControlRef, CompletionHandler<void(LAContext *)>&&) = 0;59 virtual void decidePolicyForLocalAuthenticator(CompletionHandler<void(LocalAuthenticatorPolicy)>&&) = 0; 60 60 }; 61 61 -
trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp
r257571 r257877 296 296 } 297 297 298 void AuthenticatorManager::verifyUser(SecAccessControlRef accessControlRef, CompletionHandler<void(LAContext *)>&& completionHandler) 299 { 300 RetainPtr<SecAccessControlRef> accessControl = accessControlRef; 301 dispatchPanelClientCall([accessControl = WTFMove(accessControl), completionHandler = WTFMove(completionHandler)] (const API::WebAuthenticationPanel& panel) mutable { 302 panel.client().verifyUser(accessControl.get(), WTFMove(completionHandler)); 298 void AuthenticatorManager::decidePolicyForLocalAuthenticator(CompletionHandler<void(LocalAuthenticatorPolicy)>&& completionHandler) 299 { 300 dispatchPanelClientCall([completionHandler = WTFMove(completionHandler)] (const API::WebAuthenticationPanel& panel) mutable { 301 panel.client().decidePolicyForLocalAuthenticator(WTFMove(completionHandler)); 303 302 }); 304 303 } -
trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h
r257269 r257877 84 84 void requestPin(uint64_t retries, CompletionHandler<void(const WTF::String&)>&&) final; 85 85 void selectAssertionResponse(const HashSet<Ref<WebCore::AuthenticatorAssertionResponse>>&, CompletionHandler<void(const WebCore::AuthenticatorAssertionResponse&)>&&) final; 86 void verifyUser(SecAccessControlRef, CompletionHandler<void(LAContext *)>&&) final;86 void decidePolicyForLocalAuthenticator(CompletionHandler<void(LocalAuthenticatorPolicy)>&&) final; 87 87 88 88 // Overriden by MockAuthenticatorManager. -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h
r257269 r257877 39 39 public: 40 40 // Here is the FSM. 41 // MakeCredential: Init => RequestReceived => UserConsented => Attested => End42 // GetAssertion: Init => RequestReceived => ResponseSelected => User Consented => End41 // MakeCredential: Init => RequestReceived => PolicyDecided => UserVerified => Attested => End 42 // GetAssertion: Init => RequestReceived => ResponseSelected => UserVerified => End 43 43 enum class State { 44 44 Init, 45 45 RequestReceived, 46 User Consented,46 UserVerified, 47 47 Attested, 48 ResponseSelected 48 ResponseSelected, 49 PolicyDecided, 49 50 }; 50 51 … … 58 59 59 60 void makeCredential() final; 60 void continueMakeCredentialAfterUserConsented(SecAccessControlRef, LAContext *); 61 void continueMakeCredentialAfterDecidePolicy(LocalAuthenticatorPolicy); 62 void continueMakeCredentialAfterUserVerification(SecAccessControlRef, LocalConnection::UserVerification, LAContext *); 61 63 void continueMakeCredentialAfterAttested(SecKeyRef, Vector<uint8_t>&& credentialId, Vector<uint8_t>&& authData, NSArray *certificates, NSError *); 62 64 63 65 void getAssertion() final; 64 66 void continueGetAssertionAfterResponseSelected(Ref<WebCore::AuthenticatorAssertionResponse>&&); 65 void continueGetAssertionAfterUser Consented(LAContext *, Ref<WebCore::AuthenticatorAssertionResponse>&&);67 void continueGetAssertionAfterUserVerification(Ref<WebCore::AuthenticatorAssertionResponse>&&, LocalConnection::UserVerification, LAContext *); 66 68 67 69 void receiveException(WebCore::ExceptionData&&, WebAuthenticationStatus = WebAuthenticationStatus::LAError) const; -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm
r257269 r257877 161 161 // Step 6. 162 162 // Get user consent. 163 if (auto* observer = this->observer()) { 164 auto callback = [weakThis = makeWeakPtr(*this)] (LocalAuthenticatorPolicy policy) { 165 ASSERT(RunLoop::isMain()); 166 if (!weakThis) 167 return; 168 169 weakThis->continueMakeCredentialAfterDecidePolicy(policy); 170 }; 171 observer->decidePolicyForLocalAuthenticator(WTFMove(callback)); 172 } 173 } 174 175 void LocalAuthenticator::continueMakeCredentialAfterDecidePolicy(LocalAuthenticatorPolicy policy) 176 { 177 ASSERT(m_state == State::RequestReceived); 178 m_state = State::PolicyDecided; 179 180 if (policy == LocalAuthenticatorPolicy::Disallow) { 181 receiveRespond(ExceptionData { UnknownError, "Disallow local authenticator."_s }); 182 return; 183 } 184 163 185 RetainPtr<SecAccessControlRef> accessControl; 164 186 { … … 172 194 } 173 195 174 if (auto* observer = this->observer()) { 175 SecAccessControlRef accessControlRef = accessControl.get(); 176 auto callback = [accessControl = WTFMove(accessControl), weakThis = makeWeakPtr(*this)] (LAContext *context) { 177 ASSERT(RunLoop::isMain()); 178 if (!weakThis) 179 return; 180 181 weakThis->continueMakeCredentialAfterUserConsented(accessControl.get(), context); 182 }; 183 observer->verifyUser(accessControlRef, WTFMove(callback)); 184 } 185 } 186 187 void LocalAuthenticator::continueMakeCredentialAfterUserConsented(SecAccessControlRef accessControlRef, LAContext *context) 196 SecAccessControlRef accessControlRef = accessControl.get(); 197 auto callback = [accessControl = WTFMove(accessControl), weakThis = makeWeakPtr(*this)] (LocalConnection::UserVerification verification, LAContext *context) { 198 ASSERT(RunLoop::isMain()); 199 if (!weakThis) 200 return; 201 202 weakThis->continueMakeCredentialAfterUserVerification(accessControl.get(), verification, context); 203 }; 204 m_connection->verifyUser(accessControlRef, WTFMove(callback)); 205 } 206 207 void LocalAuthenticator::continueMakeCredentialAfterUserVerification(SecAccessControlRef accessControlRef, LocalConnection::UserVerification verification, LAContext *context) 188 208 { 189 209 using namespace LocalAuthenticatorInternal; 190 210 191 ASSERT(m_state == State:: RequestReceived);192 m_state = State::User Consented;211 ASSERT(m_state == State::PolicyDecided); 212 m_state = State::UserVerified; 193 213 auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options); 194 214 195 if ( !m_connection->isUnlocked(context)) {196 receive Respond(ExceptionData { NotAllowedError, "Couldn't get user consent."_s });215 if (verification == LocalConnection::UserVerification::No) { 216 receiveException({ NotAllowedError, "Couldn't verify user."_s }); 197 217 return; 198 218 } … … 310 330 using namespace LocalAuthenticatorInternal; 311 331 312 ASSERT(m_state == State::User Consented);332 ASSERT(m_state == State::UserVerified); 313 333 m_state = State::Attested; 314 334 auto& creationOptions = WTF::get<PublicKeyCredentialCreationOptions>(requestData().options); … … 393 413 } 394 414 395 // Step 6 .415 // Step 6-7. User consent is implicitly acquired by selecting responses. 396 416 for (NSDictionary *attribute : intersectedCredentialsAttributes) { 397 417 auto addResult = m_assertionResponses.add(AuthenticatorAssertionResponse::create( … … 423 443 m_state = State::ResponseSelected; 424 444 425 // Step 7. Get user consent.426 if (auto* observer = this->observer()) {427 auto accessControlRef = response->accessControl();428 auto callback = [weakThis = makeWeakPtr(*this), response = WTFMove(response)] (LAContext *context) mutable {429 ASSERT(RunLoop::isMain());430 if (!weakThis)431 return;432 433 weakThis->continueGetAssertionAfterUserConsented(context, WTFMove(response)); 434 };435 observer->verifyUser(accessControlRef, WTFMove(callback));436 }437 } 438 439 void LocalAuthenticator::continueGetAssertionAfterUser Consented(LAContext *context, Ref<WebCore::AuthenticatorAssertionResponse>&& response)445 auto accessControlRef = response->accessControl(); 446 auto callback = [ 447 weakThis = makeWeakPtr(*this), 448 response = WTFMove(response) 449 ] (LocalConnection::UserVerification verification, LAContext *context) mutable { 450 ASSERT(RunLoop::isMain()); 451 if (!weakThis) 452 return; 453 454 weakThis->continueGetAssertionAfterUserVerification(WTFMove(response), verification, context); 455 }; 456 m_connection->verifyUser(accessControlRef, WTFMove(callback)); 457 } 458 459 void LocalAuthenticator::continueGetAssertionAfterUserVerification(Ref<WebCore::AuthenticatorAssertionResponse>&& response, LocalConnection::UserVerification verification, LAContext *context) 440 460 { 441 461 using namespace LocalAuthenticatorInternal; 442 462 ASSERT(m_state == State::ResponseSelected); 443 m_state = State::User Consented;444 445 if ( !m_connection->isUnlocked(context)) {446 receive Respond(ExceptionData { NotAllowedError, "Couldn't get user consent."_s });463 m_state = State::UserVerified; 464 465 if (verification == LocalConnection::UserVerification::No) { 466 receiveException({ NotAllowedError, "Couldn't verify user."_s }); 447 467 return; 448 468 } … … 457 477 RetainPtr<CFDataRef> signature; 458 478 { 459 auto query = adoptNS([[NSMutableDictionary alloc] init]); 460 [query addEntriesFromDictionary:@{ 479 NSDictionary *query = @{ 461 480 (id)kSecClass: (id)kSecClassKey, 462 481 (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate, 463 482 (id)kSecAttrApplicationLabel: toNSData(response->rawId()).get(), 483 (id)kSecUseAuthenticationContext: context, 464 484 (id)kSecReturnRef: @YES, 465 485 #if HAVE(DATA_PROTECTION_KEYCHAIN) … … 468 488 (id)kSecAttrNoLegacy: @YES 469 489 #endif 470 }]; 471 // context is nullptr in mock testing. 472 if (context) 473 [query setObject:context forKey:(id)kSecUseAuthenticationContext]; 490 }; 474 491 CFTypeRef privateKeyRef = nullptr; 475 OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query .get(), &privateKeyRef);492 OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &privateKeyRef); 476 493 if (status) { 477 494 receiveException({ UnknownError, makeString("Couldn't get the private key reference: ", status) }); -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.h
r257410 r257877 37 37 38 38 namespace WebCore { 39 40 39 class AuthenticatorAssertionResponse; 41 42 40 } 43 41 … … 53 51 WTF_MAKE_NONCOPYABLE(LocalConnection); 54 52 public: 53 enum class UserVerification : bool { 54 No, 55 Yes 56 }; 57 55 58 using AttestationCallback = CompletionHandler<void(NSArray *, NSError *)>; 59 using UserVerificationCallback = CompletionHandler<void(UserVerification, LAContext *)>; 56 60 57 61 LocalConnection() = default; … … 59 63 60 64 // Overrided by MockLocalConnection. 61 virtual bool isUnlocked(LAContext *) const;65 virtual void verifyUser(SecAccessControlRef, UserVerificationCallback&&) const; 62 66 virtual RetainPtr<SecKeyRef> createCredentialPrivateKey(LAContext *, SecAccessControlRef, const String& secAttrLabel, NSData *secAttrApplicationTag) const; 63 67 virtual void getAttestation(SecKeyRef, NSData *authData, NSData *hash, AttestationCallback&&) const; -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalConnection.mm
r257269 r257877 29 29 #if ENABLE(WEB_AUTHN) 30 30 31 #import <WebCore/LocalizedStrings.h> 31 32 #import <wtf/BlockPtr.h> 32 33 #import <wtf/RunLoop.h> … … 40 41 namespace WebKit { 41 42 42 bool LocalConnection::isUnlocked(LAContext *context) const43 void LocalConnection::verifyUser(SecAccessControlRef accessControl, UserVerificationCallback&& completionHandler) const 43 44 { 44 NSError *error = nil; 45 auto result = [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics options:@{ @(LAOptionNotInteractive): @YES } error:&error]; 46 if (!result) 47 LOG_ERROR("Couldn't get user consent: %@", error); 48 return !!result; 45 auto context = adoptNS([allocLAContextInstance() init]); 46 47 auto options = adoptNS([[NSMutableDictionary alloc] init]); 48 if ([context biometryType] == LABiometryTypeTouchID) 49 [options setObject:WebCore::touchIDPromptTitle() forKey:@(LAOptionAuthenticationTitle)]; 50 [options setObject:WebCore::biometricFallbackPromptTitle() forKey:@(LAOptionPasscodeTitle)]; 51 52 auto reply = makeBlockPtr([context, completionHandler = WTFMove(completionHandler)] (NSDictionary *, NSError *error) mutable { 53 ASSERT(!RunLoop::isMain()); 54 55 UserVerification verification = UserVerification::Yes; 56 if (error) { 57 LOG_ERROR("Couldn't authenticate with biometrics: %@", error); 58 verification = UserVerification::No; 59 } 60 RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), verification, context = WTFMove(context)] () mutable { 61 completionHandler(verification, context.get()); 62 }); 63 }); 64 65 [context evaluateAccessControl:accessControl operation:LAAccessControlOperationUseKeySign options:options.get() reply:reply.get()]; 49 66 } 50 67 -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm
r257085 r257877 56 56 #if defined(LOCALSERVICE_ADDITIONS) 57 57 LOCALSERVICE_ADDITIONS 58 #else 59 return false; 58 60 #endif 59 61 -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.h
r257269 r257877 51 51 void requestPin(uint64_t, CompletionHandler<void(const WTF::String&)>&&) const final; 52 52 void selectAssertionResponse(Vector<Ref<WebCore::AuthenticatorAssertionResponse>>&&, CompletionHandler<void(const WebCore::AuthenticatorAssertionResponse&)>&&) const final; 53 void verifyUser(SecAccessControlRef, CompletionHandler<void(LAContext *)>&&) const final;53 void decidePolicyForLocalAuthenticator(CompletionHandler<void(LocalAuthenticatorPolicy)>&&) const final; 54 54 55 55 _WKWebAuthenticationPanel *m_panel; … … 61 61 bool panelRequestPinWithRemainingRetriesCompletionHandler : 1; 62 62 bool panelSelectAssertionResponseCompletionHandler : 1; 63 bool panel VerifyUserWithAccessControlCompletionHandler : 1;63 bool panelDecidePolicyForLocalAuthenticatorCompletionHandler : 1; 64 64 } m_delegateMethods; 65 65 }; -
trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticationPanelClient.mm
r257269 r257877 33 33 #import "CompletionHandlerCallChecker.h" 34 34 #import "WKNSArray.h" 35 #import "WebAuthenticationFlags.h"36 35 #import "_WKWebAuthenticationAssertionResponseInternal.h" 37 36 #import "_WKWebAuthenticationPanel.h" … … 51 50 m_delegateMethods.panelRequestPinWithRemainingRetriesCompletionHandler = [delegate respondsToSelector:@selector(panel:requestPINWithRemainingRetries:completionHandler:)]; 52 51 m_delegateMethods.panelSelectAssertionResponseCompletionHandler = [delegate respondsToSelector:@selector(panel:selectAssertionResponse:completionHandler:)]; 53 m_delegateMethods.panel VerifyUserWithAccessControlCompletionHandler = [delegate respondsToSelector:@selector(panel:verifyUserWithAccessControl:completionHandler:)];52 m_delegateMethods.panelDecidePolicyForLocalAuthenticatorCompletionHandler = [delegate respondsToSelector:@selector(panel:decidePolicyForLocalAuthenticatorWithCompletionHandler:)]; 54 53 } 55 54 … … 168 167 } 169 168 170 void WebAuthenticationPanelClient::verifyUser(SecAccessControlRef accessControl, CompletionHandler<void(LAContext *)>&& completionHandler) const 171 { 172 if (!m_delegateMethods.panelVerifyUserWithAccessControlCompletionHandler) { 173 completionHandler(adoptNS([allocLAContextInstance() init]).get()); 169 static LocalAuthenticatorPolicy localAuthenticatorPolicy(_WKLocalAuthenticatorPolicy result) 170 { 171 switch (result) { 172 case _WKLocalAuthenticatorPolicyAllow: 173 return LocalAuthenticatorPolicy::Allow; 174 case _WKLocalAuthenticatorPolicyDisallow: 175 return LocalAuthenticatorPolicy::Disallow; 176 } 177 ASSERT_NOT_REACHED(); 178 return LocalAuthenticatorPolicy::Allow; 179 } 180 181 void WebAuthenticationPanelClient::decidePolicyForLocalAuthenticator(CompletionHandler<void(LocalAuthenticatorPolicy)>&& completionHandler) const 182 { 183 if (!m_delegateMethods.panelDecidePolicyForLocalAuthenticatorCompletionHandler) { 184 completionHandler(LocalAuthenticatorPolicy::Disallow); 174 185 return; 175 186 } … … 177 188 auto delegate = m_delegate.get(); 178 189 if (!delegate) { 179 completionHandler( adoptNS([allocLAContextInstance() init]).get());180 return; 181 } 182 183 auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(panel: verifyUserWithAccessControl:completionHandler:));184 [delegate panel:m_panel verifyUserWithAccessControl:accessControl completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](LAContext *context) mutable {190 completionHandler(LocalAuthenticatorPolicy::Disallow); 191 return; 192 } 193 194 auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(panel:decidePolicyForLocalAuthenticatorWithCompletionHandler:)); 195 [delegate panel:m_panel decidePolicyForLocalAuthenticatorWithCompletionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](_WKLocalAuthenticatorPolicy policy) mutable { 185 196 if (checker->completionHandlerHasBeenCalled()) 186 197 return; 187 198 checker->didCallCompletionHandler(); 188 completionHandler( context);199 completionHandler(localAuthenticatorPolicy(policy)); 189 200 }).get()]; 190 201 } -
trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.h
r257269 r257877 38 38 39 39 private: 40 bool isUnlocked(LAContext *) const final;40 void verifyUser(SecAccessControlRef, UserVerificationCallback&&) const final; 41 41 RetainPtr<SecKeyRef> createCredentialPrivateKey(LAContext *, SecAccessControlRef, const String& secAttrLabel, NSData *secAttrApplicationTag) const final; 42 42 void getAttestation(SecKeyRef, NSData *authData, NSData *hash, AttestationCallback&&) const final; -
trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockLocalConnection.mm
r257269 r257877 45 45 } 46 46 47 bool MockLocalConnection::isUnlocked(LAContext *context) const47 void MockLocalConnection::verifyUser(SecAccessControlRef, UserVerificationCallback&& callback) const 48 48 { 49 return m_configuration.local->acceptAuthentication; 49 // Mock async operations. 50 RunLoop::main().dispatch([configuration = m_configuration, callback = WTFMove(callback)]() mutable { 51 ASSERT(configuration.local); 52 if (!configuration.local->acceptAuthentication) { 53 callback(UserVerification::No, nil); 54 return; 55 } 56 callback(UserVerification::Yes, adoptNS([allocLAContextInstance() init]).get()); 57 }); 50 58 } 51 59 -
trunk/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticationFlags.h
r257269 r257877 52 52 }; 53 53 54 enum class LocalAuthenticatorPolicy : bool { 55 Allow, 56 Disallow 57 }; 58 54 59 } // namespace WebKit 55 60 -
trunk/Tools/ChangeLog
r257876 r257877 1 2020-03-03 Jiewen Tan <jiewen_tan@apple.com> 2 3 [WebAuthn] Implement -[_WKWebAuthenticationPanelDelegate panel:decidePolicyForLocalAuthenticatorWithCompletionHandler:] SPI 4 https://bugs.webkit.org/show_bug.cgi?id=208533 5 <rdar://problem/60010184> 6 7 Reviewed by Alex Christensen. 8 9 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 10 * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm: 11 (-[TestWebAuthenticationPanelDelegate panel:decidePolicyForLocalAuthenticatorWithCompletionHandler:]): 12 (TestWebKitAPI::TEST): 13 (-[TestWebAuthenticationPanelDelegate panel:verifyUserWithAccessControl:completionHandler:]): Deleted. 14 * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-get-assertion-la.html: Removed. 15 1 16 2020-03-04 Alex Christensen <achristensen@webkit.org> 2 17 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r257828 r257877 354 354 574217882400AC25002B303D /* web-authentication-make-credential-la-error.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 574217872400ABFD002B303D /* web-authentication-make-credential-la-error.html */; }; 355 355 5742178A2400AED8002B303D /* web-authentication-make-credential-la-duplicate-credential.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 574217892400AED0002B303D /* web-authentication-make-credential-la-duplicate-credential.html */; }; 356 5742178C2400CD47002B303D /* web-authentication-get-assertion-la.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5742178B2400CD2D002B303D /* web-authentication-get-assertion-la.html */; };357 356 5742178E2400D2DF002B303D /* web-authentication-make-credential-la.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5742178D2400D26C002B303D /* web-authentication-make-credential-la.html */; }; 358 357 574F55D2204D47F0002948C6 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 574F55D0204D471C002948C6 /* Security.framework */; }; … … 1530 1529 570D26FC23C3F87000D5CF67 /* web-authentication-get-assertion-hid-pin.html in Copy Resources */, 1531 1530 57663DEC234F1F9300E85E09 /* web-authentication-get-assertion-hid.html in Copy Resources */, 1532 5742178C2400CD47002B303D /* web-authentication-get-assertion-la.html in Copy Resources */,1533 1531 579833922368FA37008E5547 /* web-authentication-get-assertion-nfc-multiple-tags.html in Copy Resources */, 1534 1532 57663DEA234EA66D00E85E09 /* web-authentication-get-assertion-nfc.html in Copy Resources */, … … 1983 1981 574217872400ABFD002B303D /* web-authentication-make-credential-la-error.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-la-error.html"; sourceTree = "<group>"; }; 1984 1982 574217892400AED0002B303D /* web-authentication-make-credential-la-duplicate-credential.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-la-duplicate-credential.html"; sourceTree = "<group>"; }; 1985 5742178B2400CD2D002B303D /* web-authentication-get-assertion-la.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-get-assertion-la.html"; sourceTree = "<group>"; };1986 1983 5742178D2400D26C002B303D /* web-authentication-make-credential-la.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential-la.html"; sourceTree = "<group>"; }; 1987 1984 5742178F2400D54D002B303D /* web-authentication-make-credential.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "web-authentication-make-credential.html"; sourceTree = "<group>"; }; … … 3615 3612 570D26FB23C3F86500D5CF67 /* web-authentication-get-assertion-hid-pin.html */, 3616 3613 57663DEB234F1F8000E85E09 /* web-authentication-get-assertion-hid.html */, 3617 5742178B2400CD2D002B303D /* web-authentication-get-assertion-la.html */,3618 3614 5798337B235EB65C008E5547 /* web-authentication-get-assertion-nfc-multiple-tags.html */, 3619 3615 57663DE9234EA60B00E85E09 /* web-authentication-get-assertion-nfc.html */, -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm
r257269 r257877 56 56 static bool webAuthenticationPanelUpdateLANoCredential = false; 57 57 static bool webAuthenticationPanelCancelImmediately = false; 58 static bool webAuthenticationPanelVerifyUser = false;58 static _WKLocalAuthenticatorPolicy localAuthenticatorPolicy = _WKLocalAuthenticatorPolicyDisallow; 59 59 static String webAuthenticationPanelPin; 60 60 static BOOL webAuthenticationPanelNullUserHandle = NO; … … 152 152 } 153 153 154 - (void)panel:(_WKWebAuthenticationPanel *)panel verifyUserWithAccessControl:(SecAccessControlRef)accessControl completionHandler:(void (^)(LAContext *))completionHandler 155 { 156 webAuthenticationPanelVerifyUser = true; 157 auto context = adoptNS([[LAContext alloc] init]); 158 completionHandler(context.get()); 154 - (void)panel:(_WKWebAuthenticationPanel *)panel decidePolicyForLocalAuthenticatorWithCompletionHandler:(void (^)(_WKLocalAuthenticatorPolicy policy))completionHandler 155 { 156 completionHandler(localAuthenticatorPolicy); 159 157 } 160 158 … … 301 299 webAuthenticationPanelPin = emptyString(); 302 300 webAuthenticationPanelNullUserHandle = NO; 303 webAuthenticationPanelVerifyUser = false;301 localAuthenticatorPolicy = _WKLocalAuthenticatorPolicyDisallow; 304 302 } 305 303 … … 308 306 EXPECT_WK_STREQ(panel.relyingPartyID, relyingPartyID); 309 307 310 // Brute force given the maximum size of the array is 4. 311 auto *theTransports = panel.transports; 312 EXPECT_EQ(theTransports.count, transports.count); 308 EXPECT_EQ(panel.transports.count, transports.count); 313 309 size_t count = 0; 314 310 for (NSNumber *transport : transports) { 315 for (NSNumber *theTransport : theTransports) { 316 if (transport == theTransport) { 317 count++; 318 break; 319 } 320 } 311 if ([panel.transports containsObject:transport]) 312 count++; 321 313 } 322 314 EXPECT_EQ(count, transports.count); … … 1260 1252 1261 1253 [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]]; 1262 [webView waitForMessage:@"Succeeded!"]; 1254 [webView waitForMessage:@"Disallow local authenticator."]; 1255 } 1256 1257 TEST(WebAuthenticationPanel, LAMakeCredentialDisallowLocalAuthenticator) 1258 { 1259 reset(); 1260 RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-la" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; 1261 1262 auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; 1263 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()]; 1264 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationLocalAuthenticatorExperimentalFeature()]; 1265 1266 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]); 1267 auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]); 1268 [webView setUIDelegate:delegate.get()]; 1269 1270 [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]]; 1271 [webView waitForMessage:@"Disallow local authenticator."]; 1272 } 1273 1274 TEST(WebAuthenticationPanel, LAMakeCredentialAllowLocalAuthenticator) 1275 { 1276 reset(); 1277 RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-la" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; 1278 1279 auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; 1280 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()]; 1281 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationLocalAuthenticatorExperimentalFeature()]; 1282 1283 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]); 1284 auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]); 1285 [webView setUIDelegate:delegate.get()]; 1286 1287 localAuthenticatorPolicy = _WKLocalAuthenticatorPolicyAllow; 1288 [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]]; 1289 [webView waitForMessage:@"Succeeded!"]; 1290 checkPanel([delegate panel], @"", @[adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportUSB]).get(), adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportInternal]).get()], _WKWebAuthenticationTypeCreate); 1263 1291 cleanUpKeychain(""); 1264 1292 } 1265 1293 1266 TEST(WebAuthenticationPanel, LAMakeCredential)1267 {1268 reset();1269 RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-la" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];1270 1271 auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];1272 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];1273 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationLocalAuthenticatorExperimentalFeature()];1274 1275 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);1276 auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);1277 [webView setUIDelegate:delegate.get()];1278 1279 [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];1280 Util::run(&webAuthenticationPanelVerifyUser);1281 checkPanel([delegate panel], @"", @[adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportUSB]).get(), adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportInternal]).get()], _WKWebAuthenticationTypeCreate);1282 [webView waitForMessage:@"Succeeded!"];1283 }1284 1285 TEST(WebAuthenticationPanel, LAGetAssertion)1286 {1287 reset();1288 RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-get-assertion-la" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];1289 1290 auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];1291 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];1292 [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationLocalAuthenticatorExperimentalFeature()];1293 1294 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);1295 auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);1296 [webView setUIDelegate:delegate.get()];1297 1298 ASSERT_TRUE(addKeyToKeychain(testES256PrivateKeyBase64, "", testUserhandleBase64));1299 [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];1300 Util::run(&webAuthenticationPanelVerifyUser);1301 checkPanel([delegate panel], @"", @[adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportUSB]).get(), adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportInternal]).get()], _WKWebAuthenticationTypeGet);1302 [webView waitForMessage:@"Succeeded!"];1303 cleanUpKeychain("");1304 }1305 1306 1294 #endif // USE(APPLE_INTERNAL_SDK) || PLATFORM(IOS) 1307 1295
Note: See TracChangeset
for help on using the changeset viewer.