| 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 <string> | 5 #include <string> |
| 6 #include <utility> | 6 #include <utility> |
| 7 | 7 |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/metrics/histogram_samples.h" | 11 #include "base/metrics/histogram_samples.h" |
| 12 #include "base/metrics/statistics_recorder.h" | 12 #include "base/metrics/statistics_recorder.h" |
| 13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
| 14 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 18 #include "base/test/histogram_tester.h" |
| 18 #include "base/test/scoped_feature_list.h" | 19 #include "base/test/scoped_feature_list.h" |
| 19 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 20 #include "chrome/browser/chrome_notification_types.h" | 21 #include "chrome/browser/chrome_notification_types.h" |
| 21 #include "chrome/browser/password_manager/chrome_password_manager_client.h" | 22 #include "chrome/browser/password_manager/chrome_password_manager_client.h" |
| 22 #include "chrome/browser/password_manager/password_manager_test_base.h" | 23 #include "chrome/browser/password_manager/password_manager_test_base.h" |
| 23 #include "chrome/browser/password_manager/password_store_factory.h" | 24 #include "chrome/browser/password_manager/password_store_factory.h" |
| 24 #include "chrome/browser/profiles/profile.h" | 25 #include "chrome/browser/profiles/profile.h" |
| 25 #include "chrome/browser/ui/browser.h" | 26 #include "chrome/browser/ui/browser.h" |
| 26 #include "chrome/browser/ui/browser_navigator_params.h" | 27 #include "chrome/browser/ui/browser_navigator_params.h" |
| 27 #include "chrome/browser/ui/login/login_handler.h" | 28 #include "chrome/browser/ui/login/login_handler.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 } | 110 } |
| 110 | 111 |
| 111 class ObservingAutofillClient | 112 class ObservingAutofillClient |
| 112 : public autofill::TestAutofillClient, | 113 : public autofill::TestAutofillClient, |
| 113 public content::WebContentsUserData<ObservingAutofillClient> { | 114 public content::WebContentsUserData<ObservingAutofillClient> { |
| 114 public: | 115 public: |
| 115 ~ObservingAutofillClient() override {} | 116 ~ObservingAutofillClient() override {} |
| 116 | 117 |
| 117 void Wait() { message_loop_runner_->Run(); } | 118 void Wait() { message_loop_runner_->Run(); } |
| 118 | 119 |
| 120 // Pump messages until idle, then return bool indicating whether the popup was |
| 121 // shown. |
| 122 bool DidPopupAppear() { |
| 123 base::RunLoop run_loop; |
| 124 run_loop.RunUntilIdle(); |
| 125 return popup_shown; |
| 126 } |
| 127 |
| 119 void ShowAutofillPopup( | 128 void ShowAutofillPopup( |
| 120 const gfx::RectF& element_bounds, | 129 const gfx::RectF& element_bounds, |
| 121 base::i18n::TextDirection text_direction, | 130 base::i18n::TextDirection text_direction, |
| 122 const std::vector<autofill::Suggestion>& suggestions, | 131 const std::vector<autofill::Suggestion>& suggestions, |
| 123 base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override { | 132 base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override { |
| 124 message_loop_runner_->Quit(); | 133 if (message_loop_runner_) |
| 134 message_loop_runner_->Quit(); |
| 135 popup_shown = true; |
| 125 } | 136 } |
| 126 | 137 |
| 127 private: | 138 private: |
| 128 explicit ObservingAutofillClient(content::WebContents* web_contents) | 139 explicit ObservingAutofillClient(content::WebContents* web_contents) |
| 129 : message_loop_runner_(new content::MessageLoopRunner) {} | 140 : message_loop_runner_(new content::MessageLoopRunner), |
| 141 popup_shown(false) {} |
| 130 friend class content::WebContentsUserData<ObservingAutofillClient>; | 142 friend class content::WebContentsUserData<ObservingAutofillClient>; |
| 131 | 143 |
| 132 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | 144 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
| 145 bool popup_shown; |
| 133 | 146 |
| 134 DISALLOW_COPY_AND_ASSIGN(ObservingAutofillClient); | 147 DISALLOW_COPY_AND_ASSIGN(ObservingAutofillClient); |
| 135 }; | 148 }; |
| 136 | 149 |
| 137 // For simplicity we assume that password store contains only 1 credentials. | 150 // For simplicity we assume that password store contains only 1 credential. |
| 138 void CheckThatCredentialsStored( | 151 void CheckThatCredentialsStored( |
| 139 password_manager::TestPasswordStore* password_store, | 152 password_manager::TestPasswordStore* password_store, |
| 140 const base::string16& username, | 153 const base::string16& username, |
| 141 const base::string16& password) { | 154 const base::string16& password) { |
| 142 auto& passwords_map = password_store->stored_passwords(); | 155 auto& passwords_map = password_store->stored_passwords(); |
| 143 ASSERT_EQ(1u, passwords_map.size()); | 156 ASSERT_EQ(1u, passwords_map.size()); |
| 144 auto& passwords_vector = passwords_map.begin()->second; | 157 auto& passwords_vector = passwords_map.begin()->second; |
| 145 ASSERT_EQ(1u, passwords_vector.size()); | 158 ASSERT_EQ(1u, passwords_vector.size()); |
| 146 const autofill::PasswordForm& form = passwords_vector[0]; | 159 const autofill::PasswordForm& form = passwords_vector[0]; |
| 147 EXPECT_EQ(username, form.username_value); | 160 EXPECT_EQ(username, form.username_value); |
| (...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1749 "document.getElementById('pa_password_field').value = 'random';" | 1762 "document.getElementById('pa_password_field').value = 'random';" |
| 1750 "document.getElementById('pa_submit_button').click()"; | 1763 "document.getElementById('pa_submit_button').click()"; |
| 1751 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit)); | 1764 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_submit)); |
| 1752 observer.Wait(); | 1765 observer.Wait(); |
| 1753 EXPECT_FALSE(prompt_observer->IsShowingSavePrompt()); | 1766 EXPECT_FALSE(prompt_observer->IsShowingSavePrompt()); |
| 1754 } | 1767 } |
| 1755 | 1768 |
| 1756 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, | 1769 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, |
| 1757 InFrameNavigationDoesNotClearPopupState) { | 1770 InFrameNavigationDoesNotClearPopupState) { |
| 1758 // Mock out the AutofillClient so we know how long to wait. Unfortunately | 1771 // Mock out the AutofillClient so we know how long to wait. Unfortunately |
| 1759 // there isn't otherwise a good even to wait on to verify that the popup | 1772 // there isn't otherwise a good event to wait on to verify that the popup |
| 1760 // would have been shown. | 1773 // would have been shown. |
| 1761 password_manager::ContentPasswordManagerDriverFactory* driver_factory = | 1774 password_manager::ContentPasswordManagerDriverFactory* driver_factory = |
| 1762 password_manager::ContentPasswordManagerDriverFactory::FromWebContents( | 1775 password_manager::ContentPasswordManagerDriverFactory::FromWebContents( |
| 1763 WebContents()); | 1776 WebContents()); |
| 1764 ObservingAutofillClient::CreateForWebContents(WebContents()); | 1777 ObservingAutofillClient::CreateForWebContents(WebContents()); |
| 1765 ObservingAutofillClient* observing_autofill_client = | 1778 ObservingAutofillClient* observing_autofill_client = |
| 1766 ObservingAutofillClient::FromWebContents(WebContents()); | 1779 ObservingAutofillClient::FromWebContents(WebContents()); |
| 1767 password_manager::ContentPasswordManagerDriver* driver = | 1780 password_manager::ContentPasswordManagerDriver* driver = |
| 1768 driver_factory->GetDriverForFrame(RenderViewHost()->GetMainFrame()); | 1781 driver_factory->GetDriverForFrame(RenderViewHost()->GetMainFrame()); |
| 1769 DCHECK(driver); | 1782 DCHECK(driver); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1809 &left)); | 1822 &left)); |
| 1810 | 1823 |
| 1811 content::SimulateMouseClickAt( | 1824 content::SimulateMouseClickAt( |
| 1812 WebContents(), 0, blink::WebMouseEvent::Button::Left, gfx::Point(left + 1, | 1825 WebContents(), 0, blink::WebMouseEvent::Button::Left, gfx::Point(left + 1, |
| 1813 top + 1)); | 1826 top + 1)); |
| 1814 // Make sure the popup would be shown. | 1827 // Make sure the popup would be shown. |
| 1815 observing_autofill_client->Wait(); | 1828 observing_autofill_client->Wait(); |
| 1816 } | 1829 } |
| 1817 | 1830 |
| 1818 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, | 1831 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, |
| 1832 ShowFormNotSecureOnUsernameField) { |
| 1833 password_manager::ContentPasswordManagerDriverFactory* driver_factory = |
| 1834 password_manager::ContentPasswordManagerDriverFactory::FromWebContents( |
| 1835 WebContents()); |
| 1836 ObservingAutofillClient::CreateForWebContents(WebContents()); |
| 1837 ObservingAutofillClient* observing_autofill_client = |
| 1838 ObservingAutofillClient::FromWebContents(WebContents()); |
| 1839 password_manager::ContentPasswordManagerDriver* driver = |
| 1840 driver_factory->GetDriverForFrame(RenderViewHost()->GetMainFrame()); |
| 1841 DCHECK(driver); |
| 1842 driver->GetPasswordAutofillManager()->set_autofill_client( |
| 1843 observing_autofill_client); |
| 1844 |
| 1845 // We need to serve from a non-localhost context for the form to be treated as |
| 1846 // Not Secure. |
| 1847 host_resolver()->AddRule("example.com", "127.0.0.1"); |
| 1848 NavigationObserver observer(WebContents()); |
| 1849 ui_test_utils::NavigateToURL( |
| 1850 browser(), embedded_test_server()->GetURL( |
| 1851 "example.com", "/password/password_form.html")); |
| 1852 observer.Wait(); |
| 1853 |
| 1854 ASSERT_TRUE(content::ExecuteScript( |
| 1855 RenderViewHost(), |
| 1856 "var inputRect = document.getElementById('username_field_no_name')" |
| 1857 ".getBoundingClientRect();")); |
| 1858 |
| 1859 // Click on the username field to verify the warning is shown. |
| 1860 int top; |
| 1861 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( |
| 1862 RenderViewHost(), "window.domAutomationController.send(inputRect.top);", |
| 1863 &top)); |
| 1864 int left; |
| 1865 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( |
| 1866 RenderViewHost(), "window.domAutomationController.send(inputRect.left);", |
| 1867 &left)); |
| 1868 |
| 1869 const char kHistogram[] = |
| 1870 "PasswordManager.ShowedFormNotSecureWarningOnCurrentNavigation"; |
| 1871 base::HistogramTester histograms; |
| 1872 |
| 1873 content::SimulateMouseClickAt(WebContents(), 0, |
| 1874 blink::WebMouseEvent::Button::Left, |
| 1875 gfx::Point(left + 1, top + 1)); |
| 1876 // Ensure the warning would be shown. |
| 1877 observing_autofill_client->Wait(); |
| 1878 // Ensure the histogram was updated. |
| 1879 histograms.ExpectUniqueSample(kHistogram, true, 1); |
| 1880 } |
| 1881 |
| 1882 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, |
| 1883 DoNotShowFormNotSecureOnUnrelatedField) { |
| 1884 password_manager::ContentPasswordManagerDriverFactory* driver_factory = |
| 1885 password_manager::ContentPasswordManagerDriverFactory::FromWebContents( |
| 1886 WebContents()); |
| 1887 ObservingAutofillClient::CreateForWebContents(WebContents()); |
| 1888 ObservingAutofillClient* observing_autofill_client = |
| 1889 ObservingAutofillClient::FromWebContents(WebContents()); |
| 1890 password_manager::ContentPasswordManagerDriver* driver = |
| 1891 driver_factory->GetDriverForFrame(RenderViewHost()->GetMainFrame()); |
| 1892 DCHECK(driver); |
| 1893 driver->GetPasswordAutofillManager()->set_autofill_client( |
| 1894 observing_autofill_client); |
| 1895 |
| 1896 // We need to serve from a non-localhost context for the form to be treated as |
| 1897 // Not Secure. |
| 1898 host_resolver()->AddRule("example.com", "127.0.0.1"); |
| 1899 NavigationObserver observer(WebContents()); |
| 1900 ui_test_utils::NavigateToURL( |
| 1901 browser(), embedded_test_server()->GetURL( |
| 1902 "example.com", "/password/password_form.html")); |
| 1903 observer.Wait(); |
| 1904 |
| 1905 ASSERT_TRUE(content::ExecuteScript( |
| 1906 RenderViewHost(), |
| 1907 "var inputRect = document.getElementById('ef_extra')" |
| 1908 ".getBoundingClientRect();")); |
| 1909 |
| 1910 // Click on the non-username text field. |
| 1911 int top; |
| 1912 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( |
| 1913 RenderViewHost(), "window.domAutomationController.send(inputRect.top);", |
| 1914 &top)); |
| 1915 int left; |
| 1916 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( |
| 1917 RenderViewHost(), "window.domAutomationController.send(inputRect.left);", |
| 1918 &left)); |
| 1919 |
| 1920 const char kHistogram[] = |
| 1921 "PasswordManager.ShowedFormNotSecureWarningOnCurrentNavigation"; |
| 1922 base::HistogramTester histograms; |
| 1923 |
| 1924 content::SimulateMouseClickAt(WebContents(), 0, |
| 1925 blink::WebMouseEvent::Button::Left, |
| 1926 gfx::Point(left + 1, top + 1)); |
| 1927 // Force a round-trip. |
| 1928 ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), "var noop = 'noop';")); |
| 1929 // Ensure the warning was not triggered. |
| 1930 ASSERT_FALSE(observing_autofill_client->DidPopupAppear()); |
| 1931 // Ensure the histogram remains empty. |
| 1932 histograms.ExpectTotalCount(kHistogram, 0); |
| 1933 } |
| 1934 |
| 1935 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, |
| 1819 ChangePwdFormBubbleShown) { | 1936 ChangePwdFormBubbleShown) { |
| 1820 NavigateToFile("/password/password_form.html"); | 1937 NavigateToFile("/password/password_form.html"); |
| 1821 | 1938 |
| 1822 NavigationObserver observer(WebContents()); | 1939 NavigationObserver observer(WebContents()); |
| 1823 std::unique_ptr<BubbleObserver> prompt_observer( | 1940 std::unique_ptr<BubbleObserver> prompt_observer( |
| 1824 new BubbleObserver(WebContents())); | 1941 new BubbleObserver(WebContents())); |
| 1825 std::string fill_and_submit = | 1942 std::string fill_and_submit = |
| 1826 "document.getElementById('chg_username_field').value = 'temp';" | 1943 "document.getElementById('chg_username_field').value = 'temp';" |
| 1827 "document.getElementById('chg_password_field').value = 'random';" | 1944 "document.getElementById('chg_password_field').value = 'random';" |
| 1828 "document.getElementById('chg_new_password_1').value = 'random1';" | 1945 "document.getElementById('chg_new_password_1').value = 'random1';" |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3209 // about all frames, not just the main one. The factories should receive | 3326 // about all frames, not just the main one. The factories should receive |
| 3210 // messages for non-main frames, in particular | 3327 // messages for non-main frames, in particular |
| 3211 // AutofillHostMsg_PasswordFormsParsed. If that were the first time the | 3328 // AutofillHostMsg_PasswordFormsParsed. If that were the first time the |
| 3212 // factories hear about such frames, this would crash. | 3329 // factories hear about such frames, this would crash. |
| 3213 tab_strip_model->AddWebContents(detached_web_contents.release(), -1, | 3330 tab_strip_model->AddWebContents(detached_web_contents.release(), -1, |
| 3214 ::ui::PAGE_TRANSITION_AUTO_TOPLEVEL, | 3331 ::ui::PAGE_TRANSITION_AUTO_TOPLEVEL, |
| 3215 TabStripModel::ADD_ACTIVE); | 3332 TabStripModel::ADD_ACTIVE); |
| 3216 } | 3333 } |
| 3217 | 3334 |
| 3218 } // namespace password_manager | 3335 } // namespace password_manager |
| OLD | NEW |