OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/webstore_inline_installer.h" | 5 #include "chrome/browser/extensions/webstore_inline_installer.h" |
6 | 6 |
7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 ProgrammableInstallPrompt::g_done_callback = nullptr; | 111 ProgrammableInstallPrompt::g_done_callback = nullptr; |
112 | 112 |
113 // Fake inline installer which creates a programmable prompt in place of | 113 // Fake inline installer which creates a programmable prompt in place of |
114 // the normal dialog UI. | 114 // the normal dialog UI. |
115 class WebstoreInlineInstallerForTest : public WebstoreInlineInstaller { | 115 class WebstoreInlineInstallerForTest : public WebstoreInlineInstaller { |
116 public: | 116 public: |
117 WebstoreInlineInstallerForTest(WebContents* contents, | 117 WebstoreInlineInstallerForTest(WebContents* contents, |
118 content::RenderFrameHost* host, | 118 content::RenderFrameHost* host, |
119 const std::string& extension_id, | 119 const std::string& extension_id, |
120 const GURL& requestor_url, | 120 const GURL& requestor_url, |
121 const Callback& callback) | 121 const Callback& callback, |
| 122 bool enable_safebrowsing_redirects) |
122 : WebstoreInlineInstaller( | 123 : WebstoreInlineInstaller( |
123 contents, | 124 contents, |
124 host, | 125 host, |
125 kTestExtensionId, | 126 kTestExtensionId, |
126 requestor_url, | 127 requestor_url, |
127 base::Bind(&WebstoreInlineInstallerForTest::InstallCallback, | 128 base::Bind(&WebstoreInlineInstallerForTest::InstallCallback, |
128 base::Unretained(this))), | 129 base::Unretained(this))), |
129 install_result_target_(nullptr), | 130 install_result_target_(nullptr), |
| 131 enable_safebrowsing_redirects_(enable_safebrowsing_redirects), |
130 programmable_prompt_(nullptr) {} | 132 programmable_prompt_(nullptr) {} |
131 | 133 |
132 std::unique_ptr<ExtensionInstallPrompt> CreateInstallUI() override { | 134 std::unique_ptr<ExtensionInstallPrompt> CreateInstallUI() override { |
133 programmable_prompt_ = new ProgrammableInstallPrompt(web_contents()); | 135 programmable_prompt_ = new ProgrammableInstallPrompt(web_contents()); |
134 return base::WrapUnique(programmable_prompt_); | 136 return base::WrapUnique(programmable_prompt_); |
135 } | 137 } |
136 | 138 |
137 // Added here to make it public so that test cases can call it below. | 139 // Added here to make it public so that test cases can call it below. |
138 bool CheckRequestorAlive() const override { | 140 bool CheckRequestorAlive() const override { |
139 return WebstoreInlineInstaller::CheckRequestorAlive(); | 141 return WebstoreInlineInstaller::CheckRequestorAlive(); |
140 } | 142 } |
141 | 143 |
| 144 bool SafeBrowsingNavigationEventsEnabled() const override { |
| 145 return enable_safebrowsing_redirects_; |
| 146 } |
| 147 |
142 // Tests that care about the actual arguments to the install callback can use | 148 // Tests that care about the actual arguments to the install callback can use |
143 // this to receive a copy in |install_result_target|. | 149 // this to receive a copy in |install_result_target|. |
144 void set_install_result_target( | 150 void set_install_result_target( |
145 std::unique_ptr<InstallResult>* install_result_target) { | 151 std::unique_ptr<InstallResult>* install_result_target) { |
146 install_result_target_ = install_result_target; | 152 install_result_target_ = install_result_target; |
147 } | 153 } |
148 | 154 |
149 private: | 155 private: |
150 ~WebstoreInlineInstallerForTest() override {} | 156 ~WebstoreInlineInstallerForTest() override {} |
151 | 157 |
152 friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>; | 158 friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>; |
153 | 159 |
154 void InstallCallback(bool success, | 160 void InstallCallback(bool success, |
155 const std::string& error, | 161 const std::string& error, |
156 webstore_install::Result result) { | 162 webstore_install::Result result) { |
157 if (install_result_target_) { | 163 if (install_result_target_) { |
158 install_result_target_->reset(new InstallResult); | 164 install_result_target_->reset(new InstallResult); |
159 (*install_result_target_)->success = success; | 165 (*install_result_target_)->success = success; |
160 (*install_result_target_)->error = error; | 166 (*install_result_target_)->error = error; |
161 (*install_result_target_)->result = result; | 167 (*install_result_target_)->result = result; |
162 } | 168 } |
163 } | 169 } |
164 | 170 |
165 // This can be set by tests that want to get the actual install callback | 171 // This can be set by tests that want to get the actual install callback |
166 // arguments. | 172 // arguments. |
167 std::unique_ptr<InstallResult>* install_result_target_; | 173 std::unique_ptr<InstallResult>* install_result_target_; |
168 | 174 |
| 175 // This can be set by tests that want to use the new SafeBrowsing redirect |
| 176 // tracker. |
| 177 bool enable_safebrowsing_redirects_; |
| 178 |
169 ProgrammableInstallPrompt* programmable_prompt_; | 179 ProgrammableInstallPrompt* programmable_prompt_; |
170 }; | 180 }; |
171 | 181 |
172 class WebstoreInlineInstallerForTestFactory : | 182 class WebstoreInlineInstallerForTestFactory : |
173 public WebstoreInlineInstallerFactory { | 183 public WebstoreInlineInstallerFactory { |
174 public: | 184 public: |
175 WebstoreInlineInstallerForTestFactory() : last_installer_(nullptr) {} | 185 WebstoreInlineInstallerForTestFactory() |
| 186 : last_installer_(nullptr), enable_safebrowsing_redirects_(false) {} |
| 187 explicit WebstoreInlineInstallerForTestFactory( |
| 188 bool enable_safebrowsing_redirects) |
| 189 : last_installer_(nullptr), |
| 190 enable_safebrowsing_redirects_(enable_safebrowsing_redirects) {} |
176 ~WebstoreInlineInstallerForTestFactory() override {} | 191 ~WebstoreInlineInstallerForTestFactory() override {} |
177 | 192 |
178 WebstoreInlineInstallerForTest* last_installer() { return last_installer_; } | 193 WebstoreInlineInstallerForTest* last_installer() { return last_installer_; } |
179 | 194 |
180 WebstoreInlineInstaller* CreateInstaller( | 195 WebstoreInlineInstaller* CreateInstaller( |
181 WebContents* contents, | 196 WebContents* contents, |
182 content::RenderFrameHost* host, | 197 content::RenderFrameHost* host, |
183 const std::string& webstore_item_id, | 198 const std::string& webstore_item_id, |
184 const GURL& requestor_url, | 199 const GURL& requestor_url, |
185 const WebstoreStandaloneInstaller::Callback& callback) override { | 200 const WebstoreStandaloneInstaller::Callback& callback) override { |
186 last_installer_ = new WebstoreInlineInstallerForTest( | 201 last_installer_ = new WebstoreInlineInstallerForTest( |
187 contents, host, webstore_item_id, requestor_url, callback); | 202 contents, host, webstore_item_id, requestor_url, callback, |
| 203 enable_safebrowsing_redirects_); |
188 return last_installer_; | 204 return last_installer_; |
189 } | 205 } |
190 | 206 |
191 private: | 207 private: |
192 // The last installer that was created. | 208 // The last installer that was created. |
193 WebstoreInlineInstallerForTest* last_installer_; | 209 WebstoreInlineInstallerForTest* last_installer_; |
| 210 |
| 211 bool enable_safebrowsing_redirects_; |
194 }; | 212 }; |
195 | 213 |
196 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest, | 214 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest, |
197 CloseTabBeforeInstallConfirmation) { | 215 CloseTabBeforeInstallConfirmation) { |
198 GURL install_url = GenerateTestServerUrl(kAppDomain, "install.html"); | 216 GURL install_url = GenerateTestServerUrl(kAppDomain, "install.html"); |
199 ui_test_utils::NavigateToURL(browser(), install_url); | 217 ui_test_utils::NavigateToURL(browser(), install_url); |
200 WebContents* web_contents = | 218 WebContents* web_contents = |
201 browser()->tab_strip_model()->GetActiveWebContents(); | 219 browser()->tab_strip_model()->GetActiveWebContents(); |
202 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents); | 220 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents); |
203 tab_helper->SetWebstoreInlineInstallerFactoryForTests( | 221 tab_helper->SetWebstoreInlineInstallerFactoryForTests( |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 } | 384 } |
367 | 385 |
368 // Test calling chrome.webstore.install() twice without waiting for the first to | 386 // Test calling chrome.webstore.install() twice without waiting for the first to |
369 // finish. | 387 // finish. |
370 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest, DoubleInlineInstallTest) { | 388 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest, DoubleInlineInstallTest) { |
371 ui_test_utils::NavigateToURL( | 389 ui_test_utils::NavigateToURL( |
372 browser(), GenerateTestServerUrl(kAppDomain, "double_install.html")); | 390 browser(), GenerateTestServerUrl(kAppDomain, "double_install.html")); |
373 RunTest("runTest"); | 391 RunTest("runTest"); |
374 } | 392 } |
375 | 393 |
376 class WebstoreInlineInstallerRedirectTest : public WebstoreInlineInstallerTest { | 394 class WebstoreInlineInstallerRedirectTest |
| 395 : public WebstoreInlineInstallerTest, |
| 396 public ::testing::WithParamInterface<bool> { |
377 public: | 397 public: |
378 WebstoreInlineInstallerRedirectTest() : cws_request_received_(false) {} | 398 WebstoreInlineInstallerRedirectTest() : cws_request_received_(false) {} |
379 ~WebstoreInlineInstallerRedirectTest() override {} | 399 ~WebstoreInlineInstallerRedirectTest() override {} |
380 | 400 |
381 void SetUpOnMainThread() override { | 401 void SetUpOnMainThread() override { |
382 WebstoreInstallerTest::SetUpOnMainThread(); | 402 WebstoreInstallerTest::SetUpOnMainThread(); |
383 host_resolver()->AddRule(kRedirect1Domain, "127.0.0.1"); | 403 host_resolver()->AddRule(kRedirect1Domain, "127.0.0.1"); |
384 host_resolver()->AddRule(kRedirect2Domain, "127.0.0.1"); | 404 host_resolver()->AddRule(kRedirect2Domain, "127.0.0.1"); |
385 } | 405 } |
386 | 406 |
387 void ProcessServerRequest( | 407 void ProcessServerRequest( |
388 const net::test_server::HttpRequest& request) override { | 408 const net::test_server::HttpRequest& request) override { |
389 cws_request_received_ = true; | 409 cws_request_received_ = true; |
390 if (request.content.find("redirect_chain") != std::string::npos) { | 410 if (request.content.find("redirect_chain") != std::string::npos) { |
391 std::unique_ptr<base::Value> contents = | 411 std::unique_ptr<base::Value> contents = |
392 base::JSONReader::Read(request.content); | 412 base::JSONReader::Read(request.content); |
393 ASSERT_EQ(base::Value::Type::DICTIONARY, contents->GetType()); | 413 ASSERT_EQ(base::Value::Type::DICTIONARY, contents->GetType()); |
394 cws_request_json_data_ = base::DictionaryValue::From(std::move(contents)); | 414 cws_request_json_data_ = base::DictionaryValue::From(std::move(contents)); |
395 } | 415 } |
396 } | 416 } |
397 | 417 |
398 bool cws_request_received_; | 418 bool cws_request_received_; |
399 std::unique_ptr<base::DictionaryValue> cws_request_json_data_; | 419 std::unique_ptr<base::DictionaryValue> cws_request_json_data_; |
400 }; | 420 }; |
401 | 421 |
402 // Test that an install from a page arrived at via redirects includes the | 422 // Test that an install from a page arrived at via redirects includes the |
403 // redirect information in the webstore request. | 423 // redirect information in the webstore request. |
404 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerRedirectTest, | 424 IN_PROC_BROWSER_TEST_P(WebstoreInlineInstallerRedirectTest, |
405 IncludesRedirectData) { | 425 IncludesRedirectData) { |
| 426 const bool using_safe_browsing_tracker = GetParam(); |
| 427 WebContents* web_contents = |
| 428 browser()->tab_strip_model()->GetActiveWebContents(); |
| 429 TabHelper* tab_helper = TabHelper::FromWebContents(web_contents); |
| 430 WebstoreInlineInstallerForTestFactory* factory = |
| 431 new WebstoreInlineInstallerForTestFactory(using_safe_browsing_tracker); |
| 432 tab_helper->SetWebstoreInlineInstallerFactoryForTests(factory); |
| 433 |
406 // Hand craft a url that will cause the test server to issue redirects. | 434 // Hand craft a url that will cause the test server to issue redirects. |
407 const std::vector<std::string> redirects = {kRedirect1Domain, | 435 const std::vector<std::string> redirects = {kRedirect1Domain, |
408 kRedirect2Domain}; | 436 kRedirect2Domain}; |
409 net::HostPortPair host_port = embedded_test_server()->host_port_pair(); | 437 net::HostPortPair host_port = embedded_test_server()->host_port_pair(); |
410 std::string redirect_chain; | 438 std::string redirect_chain; |
411 for (const auto& redirect : redirects) { | 439 for (const auto& redirect : redirects) { |
412 std::string redirect_url = base::StringPrintf( | 440 std::string redirect_url = base::StringPrintf( |
413 "http://%s:%d/server-redirect?", redirect.c_str(), host_port.port()); | 441 "http://%s:%d/server-redirect?", redirect.c_str(), host_port.port()); |
414 redirect_chain += redirect_url; | 442 redirect_chain += redirect_url; |
415 } | 443 } |
416 const GURL install_url = | 444 const GURL install_url = |
417 GURL(redirect_chain + | 445 GURL(redirect_chain + |
418 GenerateTestServerUrl(kAppDomain, "install.html").spec()); | 446 GenerateTestServerUrl(kAppDomain, "install.html").spec()); |
419 | 447 |
420 AutoAcceptInstall(); | 448 AutoAcceptInstall(); |
421 ui_test_utils::NavigateToURL(browser(), install_url); | 449 ui_test_utils::NavigateToURL(browser(), install_url); |
422 RunTest("runTest"); | 450 |
| 451 RunTestAsync("runTest"); |
| 452 while (!ProgrammableInstallPrompt::Ready()) |
| 453 base::RunLoop().RunUntilIdle(); |
| 454 web_contents->Close(); |
423 | 455 |
424 EXPECT_TRUE(cws_request_received_); | 456 EXPECT_TRUE(cws_request_received_); |
425 ASSERT_NE(nullptr, cws_request_json_data_); | 457 ASSERT_NE(nullptr, cws_request_json_data_); |
426 | 458 |
427 base::ListValue* redirect_list = nullptr; | 459 base::ListValue* redirect_list = nullptr; |
428 cws_request_json_data_->GetList("redirect_chain", &redirect_list); | 460 cws_request_json_data_->GetList("redirect_chain", &redirect_list); |
429 ASSERT_NE(nullptr, redirect_list); | 461 ASSERT_NE(nullptr, redirect_list); |
430 | 462 |
431 // Check that the expected domains are in the redirect list. | 463 // Check that the expected domains are in the redirect list. |
432 const std::vector<std::string> expected_redirect_domains = { | 464 const std::set<std::string> expected_redirect_domains = { |
433 kRedirect1Domain, kRedirect2Domain, kAppDomain}; | 465 kRedirect1Domain, kRedirect2Domain, kAppDomain}; |
434 ASSERT_EQ(expected_redirect_domains.size(), redirect_list->GetSize()); | 466 |
435 int i = 0; | 467 // The SafeBrowsing tracker has a much more liberal definition of "redirect" |
| 468 // and it may (based on timing) pick up additional navigations that occur |
| 469 // shortly before the navigation we mainly care about here. Be somewhat |
| 470 // permissive in what we accept as redirect results. |
| 471 ASSERT_LE(expected_redirect_domains.size(), redirect_list->GetSize()); |
| 472 |
436 for (const auto& value : *redirect_list) { | 473 for (const auto& value : *redirect_list) { |
437 std::string value_string; | 474 std::string value_string; |
438 ASSERT_TRUE(value.GetAsString(&value_string)); | 475 ASSERT_TRUE(value.GetAsString(&value_string)); |
439 GURL redirect_url(value_string); | 476 GURL redirect_url(value_string); |
440 EXPECT_EQ(expected_redirect_domains[i++], redirect_url.host()); | 477 EXPECT_TRUE(expected_redirect_domains.find(redirect_url.host()) != |
| 478 expected_redirect_domains.end()); |
441 } | 479 } |
442 } | 480 } |
443 | 481 |
444 // Test that an install from a page arrived at via redirects does not include | 482 // Test that an install from a page arrived at via redirects does not include |
445 // redirect information when SafeBrowsing is disabled. | 483 // redirect information when SafeBrowsing is disabled. |
446 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerRedirectTest, | 484 IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerRedirectTest, |
447 NoRedirectDataWhenSafeBrowsingDisabled) { | 485 NoRedirectDataWhenSafeBrowsingDisabled) { |
448 PrefService* pref_service = browser()->profile()->GetPrefs(); | 486 PrefService* pref_service = browser()->profile()->GetPrefs(); |
449 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled)); | 487 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled)); |
450 | 488 |
(...skipping 15 matching lines...) Expand all Loading... |
466 GenerateTestServerUrl(kAppDomain, "install.html").spec()); | 504 GenerateTestServerUrl(kAppDomain, "install.html").spec()); |
467 | 505 |
468 AutoAcceptInstall(); | 506 AutoAcceptInstall(); |
469 ui_test_utils::NavigateToURL(browser(), install_url); | 507 ui_test_utils::NavigateToURL(browser(), install_url); |
470 RunTest("runTest"); | 508 RunTest("runTest"); |
471 | 509 |
472 EXPECT_TRUE(cws_request_received_); | 510 EXPECT_TRUE(cws_request_received_); |
473 ASSERT_EQ(nullptr, cws_request_json_data_); | 511 ASSERT_EQ(nullptr, cws_request_json_data_); |
474 } | 512 } |
475 | 513 |
| 514 INSTANTIATE_TEST_CASE_P(NetRedirectTracking, |
| 515 WebstoreInlineInstallerRedirectTest, |
| 516 testing::Values(false)); |
| 517 INSTANTIATE_TEST_CASE_P(SafeBrowsingRedirectTracking, |
| 518 WebstoreInlineInstallerRedirectTest, |
| 519 testing::Values(true)); |
| 520 |
476 class WebstoreInlineInstallerListenerTest : public WebstoreInlineInstallerTest { | 521 class WebstoreInlineInstallerListenerTest : public WebstoreInlineInstallerTest { |
477 public: | 522 public: |
478 WebstoreInlineInstallerListenerTest() {} | 523 WebstoreInlineInstallerListenerTest() {} |
479 ~WebstoreInlineInstallerListenerTest() override {} | 524 ~WebstoreInlineInstallerListenerTest() override {} |
480 | 525 |
481 protected: | 526 protected: |
482 void RunTest(const std::string& file_name) { | 527 void RunTest(const std::string& file_name) { |
483 AutoAcceptInstall(); | 528 AutoAcceptInstall(); |
484 ui_test_utils::NavigateToURL(browser(), | 529 ui_test_utils::NavigateToURL(browser(), |
485 GenerateTestServerUrl(kAppDomain, file_name)); | 530 GenerateTestServerUrl(kAppDomain, file_name)); |
(...skipping 30 matching lines...) Expand all Loading... |
516 WindowOpenDisposition::NEW_FOREGROUND_TAB, | 561 WindowOpenDisposition::NEW_FOREGROUND_TAB, |
517 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 562 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
518 DCHECK_NE(old_tab_index, browser()->tab_strip_model()->active_index()); | 563 DCHECK_NE(old_tab_index, browser()->tab_strip_model()->active_index()); |
519 browser()->tab_strip_model()->CloseWebContentsAt(old_tab_index, | 564 browser()->tab_strip_model()->CloseWebContentsAt(old_tab_index, |
520 TabStripModel::CLOSE_NONE); | 565 TabStripModel::CLOSE_NONE); |
521 WebstoreInstallerTest::RunTest("runTest"); | 566 WebstoreInstallerTest::RunTest("runTest"); |
522 EXPECT_TRUE(registry->enabled_extensions().GetByID(kTestExtensionId)); | 567 EXPECT_TRUE(registry->enabled_extensions().GetByID(kTestExtensionId)); |
523 } | 568 } |
524 | 569 |
525 } // namespace extensions | 570 } // namespace extensions |
OLD | NEW |