Title: [260408] trunk
Revision
260408
Author
[email protected]
Date
2020-04-20 19:36:27 -0700 (Mon, 20 Apr 2020)

Log Message

App-bound domain behavior should abide by the limitsNavigationsToAppBoundDomains argument in WKWebView configuration
https://bugs.webkit.org/show_bug.cgi?id=210769
<rdar://problem/62065241>

Reviewed by Brent Fulgham.

Source/WebKit:

Changes app-bound domain behavior to be triggered by the value of
limitsNavigationsToAppBoundDomains, a WebView configuration flag.
If the WebView has this parameter set and is currently navigating to
an app bound domain, then app-bound privileges will be granted.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
Update this function to return a boolean to indicate whether the
navigation should fail. A failure should occur if a WebView has set
the limitsNavigationsToAppBoundDomains flag and attempts to navigate
away from an app-bound domain.

If the limitsNavigationsToAppBoundDomains value has not been set to
true, maintain non-app bound behavior regardless of whether the domain
is app-bound or not.

(WebKit::WebPageProxy::decidePolicyForNavigationAction):
Check the result of setIsNavigatingToAppBoundDomainAndCheckIfPermitted and fail the
navigation if needed, with both RELEASE logging and an appropriate
error message.

(WebKit::WebPageProxy::setIsNavigatingToAppBoundDomain): Deleted.
* UIProcess/WebPageProxy.h:
Renamed for clarity.

Tools:

Removes any tests for swapping between app-bound and non app-bound
domains as this behavior is no longer supported.

Sets the limitsNavigationsToAppBoundDomains flag for tests which should
have app-bound behavior to maintain test functionality.

Adds 5 new tests for new behavior.

* TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
(TEST):
(-[AppBoundDomainDelegate webView:didFinishNavigation:]):
(-[AppBoundDomainDelegate webView:didFailProvisionalNavigation:withError:]):
(-[AppBoundDomainDelegate waitForDidFinishNavigation]):
(-[AppBoundDomainDelegate waitForDidFailProvisionalNavigationError]):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (260407 => 260408)


--- trunk/Source/WebKit/ChangeLog	2020-04-21 00:27:46 UTC (rev 260407)
+++ trunk/Source/WebKit/ChangeLog	2020-04-21 02:36:27 UTC (rev 260408)
@@ -1,3 +1,36 @@
+2020-04-20  Kate Cheney  <[email protected]>
+
+        App-bound domain behavior should abide by the limitsNavigationsToAppBoundDomains argument in WKWebView configuration
+        https://bugs.webkit.org/show_bug.cgi?id=210769
+        <rdar://problem/62065241>
+
+        Reviewed by Brent Fulgham.
+
+        Changes app-bound domain behavior to be triggered by the value of
+        limitsNavigationsToAppBoundDomains, a WebView configuration flag.
+        If the WebView has this parameter set and is currently navigating to
+        an app bound domain, then app-bound privileges will be granted.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
+        Update this function to return a boolean to indicate whether the
+        navigation should fail. A failure should occur if a WebView has set
+        the limitsNavigationsToAppBoundDomains flag and attempts to navigate
+        away from an app-bound domain.
+
+        If the limitsNavigationsToAppBoundDomains value has not been set to
+        true, maintain non-app bound behavior regardless of whether the domain
+        is app-bound or not.
+
+        (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+        Check the result of setIsNavigatingToAppBoundDomainAndCheckIfPermitted and fail the
+        navigation if needed, with both RELEASE logging and an appropriate
+        error message.
+
+        (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomain): Deleted.
+        * UIProcess/WebPageProxy.h:
+        Renamed for clarity.
+
 2020-04-20  Nikos Mouchtaris  <[email protected]>
 
         WK2 Quicklook for attachments

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (260407 => 260408)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-04-21 00:27:46 UTC (rev 260407)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-04-21 02:36:27 UTC (rev 260408)
@@ -3127,26 +3127,29 @@
     PolicyCheckIdentifier m_identifier;
 };
 
