Commit e0073fb3 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

[WebLayer] Handle user pressing Reload in SSL interstitials

The RELOAD command is currently not handled in the //weblayer SSL
implementation. However, this command can be triggered by the user:
e.g., go to badssl.com and click on the "MITM" button; the resulting
interstitial will have a Reload button.

This CL wires up handling of this command.

Bug: 1023856
Change-Id: Ib2b2fae52066bb26fbed8d895ad1b75d7295b7b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1914384
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715641}
parent 0d5057b8
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
#include "weblayer/shell/browser/shell.h" #include "weblayer/shell/browser/shell.h"
#include "weblayer/test/interstitial_utils.h" #include "weblayer/test/interstitial_utils.h"
#include "weblayer/test/load_completion_observer.h"
#include "weblayer/test/test_navigation_observer.h" #include "weblayer/test/test_navigation_observer.h"
#include "weblayer/test/weblayer_browser_test_utils.h" #include "weblayer/test/weblayer_browser_test_utils.h"
...@@ -75,11 +76,13 @@ class SSLBrowserTest : public WebLayerBrowserTest { ...@@ -75,11 +76,13 @@ class SSLBrowserTest : public WebLayerBrowserTest {
// ssl_browsertest.cc's CheckAuthenticationBrokenState() function. // ssl_browsertest.cc's CheckAuthenticationBrokenState() function.
} }
void InteractWithBlockingPage( void SendInterstitialNavigationCommandAndWait(
bool proceed, bool proceed,
base::Optional<GURL> previous_url = base::nullopt) { base::Optional<GURL> previous_url = base::nullopt) {
GURL expected_url = GURL expected_url =
proceed ? bad_ssl_url() : previous_url.value_or(ok_url()); proceed ? bad_ssl_url() : previous_url.value_or(ok_url());
ASSERT_TRUE(IsShowingSSLInterstitial(shell()->tab()));
TestNavigationObserver navigation_observer( TestNavigationObserver navigation_observer(
expected_url, TestNavigationObserver::NavigationEvent::Completion, expected_url, TestNavigationObserver::NavigationEvent::Completion,
shell()); shell());
...@@ -91,6 +94,19 @@ class SSLBrowserTest : public WebLayerBrowserTest { ...@@ -91,6 +94,19 @@ class SSLBrowserTest : public WebLayerBrowserTest {
EXPECT_FALSE(IsShowingSSLInterstitial(shell()->tab())); EXPECT_FALSE(IsShowingSSLInterstitial(shell()->tab()));
} }
void SendInterstitialReloadCommandAndWait() {
ASSERT_TRUE(IsShowingSSLInterstitial(shell()->tab()));
LoadCompletionObserver load_observer(shell());
ExecuteScript(shell(), "window.certificateErrorPageController.reload();",
false /*use_separate_isolate*/);
load_observer.Wait();
// Should still be showing the SSL interstitial after the reload command is
// processed.
EXPECT_TRUE(IsShowingSSLInterstitial(shell()->tab()));
}
void NavigateToOtherOkPage() { void NavigateToOtherOkPage() {
NavigateAndWaitForCompletion(https_server_->GetURL("/simple_page2.html"), NavigateAndWaitForCompletion(https_server_->GetURL("/simple_page2.html"),
shell()); shell());
...@@ -116,7 +132,7 @@ IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBack) { ...@@ -116,7 +132,7 @@ IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBack) {
NavigateToPageWithSslErrorExpectBlocked(); NavigateToPageWithSslErrorExpectBlocked();
// Click "Take me back". // Click "Take me back".
InteractWithBlockingPage(false /*proceed*/); SendInterstitialNavigationCommandAndWait(false /*proceed*/);
// Check that it's possible to navigate to a new page. // Check that it's possible to navigate to a new page.
NavigateToOtherOkPage(); NavigateToOtherOkPage();
...@@ -132,7 +148,25 @@ IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBackEmptyNavigationHistory) { ...@@ -132,7 +148,25 @@ IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBackEmptyNavigationHistory) {
NavigateToPageWithSslErrorExpectBlocked(); NavigateToPageWithSslErrorExpectBlocked();
// Click "Take me back". // Click "Take me back".
InteractWithBlockingPage(false /*proceed*/, GURL("about:blank")); SendInterstitialNavigationCommandAndWait(false /*proceed*/,
GURL("about:blank"));
}
IN_PROC_BROWSER_TEST_F(SSLBrowserTest, Reload) {
NavigateToOkPage();
NavigateToPageWithSslErrorExpectBlocked();
SendInterstitialReloadCommandAndWait();
// TODO(blundell): Ideally we would fix the SSL error, reload, and verify
// that the SSL interstitial isn't showing. However, currently this doesn't
// work: Calling ResetSSLConfig() on |http_server_mismatched_| passing
// CERT_OK does not cause future reloads or navigations to bad_ssl_url() to
// succeed; they still fail and pop an interstitial. I verified that the
// LoadCompletionObserver is in fact waiting for a new load, i.e., there is
// actually a *new* SSL interstitial popped up. From looking at the
// ResetSSLConfig() impl there shouldn't be any waiting or anything needed
// within the client.
} }
// Tests clicking proceed link on the interstitial page. This is a PRE_ test // Tests clicking proceed link on the interstitial page. This is a PRE_ test
...@@ -141,7 +175,7 @@ IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBackEmptyNavigationHistory) { ...@@ -141,7 +175,7 @@ IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBackEmptyNavigationHistory) {
IN_PROC_BROWSER_TEST_F(SSLBrowserTest, PRE_Proceed) { IN_PROC_BROWSER_TEST_F(SSLBrowserTest, PRE_Proceed) {
NavigateToOkPage(); NavigateToOkPage();
NavigateToPageWithSslErrorExpectBlocked(); NavigateToPageWithSslErrorExpectBlocked();
InteractWithBlockingPage(true /*proceed*/); SendInterstitialNavigationCommandAndWait(true /*proceed*/);
// Go back to an OK page, then try to navigate again. The "Proceed" decision // Go back to an OK page, then try to navigate again. The "Proceed" decision
// should be saved, so no interstitial is shown this time. // should be saved, so no interstitial is shown this time.
......
...@@ -63,8 +63,10 @@ void SSLErrorHelper::SendCommand( ...@@ -63,8 +63,10 @@ void SSLErrorHelper::SendCommand(
case security_interstitials::CMD_OPEN_HELP_CENTER: case security_interstitials::CMD_OPEN_HELP_CENTER:
interface->OpenHelpCenter(); interface->OpenHelpCenter();
break; break;
case security_interstitials::CMD_OPEN_DIAGNOSTIC:
case security_interstitials::CMD_RELOAD: case security_interstitials::CMD_RELOAD:
interface->Reload();
break;
case security_interstitials::CMD_OPEN_DIAGNOSTIC:
case security_interstitials::CMD_OPEN_DATE_SETTINGS: case security_interstitials::CMD_OPEN_DATE_SETTINGS:
case security_interstitials::CMD_OPEN_LOGIN: case security_interstitials::CMD_OPEN_LOGIN:
case security_interstitials::CMD_DO_REPORT: case security_interstitials::CMD_DO_REPORT:
......
...@@ -94,6 +94,8 @@ test("weblayer_browsertests") { ...@@ -94,6 +94,8 @@ test("weblayer_browsertests") {
"browsertests_main.cc", "browsertests_main.cc",
"interstitial_utils.cc", "interstitial_utils.cc",
"interstitial_utils.h", "interstitial_utils.h",
"load_completion_observer.cc",
"load_completion_observer.h",
"test_launcher_delegate_impl.cc", "test_launcher_delegate_impl.cc",
"test_launcher_delegate_impl.h", "test_launcher_delegate_impl.h",
"test_navigation_observer.cc", "test_navigation_observer.cc",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "weblayer/test/load_completion_observer.h"
#include "weblayer/public/navigation_controller.h"
#include "weblayer/public/tab.h"
#include "weblayer/shell/browser/shell.h"
namespace weblayer {
LoadCompletionObserver::LoadCompletionObserver(Shell* shell)
: tab_(shell->tab()) {
tab_->GetNavigationController()->AddObserver(this);
}
LoadCompletionObserver::~LoadCompletionObserver() {
tab_->GetNavigationController()->RemoveObserver(this);
}
void LoadCompletionObserver::LoadStateChanged(bool is_loading,
bool to_different_document) {
if (!is_loading)
run_loop_.Quit();
}
void LoadCompletionObserver::Wait() {
run_loop_.Run();
}
} // namespace weblayer
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBLAYER_TEST_LOAD_COMPLETION_OBSERVER_H_
#define WEBLAYER_TEST_LOAD_COMPLETION_OBSERVER_H_
#include "base/macros.h"
#include "base/run_loop.h"
#include "weblayer/public/navigation_observer.h"
namespace weblayer {
class Shell;
class Tab;
// A helper that waits for the next load to complete.
class LoadCompletionObserver : public NavigationObserver {
public:
// Creates an instance that begins waiting for a load within |shell| to
// complete.
explicit LoadCompletionObserver(Shell* shell);
~LoadCompletionObserver() override;
// Spins a RunLoop until the next load completes.
void Wait();
private:
// NavigationObserver implementation:
void LoadStateChanged(bool is_loading, bool to_different_document) override;
Tab* tab_;
base::RunLoop run_loop_;
DISALLOW_COPY_AND_ASSIGN(LoadCompletionObserver);
};
} // namespace weblayer
#endif // WEBLAYER_TEST_LOAD_COMPLETION_OBSERVER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment