1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/command_line.h" 6 #include "base/prefs/pref_service.h" 7 #include "base/strings/utf_string_conversions.h" 8 #include "base/values.h" 9 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/common/cancelable_request.h" 11 #include "chrome/browser/history/history_service_factory.h" 12 #include "chrome/browser/infobars/confirm_infobar_delegate.h" 13 #include "chrome/browser/infobars/infobar.h" 14 #include "chrome/browser/infobars/infobar_service.h" 15 #include "chrome/browser/managed_mode/managed_mode_interstitial.h" 16 #include "chrome/browser/managed_mode/managed_mode_navigation_observer.h" 17 #include "chrome/browser/managed_mode/managed_user_constants.h" 18 #include "chrome/browser/managed_mode/managed_user_service.h" 19 #include "chrome/browser/managed_mode/managed_user_service_factory.h" 20 #include "chrome/browser/managed_mode/managed_user_settings_service.h" 21 #include "chrome/browser/managed_mode/managed_user_settings_service_factory.h" 22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/ui/browser.h" 24 #include "chrome/browser/ui/browser_navigator.h" 25 #include "chrome/browser/ui/tabs/tab_strip_model.h" 26 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/pref_names.h" 28 #include "chrome/test/base/in_process_browser_test.h" 29 #include "chrome/test/base/ui_test_utils.h" 30 #include "components/user_prefs/pref_registry_syncable.h" 31 #include "content/public/browser/interstitial_page.h" 32 #include "content/public/browser/navigation_controller.h" 33 #include "content/public/browser/navigation_entry.h" 34 #include "content/public/browser/notification_service.h" 35 #include "content/public/browser/web_contents.h" 36 #include "content/public/browser/web_contents_observer.h" 37 #include "content/public/test/browser_test_utils.h" 38 #include "grit/generated_resources.h" 39 #include "ui/base/l10n/l10n_util.h" 40 41 using content::InterstitialPage; 42 using content::NavigationController; 43 using content::NavigationEntry; 44 using content::WebContents; 45 46 namespace { 47 48 // Tests the filter mode in which all sites are blocked by default. 49 class ManagedModeBlockModeTest : public InProcessBrowserTest { 50 public: 51 // Indicates whether the interstitial should proceed or not. 52 enum InterstitialAction { 53 INTERSTITIAL_PROCEED, 54 INTERSTITIAL_DONTPROCEED, 55 }; 56 57 ManagedModeBlockModeTest() : managed_user_service_(NULL) {} 58 virtual ~ManagedModeBlockModeTest() {} 59 60 void CheckShownPageIsInterstitial(WebContents* tab) { 61 CheckShownPage(tab, content::PAGE_TYPE_INTERSTITIAL); 62 } 63 64 void CheckShownPageIsNotInterstitial(WebContents* tab) { 65 CheckShownPage(tab, content::PAGE_TYPE_NORMAL); 66 } 67 68 // Checks to see if the type of the current page is |page_type|. 69 void CheckShownPage(WebContents* tab, content::PageType page_type) { 70 ASSERT_FALSE(tab->IsCrashed()); 71 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 72 ASSERT_TRUE(entry); 73 ASSERT_EQ(page_type, entry->GetPageType()); 74 } 75 76 void SendAccessRequest(WebContents* tab) { 77 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 78 ASSERT_TRUE(interstitial_page); 79 80 // Get the ManagedModeInterstitial delegate. 81 content::InterstitialPageDelegate* delegate = 82 interstitial_page->GetDelegateForTesting(); 83 84 // Simulate the click on the "request" button. 85 delegate->CommandReceived("\"request\""); 86 } 87 88 void GoBack(WebContents* tab) { 89 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 90 ASSERT_TRUE(interstitial_page); 91 92 // Get the ManagedModeInterstitial delegate. 93 content::InterstitialPageDelegate* delegate = 94 interstitial_page->GetDelegateForTesting(); 95 96 // Simulate the click on the "back" button. 97 delegate->CommandReceived("\"back\""); 98 } 99 100 protected: 101 virtual void SetUpOnMainThread() OVERRIDE { 102 // Set up the ManagedModeNavigationObserver manually since the profile was 103 // not managed when the browser was created. 104 content::WebContents* web_contents = 105 browser()->tab_strip_model()->GetActiveWebContents(); 106 ManagedModeNavigationObserver::CreateForWebContents(web_contents); 107 108 Profile* profile = browser()->profile(); 109 managed_user_service_ = ManagedUserServiceFactory::GetForProfile(profile); 110 ManagedUserSettingsService* managed_user_settings_service = 111 ManagedUserSettingsServiceFactory::GetForProfile(profile); 112 managed_user_settings_service->SetLocalSettingForTesting( 113 managed_users::kContentPackDefaultFilteringBehavior, 114 scoped_ptr<base::Value>( 115 new base::FundamentalValue(ManagedModeURLFilter::BLOCK))); 116 } 117 118 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 119 // Enable the test server and remap all URLs to it. 120 ASSERT_TRUE(test_server()->Start()); 121 std::string host_port = test_server()->host_port_pair().ToString(); 122 command_line->AppendSwitchASCII(switches::kHostResolverRules, 123 "MAP *.example.com " + host_port + "," + 124 "MAP *.new-example.com " + host_port + "," + 125 "MAP *.a.com " + host_port); 126 127 command_line->AppendSwitchASCII(switches::kManagedUserId, "asdf"); 128 } 129 130 // Acts like a synchronous call to history's QueryHistory. Modified from 131 // history_querying_unittest.cc. 132 void QueryHistory(HistoryService* history_service, 133 const std::string& text_query, 134 const history::QueryOptions& options, 135 history::QueryResults* results) { 136 CancelableRequestConsumer history_request_consumer; 137 base::RunLoop run_loop; 138 history_service->QueryHistory( 139 UTF8ToUTF16(text_query), 140 options, 141 &history_request_consumer, 142 base::Bind(&ManagedModeBlockModeTest::QueryHistoryComplete, 143 base::Unretained(this), 144 results, 145 &run_loop)); 146 run_loop.Run(); // Will go until ...Complete calls Quit. 147 } 148 149 void QueryHistoryComplete(history::QueryResults* new_results, 150 base::RunLoop* run_loop, 151 HistoryService::Handle /* handle */, 152 history::QueryResults* results) { 153 results->Swap(new_results); 154 run_loop->Quit(); // Will return out to QueryHistory. 155 } 156 157 ManagedUserService* managed_user_service_; 158 }; 159 160 // Navigates to a blocked URL. 161 IN_PROC_BROWSER_TEST_F(ManagedModeBlockModeTest, 162 SendAccessRequestOnBlockedURL) { 163 GURL test_url("http://www.example.com/files/simple.html"); 164 ui_test_utils::NavigateToURL(browser(), test_url); 165 166 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 167 168 CheckShownPageIsInterstitial(tab); 169 170 SendAccessRequest(tab); 171 172 // TODO(sergiu): Properly check that the access request was sent here. 173 174 GoBack(tab); 175 176 CheckShownPageIsNotInterstitial(tab); 177 } 178 179 // Tests whether a visit attempt adds a special history entry. 180 IN_PROC_BROWSER_TEST_F(ManagedModeBlockModeTest, 181 HistoryVisitRecorded) { 182 GURL allowed_url("http://www.example.com/files/simple.html"); 183 184 // Set the host as allowed. 185 scoped_ptr<DictionaryValue> dict(new DictionaryValue); 186 dict->SetBooleanWithoutPathExpansion(allowed_url.host(), true); 187 ManagedUserSettingsService* managed_user_settings_service = 188 ManagedUserSettingsServiceFactory::GetForProfile( 189 browser()->profile()); 190 managed_user_settings_service->SetLocalSettingForTesting( 191 managed_users::kContentPackManualBehaviorHosts, dict.PassAs<Value>()); 192 EXPECT_EQ( 193 ManagedUserService::MANUAL_ALLOW, 194 managed_user_service_->GetManualBehaviorForHost(allowed_url.host())); 195 196 ui_test_utils::NavigateToURL(browser(), allowed_url); 197 198 // Navigate to it and check that we don't get an interstitial. 199 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 200 CheckShownPageIsNotInterstitial(tab); 201 202 // Navigate to a blocked page and go back on the interstitial. 203 GURL blocked_url("http://www.new-example.com/files/simple.html"); 204 ui_test_utils::NavigateToURL(browser(), blocked_url); 205 206 tab = browser()->tab_strip_model()->GetActiveWebContents(); 207 208 CheckShownPageIsInterstitial(tab); 209 GoBack(tab); 210 211 // Check that we went back to the first URL and that the manual behaviors 212 // have not changed. 213 EXPECT_EQ(allowed_url.spec(), tab->GetURL().spec()); 214 EXPECT_EQ(ManagedUserService::MANUAL_ALLOW, 215 managed_user_service_->GetManualBehaviorForHost("www.example.com")); 216 EXPECT_EQ( 217 ManagedUserService::MANUAL_NONE, 218 managed_user_service_->GetManualBehaviorForHost("www.new-example.com")); 219 220 // Query the history entry. 221 HistoryService* history_service = HistoryServiceFactory::GetForProfile( 222 browser()->profile(), Profile::EXPLICIT_ACCESS); 223 history::QueryOptions options; 224 history::QueryResults results; 225 QueryHistory(history_service, "", options, &results); 226 227 // Check that the entries have the correct blocked_visit value. 228 ASSERT_EQ(2u, results.size()); 229 EXPECT_EQ(blocked_url.spec(), results[0].url().spec()); 230 EXPECT_TRUE(results[0].blocked_visit()); 231 EXPECT_EQ(allowed_url.spec(), results[1].url().spec()); 232 EXPECT_FALSE(results[1].blocked_visit()); 233 } 234 235 IN_PROC_BROWSER_TEST_F(ManagedModeBlockModeTest, Unblock) { 236 GURL test_url("http://www.example.com/files/simple.html"); 237 ui_test_utils::NavigateToURL(browser(), test_url); 238 239 WebContents* web_contents = 240 browser()->tab_strip_model()->GetActiveWebContents(); 241 242 CheckShownPageIsInterstitial(web_contents); 243 244 content::WindowedNotificationObserver observer( 245 content::NOTIFICATION_LOAD_STOP, 246 content::NotificationService::AllSources()); 247 248 // Set the host as allowed. 249 scoped_ptr<DictionaryValue> dict(new DictionaryValue); 250 dict->SetBooleanWithoutPathExpansion(test_url.host(), true); 251 ManagedUserSettingsService* managed_user_settings_service = 252 ManagedUserSettingsServiceFactory::GetForProfile( 253 browser()->profile()); 254 managed_user_settings_service->SetLocalSettingForTesting( 255 managed_users::kContentPackManualBehaviorHosts, dict.PassAs<Value>()); 256 EXPECT_EQ( 257 ManagedUserService::MANUAL_ALLOW, 258 managed_user_service_->GetManualBehaviorForHost(test_url.host())); 259 260 observer.Wait(); 261 EXPECT_EQ(test_url, web_contents->GetURL()); 262 } 263 264 } // namespace 265