-void WebPageProxy::setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL& requestURL, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
+bool WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMainFrame, const URL& requestURL, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
 {
 #if PLATFORM(IOS_FAMILY)
     if (isMainFrame) {
         if (WEB_PAGE_PROXY_ADDITIONS_SETISNAVIGATINGTOAPPBOUNDDOMAIN)
-            return;
+            return true;
         if (!isNavigatingToAppBoundDomain) {
             m_isNavigatingToAppBoundDomain = WTF::nullopt;
-            return;
+            return true;
         }
         if (m_ignoresAppBoundDomains)
-            return;
-        if (*isNavigatingToAppBoundDomain == NavigatingToAppBoundDomain::No) {
+            return true;
+        
+        if (m_limitsNavigationsToAppBoundDomains) {
+            if (*isNavigatingToAppBoundDomain == NavigatingToAppBoundDomain::No)
+                return false;
+            m_configuration->setWebViewCategory(WebViewCategory::AppBoundDomain);
+            m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::Yes;
+        } else {
             m_configuration->setWebViewCategory(WebViewCategory::InAppBrowser);
             m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::No;
             m_hasNavigatedAwayFromAppBoundDomain = NavigatedAwayFromAppBoundDomain::Yes;
-            return;
         }
-        m_configuration->setWebViewCategory(WebViewCategory::AppBoundDomain);
-        m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::Yes;
     }
 #else
     UNUSED_PARAM(isMainFrame);
@@ -3153,6 +3156,7 @@
     UNUSED_PARAM(requestURL);
     UNUSED_PARAM(isNavigatingToAppBoundDomain);
 #endif
+    return true;
 }
 
 void WebPageProxy::isNavigatingToAppBoundDomainTesting(CompletionHandler<void(bool)>&& completionHandler)
@@ -5155,11 +5159,8 @@
     shouldExpectAppBoundDomainResult = ShouldExpectAppBoundDomainResult::Yes;
 #endif
     
-    auto listener = makeRef(frame.setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(frame), sender = WTFMove(sender), navigation] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, Optional<NavigatingToAppBoundDomain> isAppBoundDomain) mutable {
+    auto listener = makeRef(frame.setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(frame), sender = WTFMove(sender), navigation, frameInfo, userDataObject = process->transformHandlesToObjects(userData.object()).get()] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, Optional<NavigatingToAppBoundDomain> isAppBoundDomain) mutable {
 
-        if (policyAction != PolicyAction::Ignore)
-            setIsNavigatingToAppBoundDomain(frame->isMainFrame(), navigation->currentRequest().url(), isAppBoundDomain);
-
         auto completionHandler = [this, protectedThis = protectedThis.copyRef(), frame = frame.copyRef(), sender = WTFMove(sender), navigation, processSwapRequestedByClient, policies = makeRefPtr(policies)] (PolicyAction policyAction) mutable {
             if (frame->isMainFrame()) {
                 if (!policies) {
@@ -5171,6 +5172,16 @@
             }
             receivedNavigationPolicyDecision(policyAction, navigation.get(), processSwapRequestedByClient, frame, WTFMove(policies), WTFMove(sender));
         };
+        
+        if (policyAction != PolicyAction::Ignore) {
+            if (!setIsNavigatingToAppBoundDomainAndCheckIfPermitted(frame->isMainFrame(), navigation->currentRequest().url(), isAppBoundDomain)) {
+                auto error = ResourceError { String { }, 0, navigation->currentRequest().url(), "Attempted navigation away from app-bound domain"_s };
+                m_navigationClient->didFailProvisionalNavigationWithError(*this, FrameInfoData { frameInfo }, navigation.get(), error, userDataObject);
+                RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring request to load this main resource because it is attempting to navigate away from an app-bound domain");
+                completionHandler(PolicyAction::Ignore);
+                return;
+            }
+        }
 
         if (!m_pageClient)
             return completionHandler(policyAction);

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (260407 => 260408)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2020-04-21 00:27:46 UTC (rev 260407)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2020-04-21 02:36:27 UTC (rev 260408)
@@ -2311,7 +2311,7 @@
     void tryCloseTimedOut();
     void makeStorageSpaceRequest(WebCore::FrameIdentifier, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&&);
         
-    void setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL&, Optional<NavigatingToAppBoundDomain>);
+    bool setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMainFrame, const URL&, Optional<NavigatingToAppBoundDomain>);
     NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain() const { return m_hasNavigatedAwayFromAppBoundDomain; }
         
     const Identifier m_identifier;

Modified: trunk/Tools/ChangeLog (260407 => 260408)


