Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5937)

Unified Diff: chrome/browser/ui/login/login_prompt_browsertest.cc

Issue 1368863002: Set SSL info when an HTTP auth dialog is triggered by direct navigation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fill in the rest of entry->GetSSL(). Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/login/login_prompt_browsertest.cc
diff --git a/chrome/browser/ui/login/login_prompt_browsertest.cc b/chrome/browser/ui/login/login_prompt_browsertest.cc
index a284438c112e559c06aae0cd86dc0fcc49d1feb5..acc8bc92a59737706867696bcf76e44122ee1c44 100644
--- a/chrome/browser/ui/login/login_prompt_browsertest.cc
+++ b/chrome/browser/ui/login/login_prompt_browsertest.cc
@@ -7,6 +7,7 @@
#include <map>
#include "base/metrics/field_trial.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/prerender/prerender_manager.h"
@@ -20,12 +21,15 @@
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/interstitial_page.h"
+#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/ssl_status.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/base/auth.h"
+#include "net/base/filename_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
@@ -35,6 +39,8 @@ using content::Referrer;
namespace {
+enum ExpectedSSLStatus { SSL_STATUS_NONE, SSL_STATUS_OK, SSL_STATUS_BROKEN };
+
class LoginPromptBrowserTest : public InProcessBrowserTest {
public:
LoginPromptBrowserTest()
@@ -62,11 +68,16 @@ class LoginPromptBrowserTest : public InProcessBrowserTest {
typedef std::map<std::string, AuthInfo> AuthMap;
- void SetAuthFor(LoginHandler* handler);
+ void SetAuthFor(LoginHandler* handler) const;
void TestCrossOriginPrompt(const GURL& visit_url,
const std::string& landing_host) const;
+ void TestSSLState(Browser* browser,
+ const GURL& test_page,
+ bool has_redirect,
+ int expected_ssl_status) const;
+
AuthMap auth_map_;
std::string bad_password_;
std::string bad_username_;
@@ -75,11 +86,11 @@ class LoginPromptBrowserTest : public InProcessBrowserTest {
std::string username_digest_;
};
-void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) {
+void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) const {
const net::AuthChallengeInfo* challenge = handler->auth_info();
ASSERT_TRUE(challenge);
- AuthMap::iterator i = auth_map_.find(challenge->realm);
+ AuthMap::const_iterator i = auth_map_.find(challenge->realm);
EXPECT_TRUE(auth_map_.end() != i);
if (i != auth_map_.end()) {
const AuthInfo& info = i->second;
@@ -88,6 +99,32 @@ void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) {
}
}
+void CheckSSLState(content::WebContents* contents, int expected_ssl_status) {
+ NavigationController* controller = &contents->GetController();
+ content::NavigationEntry* entry = controller->GetVisibleEntry();
+ const content::SSLStatus& ssl_status = entry->GetSSL();
+ EXPECT_EQ(content::SSLStatus::NORMAL_CONTENT, ssl_status.content_status);
+ EXPECT_EQ(128, ssl_status.security_bits);
+ switch (expected_ssl_status) {
+ case SSL_STATUS_OK:
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED,
+ ssl_status.security_style);
+ break;
+ case SSL_STATUS_BROKEN:
+ EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN,
+ ssl_status.security_style);
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void CancelAndWaitForInterstitialDetach(LoginHandler* handler,
+ content::WebContents* contents) {
+ RunTaskAndWaitForInterstitialDetach(
+ contents, base::Bind(&LoginHandler::CancelAuth, handler));
+}
+
const char kPrefetchAuthPage[] = "files/login/prefetch.html";
const char kMultiRealmTestPage[] = "files/login/multi_realm.html";
@@ -1375,4 +1412,155 @@ IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest,
}
}
+// Navigates the active tab to |test_page| which should end up at a URL with
+// HTTP auth, and checks if the SSL information at this final URL is set
+// correctly.
+// If |has_redirect| is true, |test_page| redirects to the HTTP auth URL.
+// If |has_redirect| is false, |test_page| is the final HTTP auth URL.
+void LoginPromptBrowserTest::TestSSLState(Browser* browser,
+ const GURL& test_page,
+ bool has_redirect,
+ int expected_ssl_status) const {
+ content::WebContents* contents =
+ browser->tab_strip_model()->GetActiveWebContents();
+ NavigationController* controller = &contents->GetController();
+ LoginPromptBrowserTestObserver observer;
+
+ observer.Register(content::Source<NavigationController>(controller));
+ {
+ WindowedAuthNeededObserver auth_needed_waiter(controller);
+ ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
+ browser, test_page, has_redirect ? 2 : 1);
+ // After redirects etc., the page should end up at the HTTPS url.
+ ASSERT_EQ("127.0.0.1", contents->GetURL().host());
+ if (expected_ssl_status == SSL_STATUS_BROKEN) {
+ // Wait for the broken SSL interstitial and proceed through it.
+ WaitForInterstitialAttach(contents);
+ EXPECT_TRUE(contents->ShowingInterstitialPage());
+ EXPECT_EQ(SSLBlockingPage::kTypeForTesting,
+ contents->GetInterstitialPage()
+ ->GetDelegateForTesting()
+ ->GetTypeForTesting());
+ contents->GetInterstitialPage()->Proceed();
+ }
+
+ // The auth prompt should show with the blank login interstitial, and the
+ // SSL status should be available (but broken).
+ auth_needed_waiter.Wait();
+ ASSERT_EQ(1u, observer.handlers().size());
+ WaitForInterstitialAttach(contents);
+ EXPECT_TRUE(contents->ShowingInterstitialPage());
+ EXPECT_EQ(LoginInterstitialDelegate::kTypeForTesting,
+ contents->GetInterstitialPage()
+ ->GetDelegateForTesting()
+ ->GetTypeForTesting());
+ // Navigation not committed yet when the auth dialog is displayed.
+ EXPECT_EQ("", contents->GetLastCommittedURL().host());
+ EXPECT_EQ("127.0.0.1", contents->GetVisibleURL().host());
+ CheckSSLState(contents, expected_ssl_status);
+
+ // Cancelling the login prompt should detach the interstitial while keeping
+ // the correct origin and SSL state.
+ CancelAndWaitForInterstitialDetach(*observer.handlers().begin(), contents);
+ EXPECT_EQ("127.0.0.1", contents->GetVisibleURL().host());
+ EXPECT_EQ("127.0.0.1", contents->GetLastCommittedURL().host());
+ EXPECT_FALSE(contents->ShowingInterstitialPage());
+ CheckSSLState(contents, expected_ssl_status);
+ }
+}
+
+// Omnibox and connection tab should reflect the correct SSL State when login
+// prompt is displayed in the main frame.
+// This is simply the scenario where the user enters an HTTPS url that ends up
+// with an HTTP auth dialog.
+IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest,
+ SSLStateShouldUpdateOnDirectNavigation) {
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::SSLOptions(
+ net::SpawnedTestServer::SSLOptions::CERT_OK),
+ base::FilePath());
+ ASSERT_TRUE(https_server.Start());
+ GURL test_page = https_server.GetURL(kAuthBasicPage);
+ ASSERT_EQ("127.0.0.1", test_page.host());
+ TestSSLState(browser(), test_page, false, SSL_STATUS_OK);
+}
+
+// Same as above, except the HTTPS url has a cert error. When the user proceeds
+// through the SSL interstitial, HTTP auth dialog should be displayed with the
+// correct (i.e. broken) SSL information.
+IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest,
+ SSLStateShouldUpdateOnDirectNavigation_BrokenSSL) {
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::SSLOptions(
+ net::SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT),
+ base::FilePath());
+ ASSERT_TRUE(https_server.Start());
+ GURL test_page = https_server.GetURL(kAuthBasicPage);
+ ASSERT_EQ("127.0.0.1", test_page.host());
+ TestSSLState(browser(), test_page, false, SSL_STATUS_BROKEN);
+}
+
+// Same as |SSLStateShouldUpdateOnDirectNavigation|, except the user doesn't
+// navigate directly to the HTTPS page. Instead, another page redirects to the
+// HTTPS page.
+IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, SSLStateShouldUpdateOnRedirect) {
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::SSLOptions(
+ net::SpawnedTestServer::SSLOptions::CERT_OK),
+ base::FilePath());
+ ASSERT_TRUE(https_server.Start());
+ GURL https_url = https_server.GetURL(kAuthBasicPage);
+ ASSERT_EQ("127.0.0.1", https_url.host());
+
+ // Write an HTML file that redirects to the HTTPS url above.
+ base::ScopedTempDir temp_directory;
+ ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
+ base::FilePath temp_file;
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_directory.path(), &temp_file));
+ std::string html = base::StringPrintf(
+ "<html>"
+ "<script>window.location = '%s';</script>"
+ "</html>",
+ https_url.spec().c_str());
+ ASSERT_EQ(static_cast<int>(html.size()),
+ base::WriteFile(temp_file, html.data(), html.size()));
+ TestSSLState(browser(), net::FilePathToFileURL(temp_file), true,
+ SSL_STATUS_OK);
+}
+
+// Same as |SSLStateShouldUpdateOnDirectNavigation_BrokenSSL|, except the user
+// doesn't navigate directly to the HTTPS page. Instead, another page redirects
+// to the HTTPS page.
+IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest,
+ SSLStateShouldUpdateOnRedirect_BrokenSSL) {
+ net::SpawnedTestServer https_server(
+ net::SpawnedTestServer::TYPE_HTTPS,
+ net::SpawnedTestServer::SSLOptions(
+ net::SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT),
+ base::FilePath());
+ ASSERT_TRUE(https_server.Start());
+ GURL https_url = https_server.GetURL(kAuthBasicPage);
+ ASSERT_EQ("127.0.0.1", https_url.host());
+
+ // Write an HTML file that redirects to the HTTPS url above.
+ base::ScopedTempDir temp_directory;
+ ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
+ base::FilePath temp_file;
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_directory.path(), &temp_file));
+ std::string html = base::StringPrintf(
+ "<html>"
+ "<script>window.location = '%s';</script>"
+ "</html>",
+ https_url.spec().c_str());
+ ASSERT_EQ(static_cast<int>(html.size()),
+ base::WriteFile(temp_file, html.data(), html.size()));
+ TestSSLState(browser(), net::FilePathToFileURL(temp_file), true,
+ SSL_STATUS_BROKEN);
+}
+
} // namespace

Powered by Google App Engine
This is Rietveld 408576698