OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/password_manager/chrome_password_manager_client.h" | 5 #include "chrome/browser/password_manager/chrome_password_manager_client.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <tuple> | 10 #include <tuple> |
11 | 11 |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/metrics/field_trial.h" | 13 #include "base/metrics/field_trial.h" |
14 #include "base/strings/string16.h" | 14 #include "base/strings/string16.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
16 #include "base/test/scoped_feature_list.h" | 16 #include "base/test/scoped_feature_list.h" |
| 17 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" |
17 #include "chrome/browser/sync/profile_sync_service_factory.h" | 18 #include "chrome/browser/sync/profile_sync_service_factory.h" |
18 #include "chrome/browser/sync/profile_sync_test_util.h" | 19 #include "chrome/browser/sync/profile_sync_test_util.h" |
19 #include "chrome/common/channel_info.h" | 20 #include "chrome/common/channel_info.h" |
20 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
21 #include "chrome/test/base/testing_profile.h" | 22 #include "chrome/test/base/testing_profile.h" |
22 #include "components/autofill/content/common/autofill_messages.h" | 23 #include "components/autofill/content/common/autofill_messages.h" |
23 #include "components/password_manager/content/browser/password_manager_internals
_service_factory.h" | 24 #include "components/password_manager/content/browser/password_manager_internals
_service_factory.h" |
24 #include "components/password_manager/core/browser/credentials_filter.h" | 25 #include "components/password_manager/core/browser/credentials_filter.h" |
25 #include "components/password_manager/core/browser/log_manager.h" | 26 #include "components/password_manager/core/browser/log_manager.h" |
26 #include "components/password_manager/core/browser/log_receiver.h" | 27 #include "components/password_manager/core/browser/log_receiver.h" |
27 #include "components/password_manager/core/browser/log_router.h" | 28 #include "components/password_manager/core/browser/log_router.h" |
28 #include "components/password_manager/core/browser/password_manager_internals_se
rvice.h" | 29 #include "components/password_manager/core/browser/password_manager_internals_se
rvice.h" |
29 #include "components/password_manager/core/browser/password_manager_test_utils.h
" | 30 #include "components/password_manager/core/browser/password_manager_test_utils.h
" |
30 #include "components/password_manager/core/common/credential_manager_types.h" | 31 #include "components/password_manager/core/common/credential_manager_types.h" |
31 #include "components/password_manager/core/common/password_manager_features.h" | 32 #include "components/password_manager/core/common/password_manager_features.h" |
32 #include "components/password_manager/core/common/password_manager_pref_names.h" | 33 #include "components/password_manager/core/common/password_manager_pref_names.h" |
33 #include "components/prefs/pref_registry_simple.h" | 34 #include "components/prefs/pref_registry_simple.h" |
34 #include "components/prefs/pref_service.h" | 35 #include "components/prefs/pref_service.h" |
35 #include "components/prefs/testing_pref_service.h" | 36 #include "components/prefs/testing_pref_service.h" |
| 37 #include "components/sessions/content/content_record_password_state.h" |
36 #include "components/syncable_prefs/testing_pref_service_syncable.h" | 38 #include "components/syncable_prefs/testing_pref_service_syncable.h" |
37 #include "components/version_info/version_info.h" | 39 #include "components/version_info/version_info.h" |
38 #include "content/public/browser/browser_context.h" | 40 #include "content/public/browser/browser_context.h" |
39 #include "content/public/browser/web_contents.h" | 41 #include "content/public/browser/web_contents.h" |
40 #include "content/public/test/mock_render_process_host.h" | 42 #include "content/public/test/mock_render_process_host.h" |
41 #include "testing/gmock/include/gmock/gmock.h" | 43 #include "testing/gmock/include/gmock/gmock.h" |
42 #include "testing/gtest/include/gtest/gtest.h" | 44 #include "testing/gtest/include/gtest/gtest.h" |
43 | 45 |
44 using content::BrowserContext; | 46 using content::BrowserContext; |
45 using content::WebContents; | 47 using content::WebContents; |
| 48 using sessions::GetPasswordStateFromNavigation; |
| 49 using sessions::SerializedNavigationEntry; |
46 using testing::Return; | 50 using testing::Return; |
47 using testing::_; | 51 using testing::_; |
48 | 52 |
49 namespace { | 53 namespace { |
50 | 54 |
51 const char kPasswordManagerSettingsBehaviourChangeFieldTrialName[] = | 55 const char kPasswordManagerSettingsBehaviourChangeFieldTrialName[] = |
52 "PasswordManagerSettingsBehaviourChange"; | 56 "PasswordManagerSettingsBehaviourChange"; |
53 const char kPasswordManagerSettingsBehaviourChangeEnabledGroupName[] = | 57 const char kPasswordManagerSettingsBehaviourChangeEnabledGroupName[] = |
54 "PasswordManagerSettingsBehaviourChange.Active"; | 58 "PasswordManagerSettingsBehaviourChange.Active"; |
55 const char kPasswordManagerSettingsBehaviourChangeDisabledGroupName[] = | 59 const char kPasswordManagerSettingsBehaviourChangeDisabledGroupName[] = |
(...skipping 23 matching lines...) Expand all Loading... |
79 void LogSavePasswordProgress(const std::string& text) override {} | 83 void LogSavePasswordProgress(const std::string& text) override {} |
80 | 84 |
81 private: | 85 private: |
82 DISALLOW_COPY_AND_ASSIGN(DummyLogReceiver); | 86 DISALLOW_COPY_AND_ASSIGN(DummyLogReceiver); |
83 }; | 87 }; |
84 | 88 |
85 } // namespace | 89 } // namespace |
86 | 90 |
87 class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness { | 91 class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness { |
88 public: | 92 public: |
89 ChromePasswordManagerClientTest() : field_trial_list_(nullptr) {} | 93 ChromePasswordManagerClientTest() |
| 94 : field_trial_list_(nullptr), metrics_enabled_(false) {} |
90 void SetUp() override; | 95 void SetUp() override; |
| 96 void TearDown() override; |
91 | 97 |
92 syncable_prefs::TestingPrefServiceSyncable* prefs() { | 98 syncable_prefs::TestingPrefServiceSyncable* prefs() { |
93 return profile()->GetTestingPrefService(); | 99 return profile()->GetTestingPrefService(); |
94 } | 100 } |
95 | 101 |
96 void EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup( | 102 void EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup( |
97 const char* name) { | 103 const char* name) { |
98 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( | 104 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
99 kPasswordManagerSettingsBehaviourChangeFieldTrialName, name)); | 105 kPasswordManagerSettingsBehaviourChangeFieldTrialName, name)); |
100 } | 106 } |
101 | 107 |
| 108 // Caller does not own the returned pointer. |
| 109 ProfileSyncServiceMock* SetupBasicMockSync() { |
| 110 ProfileSyncServiceMock* mock_sync_service = |
| 111 static_cast<ProfileSyncServiceMock*>( |
| 112 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 113 profile(), BuildMockProfileSyncService)); |
| 114 |
| 115 EXPECT_CALL(*mock_sync_service, IsFirstSetupComplete()) |
| 116 .WillRepeatedly(Return(true)); |
| 117 EXPECT_CALL(*mock_sync_service, IsSyncActive()) |
| 118 .WillRepeatedly(Return(true)); |
| 119 return mock_sync_service; |
| 120 } |
| 121 |
| 122 // Make a navigation entry that will accept an annotation. |
| 123 void SetupNavigationForAnnotation() { |
| 124 ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); |
| 125 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) |
| 126 .WillRepeatedly(Return(false)); |
| 127 metrics_enabled_ = true; |
| 128 NavigateAndCommit(GURL("about:blank")); |
| 129 } |
| 130 |
102 protected: | 131 protected: |
103 ChromePasswordManagerClient* GetClient(); | 132 ChromePasswordManagerClient* GetClient(); |
104 | 133 |
105 // If the test IPC sink contains an AutofillMsg_SetLoggingState message, then | 134 // If the test IPC sink contains an AutofillMsg_SetLoggingState message, then |
106 // copies its argument into |activation_flag| and returns true. Otherwise | 135 // copies its argument into |activation_flag| and returns true. Otherwise |
107 // returns false. | 136 // returns false. |
108 bool WasLoggingActivationMessageSent(bool* activation_flag); | 137 bool WasLoggingActivationMessageSent(bool* activation_flag); |
109 | 138 |
110 TestingPrefServiceSimple prefs_; | 139 TestingPrefServiceSimple prefs_; |
111 base::FieldTrialList field_trial_list_; | 140 base::FieldTrialList field_trial_list_; |
| 141 bool metrics_enabled_; |
112 }; | 142 }; |
113 | 143 |
114 void ChromePasswordManagerClientTest::SetUp() { | 144 void ChromePasswordManagerClientTest::SetUp() { |
115 ChromeRenderViewHostTestHarness::SetUp(); | 145 ChromeRenderViewHostTestHarness::SetUp(); |
116 prefs_.registry()->RegisterBooleanPref( | 146 prefs_.registry()->RegisterBooleanPref( |
117 password_manager::prefs::kPasswordManagerSavingEnabled, true); | 147 password_manager::prefs::kPasswordManagerSavingEnabled, true); |
118 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( | 148 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( |
119 web_contents(), nullptr); | 149 web_contents(), nullptr); |
| 150 |
| 151 // Connect our bool for testing. |
| 152 ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting( |
| 153 &metrics_enabled_); |
| 154 } |
| 155 |
| 156 void ChromePasswordManagerClientTest::TearDown() { |
| 157 ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(nullptr); |
| 158 ChromeRenderViewHostTestHarness::TearDown(); |
120 } | 159 } |
121 | 160 |
122 ChromePasswordManagerClient* ChromePasswordManagerClientTest::GetClient() { | 161 ChromePasswordManagerClient* ChromePasswordManagerClientTest::GetClient() { |
123 return ChromePasswordManagerClient::FromWebContents(web_contents()); | 162 return ChromePasswordManagerClient::FromWebContents(web_contents()); |
124 } | 163 } |
125 | 164 |
126 bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent( | 165 bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent( |
127 bool* activation_flag) { | 166 bool* activation_flag) { |
128 const uint32_t kMsgID = AutofillMsg_SetLoggingState::ID; | 167 const uint32_t kMsgID = AutofillMsg_SetLoggingState::ID; |
129 const IPC::Message* message = | 168 const IPC::Message* message = |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 scoped_feature_list.InitAndEnableFeature( | 211 scoped_feature_list.InitAndEnableFeature( |
173 password_manager::features::kEnableAutomaticPasswordSaving); | 212 password_manager::features::kEnableAutomaticPasswordSaving); |
174 | 213 |
175 if (chrome::GetChannel() == version_info::Channel::UNKNOWN) | 214 if (chrome::GetChannel() == version_info::Channel::UNKNOWN) |
176 EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled()); | 215 EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled()); |
177 else | 216 else |
178 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled()); | 217 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled()); |
179 } | 218 } |
180 | 219 |
181 TEST_F(ChromePasswordManagerClientTest, GetPasswordSyncState) { | 220 TEST_F(ChromePasswordManagerClientTest, GetPasswordSyncState) { |
182 ChromePasswordManagerClient* client = GetClient(); | 221 ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); |
183 | |
184 ProfileSyncServiceMock* mock_sync_service = | |
185 static_cast<ProfileSyncServiceMock*>( | |
186 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( | |
187 profile(), BuildMockProfileSyncService)); | |
188 | 222 |
189 syncer::ModelTypeSet active_types; | 223 syncer::ModelTypeSet active_types; |
190 active_types.Put(syncer::PASSWORDS); | 224 active_types.Put(syncer::PASSWORDS); |
191 EXPECT_CALL(*mock_sync_service, IsFirstSetupComplete()) | |
192 .WillRepeatedly(Return(true)); | |
193 EXPECT_CALL(*mock_sync_service, IsSyncActive()).WillRepeatedly(Return(true)); | |
194 EXPECT_CALL(*mock_sync_service, GetActiveDataTypes()) | 225 EXPECT_CALL(*mock_sync_service, GetActiveDataTypes()) |
195 .WillRepeatedly(Return(active_types)); | 226 .WillRepeatedly(Return(active_types)); |
196 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) | 227 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) |
197 .WillRepeatedly(Return(false)); | 228 .WillRepeatedly(Return(false)); |
198 | 229 |
| 230 ChromePasswordManagerClient* client = GetClient(); |
| 231 |
199 // Passwords are syncing and custom passphrase isn't used. | 232 // Passwords are syncing and custom passphrase isn't used. |
200 EXPECT_EQ(password_manager::SYNCING_NORMAL_ENCRYPTION, | 233 EXPECT_EQ(password_manager::SYNCING_NORMAL_ENCRYPTION, |
201 client->GetPasswordSyncState()); | 234 client->GetPasswordSyncState()); |
202 | 235 |
203 // Again, using a custom passphrase. | 236 // Again, using a custom passphrase. |
204 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) | 237 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) |
205 .WillRepeatedly(Return(true)); | 238 .WillRepeatedly(Return(true)); |
206 | 239 |
207 EXPECT_EQ(password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE, | 240 EXPECT_EQ(password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE, |
208 client->GetPasswordSyncState()); | 241 client->GetPasswordSyncState()); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile()); | 378 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile()); |
346 DummyLogReceiver log_receiver; | 379 DummyLogReceiver log_receiver; |
347 EXPECT_EQ(std::string(), log_router->RegisterReceiver(&log_receiver)); | 380 EXPECT_EQ(std::string(), log_router->RegisterReceiver(&log_receiver)); |
348 | 381 |
349 // But then navigate to a WebUI, there the logging should not be active. | 382 // But then navigate to a WebUI, there the logging should not be active. |
350 NavigateAndCommit(GURL("about:password-manager-internals")); | 383 NavigateAndCommit(GURL("about:password-manager-internals")); |
351 EXPECT_FALSE(GetClient()->GetLogManager()->IsLoggingActive()); | 384 EXPECT_FALSE(GetClient()->GetLogManager()->IsLoggingActive()); |
352 | 385 |
353 log_router->UnregisterReceiver(&log_receiver); | 386 log_router->UnregisterReceiver(&log_receiver); |
354 } | 387 } |
| 388 |
| 389 // Metrics enabled, syncing with non-custom passphrase: Do not annotate. |
| 390 TEST_F(ChromePasswordManagerClientTest, |
| 391 AnnotateNavigationEntryWithMetricsNoCustom) { |
| 392 ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); |
| 393 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) |
| 394 .WillRepeatedly(Return(false)); |
| 395 metrics_enabled_ = true; |
| 396 |
| 397 NavigateAndCommit(GURL("about:blank")); |
| 398 GetClient()->AnnotateNavigationEntry(true); |
| 399 |
| 400 EXPECT_EQ( |
| 401 SerializedNavigationEntry::HAS_PASSWORD_FIELD, |
| 402 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 403 } |
| 404 |
| 405 // Metrics disabled, syncing with non-custom passphrase: Do not annotate. |
| 406 TEST_F(ChromePasswordManagerClientTest, |
| 407 AnnotateNavigationEntryNoMetricsNoCustom) { |
| 408 ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); |
| 409 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) |
| 410 .WillRepeatedly(Return(false)); |
| 411 metrics_enabled_ = false; |
| 412 |
| 413 NavigateAndCommit(GURL("about:blank")); |
| 414 GetClient()->AnnotateNavigationEntry(true); |
| 415 |
| 416 EXPECT_EQ( |
| 417 SerializedNavigationEntry::PASSWORD_STATE_UNKNOWN, |
| 418 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 419 } |
| 420 |
| 421 // Metrics enabled, syncing with custom passphrase: Do not annotate. |
| 422 TEST_F(ChromePasswordManagerClientTest, |
| 423 AnnotateNavigationEntryWithMetricsWithCustom) { |
| 424 ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); |
| 425 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) |
| 426 .WillRepeatedly(Return(true)); |
| 427 metrics_enabled_ = true; |
| 428 |
| 429 NavigateAndCommit(GURL("about:blank")); |
| 430 GetClient()->AnnotateNavigationEntry(true); |
| 431 |
| 432 EXPECT_EQ( |
| 433 SerializedNavigationEntry::PASSWORD_STATE_UNKNOWN, |
| 434 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 435 } |
| 436 |
| 437 // Metrics disabled, syncing with custom passphrase: Do not annotate. |
| 438 TEST_F(ChromePasswordManagerClientTest, |
| 439 AnnotateNavigationEntryNoMetricsWithCustom) { |
| 440 ProfileSyncServiceMock* mock_sync_service = SetupBasicMockSync(); |
| 441 EXPECT_CALL(*mock_sync_service, IsUsingSecondaryPassphrase()) |
| 442 .WillRepeatedly(Return(true)); |
| 443 metrics_enabled_ = false; |
| 444 |
| 445 NavigateAndCommit(GURL("about:blank")); |
| 446 GetClient()->AnnotateNavigationEntry(true); |
| 447 |
| 448 EXPECT_EQ( |
| 449 SerializedNavigationEntry::PASSWORD_STATE_UNKNOWN, |
| 450 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 451 } |
| 452 |
| 453 // State transition: Unannotated |
| 454 TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryUnannotated) { |
| 455 SetupNavigationForAnnotation(); |
| 456 |
| 457 EXPECT_EQ( |
| 458 SerializedNavigationEntry::PASSWORD_STATE_UNKNOWN, |
| 459 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 460 } |
| 461 |
| 462 // State transition: unknown->false |
| 463 TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryToFalse) { |
| 464 SetupNavigationForAnnotation(); |
| 465 |
| 466 GetClient()->AnnotateNavigationEntry(false); |
| 467 EXPECT_EQ( |
| 468 SerializedNavigationEntry::NO_PASSWORD_FIELD, |
| 469 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 470 } |
| 471 |
| 472 // State transition: false->true |
| 473 TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryToTrue) { |
| 474 SetupNavigationForAnnotation(); |
| 475 |
| 476 GetClient()->AnnotateNavigationEntry(false); |
| 477 GetClient()->AnnotateNavigationEntry(true); |
| 478 EXPECT_EQ( |
| 479 SerializedNavigationEntry::HAS_PASSWORD_FIELD, |
| 480 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 481 } |
| 482 |
| 483 // State transition: true->false (retains true) |
| 484 TEST_F(ChromePasswordManagerClientTest, AnnotateNavigationEntryTrueToFalse) { |
| 485 SetupNavigationForAnnotation(); |
| 486 |
| 487 GetClient()->AnnotateNavigationEntry(true); |
| 488 GetClient()->AnnotateNavigationEntry(false); |
| 489 EXPECT_EQ( |
| 490 SerializedNavigationEntry::HAS_PASSWORD_FIELD, |
| 491 GetPasswordStateFromNavigation(*controller().GetLastCommittedEntry())); |
| 492 } |
OLD | NEW |