--- trunk/Tools/ChangeLog	2020-04-21 00:27:46 UTC (rev 260407)
+++ trunk/Tools/ChangeLog	2020-04-21 02:36:27 UTC (rev 260408)
@@ -1,3 +1,26 @@
+2020-04-20  Kate Cheney  <[email protected]>
+
+        App-bound domain behavior should abide by the limitsNavigationsToAppBoundDomains argument in WKWebView configuration
+        https://bugs.webkit.org/show_bug.cgi?id=210769
+        <rdar://problem/62065241>
+
+        Reviewed by Brent Fulgham.
+
+        Removes any tests for swapping between app-bound and non app-bound
+        domains as this behavior is no longer supported.
+
+        Sets the limitsNavigationsToAppBoundDomains flag for tests which should
+        have app-bound behavior to maintain test functionality.
+
+        Adds 5 new tests for new behavior.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+        (TEST):
+        (-[AppBoundDomainDelegate webView:didFinishNavigation:]):
+        (-[AppBoundDomainDelegate webView:didFailProvisionalNavigation:withError:]):
+        (-[AppBoundDomainDelegate waitForDidFinishNavigation]):
+        (-[AppBoundDomainDelegate waitForDidFailProvisionalNavigationError]):
+
 2020-04-20  Megan Gardner  <[email protected]>
 
         Date and Time form controls not showing correct initial values on immediate second invocation.

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (260407 => 260408)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2020-04-21 00:27:46 UTC (rev 260407)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2020-04-21 02:36:27 UTC (rev 260408)
@@ -220,49 +220,6 @@
     TestWebKitAPI::Util::run(&isDone);
 }
 
-TEST(InAppBrowserPrivacy, SwapBackToAppBoundRejectsUserScript)
-{
-    initializeInAppBrowserPrivacyTestSettings();
-    auto userScript = adoptNS([[WKUserScript alloc] initWithSource:userScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
-
-    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
-    [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
-    [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
-
-    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
-    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
-    
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
-    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-script"]];
-    [webView loadRequest:request];
-    [webView _test_waitForDidFinishNavigation];
-
-    [configuration.userContentController _addUserScriptImmediately:userScript.get()];
-    [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
-        EXPECT_FALSE(result);
-        EXPECT_TRUE(!!error);
-        isDone = true;
-    }];
-
-    isDone = false;
-    TestWebKitAPI::Util::run(&isDone);
-
-    request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
-    [webView loadRequest:request];
-    [webView _test_waitForDidFinishNavigation];
-    
-    isDone = false;
-    [configuration.userContentController _addUserScriptImmediately:userScript.get()];
-    [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
-        EXPECT_FALSE(result);
-        EXPECT_TRUE(!!error);
-        cleanUpInAppBrowserPrivacyTestSettings();
-        isDone = true;
-    }];
-
-    TestWebKitAPI::Util::run(&isDone);
-}
-
 TEST(InAppBrowserPrivacy, AppBoundDomains)
 {
     initializeInAppBrowserPrivacyTestSettings();
@@ -288,6 +245,7 @@
     initializeInAppBrowserPrivacyTestSettings();
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+    [configuration setLimitsNavigationsToAppBoundDomains:YES];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
@@ -308,6 +266,7 @@
     initializeInAppBrowserPrivacyTestSettings();
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+    [configuration setLimitsNavigationsToAppBoundDomains:YES];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"data:text/html,start"]]];
@@ -327,6 +286,7 @@
     initializeInAppBrowserPrivacyTestSettings();
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+    [configuration setLimitsNavigationsToAppBoundDomains:YES];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
@@ -345,6 +305,7 @@
 static NSString *backgroundColorScript = @"window.getComputedStyle(document.body, null).getPropertyValue('background-color')";
 static NSString *frameBackgroundColorScript = @"window.getComputedStyle(document.getElementsByTagName('iframe')[0].contentDocument.body, null).getPropertyValue('background-color')";
 static const char* redInRGB = "rgb(255, 0, 0)";
+static const char* blackInRGB = "rgba(0, 0, 0, 0)";
 
 static void expectScriptEvaluatesToColor(WKWebView *webView, NSString *script, const char* color)
 {
@@ -458,7 +419,7 @@
     cleanUpInAppBrowserPrivacyTestSettings();
 }
 
-TEST(InAppBrowserPrivacy, AppBoundToNonAppBoundDomainCannotAccessMessageHandlers)
+TEST(InAppBrowserPrivacy, AppBoundDomainCanAccessMessageHandlers)
 {
     initializeInAppBrowserPrivacyTestSettings();
     isDone = false;
@@ -468,6 +429,7 @@
     auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
     [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
     [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+    [configuration setLimitsNavigationsToAppBoundDomains:YES];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
 
@@ -486,14 +448,6 @@
         FAIL();
     }];
 
-    // Navigate away from an app-bound domain.
-    NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-message-handler"]];
-    [webView loadRequest:request2];
-    [webView _test_waitForDidFinishNavigation];
-
-    // Set the background color to red if message handlers returned null so we can
-    // check without needing a message handler.
-    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
     cleanUpInAppBrowserPrivacyTestSettings();
 }
 
