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