[iOS] Apple Pay should be available in documents with no user agent scripts
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 20:51:56 +0000 (20:51 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 20:51:56 +0000 (20:51 +0000)
commit303996720db5d28668728246aa268e25ae3bf04f
treebe9bec1800bb97e51129bde9c93f2fe842121278
parent45ea9e33de57f302616e698f035bffc879e22db4
[iOS] Apple Pay should be available in documents with no user agent scripts
https://bugs.webkit.org/show_bug.cgi?id=196061
<rdar://problem/48649391>

Reviewed by Brady Eidson.

Source/WebCore:

On platforms that support APPLE_PAY_REMOTE_UI, we can enable Apple Pay JS and Payment Request
by default in all WebKit clients.

In order to protect the privacy of Apple Pay transactions, this patch implements the
following restrictions on API usage:

1. If user agent scripts have been evaluated in a document, Apple Pay APIs will no longer be
available for the duration of the document's lifetime.
2. If an Apple Pay transaction has started in a document, user agent scripts will no longer
be evaluated for the duration of the document's lifetime.

These restrictions are disabled for clients with the
com.apple.private.WebKit.UnrestrictedApplePay entitlement and platforms that do support
Apple Pay but don't support APPLE_PAY_REMOTE_UI.

Added new API tests.

* Modules/applepay/ApplePayRequestBase.cpp:
(WebCore::convertAndValidate):
* Modules/applepay/ApplePayRequestBase.h:
* Modules/applepay/ApplePaySession.cpp:
(WebCore::convertAndValidate):
(WebCore::ApplePaySession::create):
(WebCore::ApplePaySession::supportsVersion):
(WebCore::ApplePaySession::canMakePayments):
(WebCore::ApplePaySession::canMakePaymentsWithActiveCard):
(WebCore::ApplePaySession::openPaymentSetup):
(WebCore::ApplePaySession::begin):
* Modules/applepay/ApplePaySession.h:
* Modules/applepay/ApplePaySession.idl:
* Modules/applepay/PaymentCoordinator.cpp:
(WebCore::PaymentCoordinator::supportsVersion const):
(WebCore::PaymentCoordinator::canMakePayments):
(WebCore::PaymentCoordinator::canMakePaymentsWithActiveCard):
(WebCore::PaymentCoordinator::openPaymentSetup):
(WebCore::PaymentCoordinator::beginPaymentSession):
(WebCore::PaymentCoordinator::validatedPaymentNetwork const):
(WebCore::PaymentCoordinator::shouldAllowApplePay const):
(WebCore::PaymentCoordinator::shouldAllowUserAgentScripts const):
* Modules/applepay/PaymentCoordinator.h:
* Modules/applepay/PaymentCoordinatorClient.h:
(WebCore::PaymentCoordinatorClient::supportsUnrestrictedApplePay const):
* Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp:
(WebCore::ApplePayPaymentHandler::show):
(WebCore::ApplePayPaymentHandler::canMakePayment):
(WebCore::ApplePayPaymentHandler::version const):
* Modules/applepay/paymentrequest/ApplePayPaymentHandler.h:
* Modules/paymentrequest/PaymentHandler.h:
* Modules/paymentrequest/PaymentRequest.cpp:
(WebCore::PaymentRequest::show):
(WebCore::PaymentRequest::canMakePayment):

Plumbed a Document& through to the various places that call into PaymentCoordinator for use
by shouldAllowApplePay and shouldAllowUserAgentScripts.

* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::executeUserAgentScriptInWorld):
(WebCore::ScriptController::shouldAllowUserAgentScripts const):
* bindings/js/ScriptController.h:

Added executeUserAgentScriptInWorld, which calls executeScriptInWorld if allowed.

* dom/Document.cpp:
(WebCore::Document::ensurePlugInsInjectedScript):

Changed to only evaluate the chrome client's plug-in extra script if allowed, and to mark
the document as having evaluated user agent scripts.

(WebCore::Document::hasEvaluatedUserAgentScripts const):
(WebCore::Document::isRunningUserScripts const):
(WebCore::Document::setAsRunningUserScripts):
(WebCore::Document::setHasEvaluatedUserAgentScripts):
(WebCore::Document::hasStartedApplePaySession const):
(WebCore::Document::setHasStartedApplePaySession):
* dom/Document.h:

Added helper functions to set state on the top document.

* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::DocumentThreadableLoader):

Removed call to topDocument() now that isRunningUserScripts() always checks the top document.