@@ -875,6 +829,205 @@
     isDone = false;
 }
 
+@interface AppBoundDomainDelegate : NSObject <WKNavigationDelegate>
+- (void)waitForDidFinishNavigation;
+- (NSError *)waitForDidFailProvisionalNavigationError;
+@end
+
+@implementation AppBoundDomainDelegate {
+    bool _navigationFinished;
+    RetainPtr<NSError> _provisionalNavigationFailedError;
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+    _navigationFinished = true;
+}
+
+- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
+{
+    _provisionalNavigationFailedError = error;
+}
+
+- (void)waitForDidFinishNavigation
+{
+    TestWebKitAPI::Util::run(&_navigationFinished);
+}
+
+- (NSError *)waitForDidFailProvisionalNavigationError
+{
+    while (!_provisionalNavigationFailedError)
+        TestWebKitAPI::Util::spinRunLoop();
+    return _provisionalNavigationFailedError.autorelease();
+}
+
+@end
+
+TEST(InAppBrowserPrivacy, AppBoundFlagForNonAppBoundDomainFails)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+    [configuration setLimitsNavigationsToAppBoundDomains:YES];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    // Load a non-app bound domain.
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+    [webView loadRequest:request];
+    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+    EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+
+    // Make sure the load didn't complete by checking the background color.
+    // Red would indicate it finished loading.
+    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
+    cleanUpInAppBrowserPrivacyTestSettings();
+}
+
+TEST(InAppBrowserPrivacy, NavigateAwayFromAppBoundDomainWithAppBoundFlagFails)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+    [configuration setLimitsNavigationsToAppBoundDomains:YES];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+    
+    // Navigate to an app-bound domain and expect a successful load.
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+    [delegate waitForDidFinishNavigation];
+    
+    // Now try to load a non-app bound domain and make sure it fails.
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+    [webView loadRequest:request];
+    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+    EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+
+    // Make sure the load didn't complete by checking the background color.
+    // Red would indicate it finished loading.
+    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
+    cleanUpInAppBrowserPrivacyTestSettings();
+}
+
+TEST(InAppBrowserPrivacy, AppBoundDomainWithoutFlagTreatedAsNonAppBound)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+    
+    // Navigate to an app-bound domain and expect a successful load.
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+    [delegate waitForDidFinishNavigation];
+
+    // But the navigation should not have been considered app-bound because the WebView configuration
+    // specification was not set.
+    isDone = false;
+    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+        EXPECT_FALSE(isAppBound);
+        cleanUpInAppBrowserPrivacyTestSettings();
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+}
+
+TEST(InAppBrowserPrivacy, WebViewWithoutAppBoundFlagCanFreelyNavigate)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+    
+    // Navigate to an app-bound domain and expect a successful load.
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+    [delegate waitForDidFinishNavigation];
+
+    isDone = false;
+    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+        EXPECT_FALSE(isAppBound);
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+
+    // Navigate to an non app-bound domain and expect a successful load.
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+    [webView loadRequest:request];
+    [delegate waitForDidFinishNavigation];
+    
+    isDone = false;
+    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+        EXPECT_FALSE(isAppBound);
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+
+    // Navigation should be successful, but this WebView should not get app-bound domain
+    // privileges like user style sheets.
+    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
+    cleanUpInAppBrowserPrivacyTestSettings();
+}
+
+TEST(InAppBrowserPrivacy, WebViewCannotUpdateAppBoundFlagOnceSet)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+    isDone = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+    [configuration setLimitsNavigationsToAppBoundDomains:YES];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+    auto delegate = adoptNS([AppBoundDomainDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+    
+    // Navigate to an app-bound domain and expect a successful load.
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+    [delegate waitForDidFinishNavigation];
+
+    isDone = false;
+    [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+        EXPECT_TRUE(isAppBound);
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+
+    [[webView configuration] setLimitsNavigationsToAppBoundDomains:NO];
+    // Now try to load a non-app bound domain and make sure it fails.
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+    [webView loadRequest:request];
+    NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+    EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+
+    cleanUpInAppBrowserPrivacyTestSettings();
+}
+
 #endif // USE(APPLE_INTERNAL_SDK)
 
 #endif // PLATFORM(IOS_FAMILY)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to