Title: [260918] branches/safari-610.1.11-branch
Revision
260918
Author
[email protected]
Date
2020-04-29 15:13:28 -0700 (Wed, 29 Apr 2020)

Log Message

Cherry-pick r260408. rdar://problem/62617775

    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]):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260408 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-610.1.11-branch/Source/WebKit/ChangeLog (260917 => 260918)


--- branches/safari-610.1.11-branch/Source/WebKit/ChangeLog	2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Source/WebKit/ChangeLog	2020-04-29 22:13:28 UTC (rev 260918)
@@ -1,3 +1,93 @@
+2020-04-29  Alan Coon  <[email protected]>
+
+        Cherry-pick r260408. rdar://problem/62617775
+
+    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]):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260408 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    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-27  Alan Coon  <[email protected]>
 
         Cherry-pick r260763. rdar://problem/62467013

Modified: branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.cpp (260917 => 260918)


--- branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-04-29 22:13:28 UTC (rev 260918)
@@ -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: branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.h (260917 => 260918)


--- branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.h	2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.h	2020-04-29 22:13:28 UTC (rev 260918)
@@ -2303,7 +2303,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: branches/safari-610.1.11-branch/Tools/ChangeLog (260917 => 260918)


--- branches/safari-610.1.11-branch/Tools/ChangeLog	2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Tools/ChangeLog	2020-04-29 22:13:28 UTC (rev 260918)
@@ -1,3 +1,83 @@
+2020-04-29  Alan Coon  <[email protected]>
+
+        Cherry-pick r260408. rdar://problem/62617775
+
+    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]):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260408 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    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-24  Alan Coon  <[email protected]>
 
         Cherry-pick r260486. rdar://problem/62349885

Modified: branches/safari-610.1.11-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (260917 => 260918)


--- branches/safari-610.1.11-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2020-04-29 22:13:28 UTC (rev 260918)
@@ -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