* page/Frame.cpp:
(WebCore::Frame::injectUserScriptImmediately):

Changed to only inject the user script if allowed.

* page/Settings.yaml:
* page/SettingsDefaultValues.h:

Enabled Apple Pay by default on platforms that enable APPLE_PAY_REMOTE_UI.

* testing/Internals.cpp:
(WebCore::Internals::setAsRunningUserScripts):
(WebCore::Internals::setHasStartedApplePaySession):
* testing/Internals.h:
* testing/Internals.idl:
* testing/MockPaymentCoordinator.h:
* testing/MockPaymentCoordinator.idl:

Added some internal interfaces for use by TestWebKitAPI.

Source/WebKit:

* Shared/AuxiliaryProcess.h:
* Shared/Cocoa/AuxiliaryProcessCocoa.mm:
(WebKit::AuxiliaryProcess::parentProcessHasEntitlement):

Added a convenience function for checking parent process entitlements.

* Shared/WebPreferences.yaml:
* Shared/WebPreferencesDefaultValues.h:
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):

Enabled Apple Pay by default on platforms that enable APPLE_PAY_REMOTE_UI.

* WebProcess/ApplePay/WebPaymentCoordinator.cpp:
(WebKit::WebPaymentCoordinator::supportsUnrestrictedApplePay const):
* WebProcess/ApplePay/WebPaymentCoordinator.h:

Implemented supportsUnrestrictedApplePay by checking for the
com.apple.private.WebKit.UnrestrictedApplePay entitlement on platforms that enable
APPLE_PAY_REMOTE_UI.

* WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h:
* WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
(didClearWindowObjectForFrame):
(setUpPageLoaderClient):

Added injected bundle SPI that TestWebKitAPI uses to inject the WebCore Internals interface.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::runJavaScript):

Changed to call ScriptController::executeUserAgentScriptInWorld.

Source/WebKitLegacy/mac:

* WebView/WebFrame.mm:
(-[WebFrame _stringByEvaluatingJavaScriptFromString:withGlobalObject:inScriptWorld:]):

Tools:

Added API tests and related infrastructure.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/ApplePay.mm: Added.
(-[TestApplePayScriptMessageHandler initWithExpectation:]):
(-[TestApplePayScriptMessageHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/apple-pay-active-session.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability-in-iframe.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability.html: Added.
* TestWebKitAPI/cocoa/TestProtocol.mm:
(-[TestProtocol startLoading]):
* TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.h: Added.
* TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.mm: Added.
(-[WebProcessPlugInWithInternals webProcessPlugIn:didCreateBrowserContextController:]):
(-[WebProcessPlugInWithInternals webProcessPlugInBrowserContextController:didClearWindowObjectForFrame:inScriptWorld:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243324 268f45cc-cd09-0410-ab3c-d52691b4dbfc
48 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/applepay/ApplePayRequestBase.cpp
Source/WebCore/Modules/applepay/ApplePayRequestBase.h
Source/WebCore/Modules/applepay/ApplePaySession.cpp
Source/WebCore/Modules/applepay/ApplePaySession.h
Source/WebCore/Modules/applepay/ApplePaySession.idl
Source/WebCore/Modules/applepay/PaymentCoordinator.cpp
Source/WebCore/Modules/applepay/PaymentCoordinator.h
Source/WebCore/Modules/applepay/PaymentCoordinatorClient.h
Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp
Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.h
Source/WebCore/Modules/paymentrequest/PaymentHandler.h
Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp
Source/WebCore/bindings/js/ScriptController.cpp
Source/WebCore/bindings/js/ScriptController.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/page/Frame.cpp
Source/WebCore/page/Settings.yaml
Source/WebCore/page/SettingsDefaultValues.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebCore/testing/MockPaymentCoordinator.h
Source/WebCore/testing/MockPaymentCoordinator.idl
Source/WebKit/ChangeLog
Source/WebKit/Shared/AuxiliaryProcess.h
Source/WebKit/Shared/Cocoa/AuxiliaryProcessCocoa.mm
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/Shared/WebPreferencesDefaultValues.h
Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm
Source/WebKit/WebProcess/ApplePay/WebPaymentCoordinator.cpp
Source/WebKit/WebProcess/ApplePay/WebPaymentCoordinator.h
Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h
Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebFrame.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplePay.mm [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-active-session.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability-in-iframe.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability.html [new file with mode: 0644]
Tools/TestWebKitAPI/cocoa/TestProtocol.mm
Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.h [new file with mode: 0644]
Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.mm [new file with mode: 0644]