blob: 00bc1a9daaef36c43c000fb8a0ce58f559803345 [file] [log] [blame]
// Copyright 2015 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 "chrome/browser/ssl/captive_portal_blocking_page.h"
#include <string>
#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/prefs/pref_service.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/captive_portal/captive_portal_detector.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using chrome_browser_interstitials::IsInterstitialDisplayingText;
using chrome_browser_interstitials::SecurityInterstitialIDNTest;
namespace {
// Partial text in the captive portal interstitial's main paragraph when the
// login domain isn't displayed.
const char kGenericLoginURLText[] = "its login page";
const char kBrokenSSL[] = "https://broken.ssl";
const char kWiFiSSID[] = "WiFiSSID";
enum ExpectWiFi {
EXPECT_WIFI_NO,
EXPECT_WIFI_YES
};
enum ExpectWiFiSSID {
EXPECT_WIFI_SSID_NO,
EXPECT_WIFI_SSID_YES
};
enum ExpectLoginURL {
EXPECT_LOGIN_URL_NO,
EXPECT_LOGIN_URL_YES
};
} // namespace
class FakeConnectionInfoDelegate : public CaptivePortalBlockingPage::Delegate {
public:
FakeConnectionInfoDelegate(bool is_wifi_connection, std::string wifi_ssid)
: is_wifi_connection_(is_wifi_connection), wifi_ssid_(wifi_ssid) {}
~FakeConnectionInfoDelegate() override {}
bool IsWifiConnection() const override { return is_wifi_connection_; }
std::string GetWiFiSSID() const override { return wifi_ssid_; }
private:
const bool is_wifi_connection_;
const std::string wifi_ssid_;
DISALLOW_COPY_AND_ASSIGN(FakeConnectionInfoDelegate);
};
class CaptivePortalBlockingPageTest : public InProcessBrowserTest {
public:
CaptivePortalBlockingPageTest() {}
void TestInterstitial(bool is_wifi_connection,
const std::string& wifi_ssid,
const GURL& login_url,
ExpectWiFi expect_wifi,
ExpectWiFiSSID expect_wifi_ssid,
ExpectLoginURL expect_login_url,
const std::string& expected_login_hostname);
void TestInterstitial(bool is_wifi_connection,
const std::string& wifi_ssid,
const GURL& login_url,
ExpectWiFi expect_wifi,
ExpectWiFiSSID expect_wifi_ssid,
ExpectLoginURL expect_login_url);
private:
DISALLOW_COPY_AND_ASSIGN(CaptivePortalBlockingPageTest);
};
void CaptivePortalBlockingPageTest::TestInterstitial(
bool is_wifi_connection,
const std::string& wifi_ssid,
const GURL& login_url,
ExpectWiFi expect_wifi,
ExpectWiFiSSID expect_wifi_ssid,
ExpectLoginURL expect_login_url,
const std::string& expected_login_hostname) {
content::WebContents* contents =
browser()->tab_strip_model()->GetActiveWebContents();
DCHECK(contents);
// Delegate is owned by the blocking page.
FakeConnectionInfoDelegate* delegate =
new FakeConnectionInfoDelegate(is_wifi_connection, wifi_ssid);
// Blocking page is owned by the interstitial.
CaptivePortalBlockingPage* blocking_page = new CaptivePortalBlockingPage(
contents, GURL(kBrokenSSL), login_url, base::Callback<void(bool)>());
blocking_page->SetDelegateForTesting(delegate);
blocking_page->Show();
WaitForInterstitialAttach(contents);
EXPECT_TRUE(
WaitForRenderFrameReady(contents->GetInterstitialPage()->GetMainFrame()));
EXPECT_EQ(expect_wifi == EXPECT_WIFI_YES,
IsInterstitialDisplayingText(contents->GetInterstitialPage(),
"Wi-Fi"));
if (!wifi_ssid.empty()) {
EXPECT_EQ(expect_wifi_ssid == EXPECT_WIFI_SSID_YES,
IsInterstitialDisplayingText(contents->GetInterstitialPage(),
wifi_ssid));
}
EXPECT_EQ(expect_login_url == EXPECT_LOGIN_URL_YES,
IsInterstitialDisplayingText(contents->GetInterstitialPage(),
expected_login_hostname));
EXPECT_EQ(expect_login_url == EXPECT_LOGIN_URL_NO,
IsInterstitialDisplayingText(contents->GetInterstitialPage(),
kGenericLoginURLText));
}
void CaptivePortalBlockingPageTest::TestInterstitial(
bool is_wifi_connection,
const std::string& wifi_ssid,
const GURL& login_url,
ExpectWiFi expect_wifi,
ExpectWiFiSSID expect_wifi_ssid,
ExpectLoginURL expect_login_url) {
TestInterstitial(is_wifi_connection, wifi_ssid, login_url,
expect_wifi, expect_wifi_ssid, expect_login_url,
login_url.host());
}
// If the connection is not a Wi-Fi connection, the wired network version of the
// captive portal interstitial should be displayed.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiredNetwork_LoginURL) {
TestInterstitial(false, "", GURL("http://captive.portal/landing_url"),
EXPECT_WIFI_NO, EXPECT_WIFI_SSID_NO, EXPECT_LOGIN_URL_YES);
}
// Same as above, but SSID is available, so the connection should be assumed to
// be Wi-Fi.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiredNetwork_LoginURL_With_SSID) {
TestInterstitial(false, kWiFiSSID, GURL("http://captive.portal/landing_url"),
EXPECT_WIFI_YES, EXPECT_WIFI_SSID_YES, EXPECT_LOGIN_URL_YES);
}
// Same as above, expect the login URL is the same as the captive portal ping
// url (i.e. the portal intercepts requests without using HTTP redirects), in
// which case the login URL shouldn't be displayed.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiredNetwork_NoLoginURL) {
const GURL kLandingUrl(captive_portal::CaptivePortalDetector::kDefaultURL);
TestInterstitial(false, "", kLandingUrl, EXPECT_WIFI_NO, EXPECT_WIFI_SSID_NO,
EXPECT_LOGIN_URL_NO);
}
// Same as above, but SSID is available, so the connection should be assumed to
// be Wi-Fi.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiredNetwork_NoLoginURL_With_SSID) {
const GURL kLandingUrl(captive_portal::CaptivePortalDetector::kDefaultURL);
TestInterstitial(false, kWiFiSSID, kLandingUrl, EXPECT_WIFI_YES,
EXPECT_WIFI_SSID_YES, EXPECT_LOGIN_URL_NO);
}
// If the connection is a Wi-Fi connection, the Wi-Fi version of the captive
// portal interstitial should be displayed.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiFi_SSID_LoginURL) {
TestInterstitial(true, kWiFiSSID, GURL("http://captive.portal/landing_url"),
EXPECT_WIFI_YES, EXPECT_WIFI_SSID_YES, EXPECT_LOGIN_URL_YES);
}
// Same as above, with login URL but no SSID.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiFi_NoSSID_LoginURL) {
TestInterstitial(true, "", GURL("http://captive.portal/landing_url"),
EXPECT_WIFI_YES, EXPECT_WIFI_SSID_NO, EXPECT_LOGIN_URL_YES);
}
// Same as above, with SSID but no login URL.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiFi_SSID_NoLoginURL) {
const GURL kLandingUrl(captive_portal::CaptivePortalDetector::kDefaultURL);
TestInterstitial(true, kWiFiSSID, kLandingUrl,
EXPECT_WIFI_YES, EXPECT_WIFI_SSID_YES, EXPECT_LOGIN_URL_NO);
}
// Same as above, with no SSID and no login URL.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest,
WiFi_NoSSID_NoLoginURL) {
const GURL kLandingUrl(captive_portal::CaptivePortalDetector::kDefaultURL);
TestInterstitial(true, "", kLandingUrl,
EXPECT_WIFI_YES, EXPECT_WIFI_SSID_NO, EXPECT_LOGIN_URL_NO);
}
class CaptivePortalBlockingPageIDNTest : public SecurityInterstitialIDNTest {
protected:
// SecurityInterstitialIDNTest implementation
SecurityInterstitialPage* CreateInterstitial(
content::WebContents* contents,
const GURL& request_url) const override {
// Delegate is owned by the blocking page.
FakeConnectionInfoDelegate* delegate =
new FakeConnectionInfoDelegate(false, "");
// Blocking page is owned by the interstitial.
CaptivePortalBlockingPage* blocking_page = new CaptivePortalBlockingPage(
contents, GURL(kBrokenSSL), request_url, base::Callback<void(bool)>());
blocking_page->SetDelegateForTesting(delegate);
return blocking_page;
}
};
// Test that an IDN login domain is decoded properly.
IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageIDNTest,
ShowLoginIDNIfPortalRedirectsDetectionURL) {
EXPECT_TRUE(VerifyIDNDecoded());
}