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
3 // found in the LICENSE file.
5 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
7 #include "base/command_line.h"
8 #include "base/metrics/field_trial.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/testing_pref_service.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/sync/profile_sync_service_factory.h"
15 #include "chrome/browser/sync/profile_sync_service_mock.h"
16 #include "chrome/common/channel_info.h"
17 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/autofill/content/common/autofill_messages.h"
20 #include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
21 #include "components/password_manager/content/common/credential_manager_messages.h"
22 #include "components/password_manager/core/browser/credentials_filter.h"
23 #include "components/password_manager/core/browser/log_receiver.h"
24 #include "components/password_manager/core/browser/password_manager_internals_service.h"
25 #include "components/password_manager/core/common/credential_manager_types.h"
26 #include "components/password_manager/core/common/password_manager_pref_names.h"
27 #include "components/password_manager/core/common/password_manager_switches.h"
28 #include "components/syncable_prefs/testing_pref_service_syncable.h"
29 #include "components/version_info/version_info.h"
30 #include "content/public/browser/browser_context.h"
31 #include "content/public/browser/web_contents.h"
32 #include "content/public/test/mock_render_process_host.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 using content::BrowserContext
;
37 using content::WebContents
;
38 using testing::Return
;
43 const char kPasswordManagerSettingsBehaviourChangeFieldTrialName
[] =
44 "PasswordManagerSettingsBehaviourChange";
45 const char kPasswordManagerSettingsBehaviourChangeEnabledGroupName
[] =
46 "PasswordManagerSettingsBehaviourChange.Active";
47 const char kPasswordManagerSettingsBehaviourChangeDisabledGroupName
[] =
48 "PasswordManagerSettingsBehaviourChange.NotActive";
50 const char kTestText
[] = "abcd1234";
52 class MockLogReceiver
: public password_manager::LogReceiver
{
54 MOCK_METHOD1(LogSavePasswordProgress
, void(const std::string
&));
57 // TODO(vabr): Get rid of the mocked client in the client's own test, see
58 // http://crbug.com/474577.
59 class MockChromePasswordManagerClient
: public ChromePasswordManagerClient
{
61 MOCK_CONST_METHOD0(DidLastPageLoadEncounterSSLErrors
, bool());
63 explicit MockChromePasswordManagerClient(content::WebContents
* web_contents
)
64 : ChromePasswordManagerClient(web_contents
, nullptr) {
65 ON_CALL(*this, DidLastPageLoadEncounterSSLErrors())
66 .WillByDefault(testing::Return(false));
68 ~MockChromePasswordManagerClient() override
{}
71 DISALLOW_COPY_AND_ASSIGN(MockChromePasswordManagerClient
);
76 class ChromePasswordManagerClientTest
: public ChromeRenderViewHostTestHarness
{
78 ChromePasswordManagerClientTest()
79 : service_(nullptr), field_trial_list_(nullptr) {}
80 void SetUp() override
;
82 syncable_prefs::TestingPrefServiceSyncable
* prefs() {
83 return profile()->GetTestingPrefService();
86 void EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup(
88 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
89 kPasswordManagerSettingsBehaviourChangeFieldTrialName
, name
));
93 ChromePasswordManagerClient
* GetClient();
95 // If the test IPC sink contains an AutofillMsg_SetLoggingState message, then
96 // copies its argument into |activation_flag| and returns true. Otherwise
98 bool WasLoggingActivationMessageSent(bool* activation_flag
);
100 password_manager::PasswordManagerInternalsService
* service_
;
102 testing::StrictMock
<MockLogReceiver
> receiver_
;
103 TestingPrefServiceSimple prefs_
;
104 base::FieldTrialList field_trial_list_
;
107 void ChromePasswordManagerClientTest::SetUp() {
108 ChromeRenderViewHostTestHarness::SetUp();
109 prefs_
.registry()->RegisterBooleanPref(
110 password_manager::prefs::kPasswordManagerSavingEnabled
, true);
111 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
112 web_contents(), nullptr);
113 service_
= password_manager::PasswordManagerInternalsServiceFactory::
114 GetForBrowserContext(profile());
115 ASSERT_TRUE(service_
);
118 ChromePasswordManagerClient
* ChromePasswordManagerClientTest::GetClient() {
119 return ChromePasswordManagerClient::FromWebContents(web_contents());
122 bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent(
123 bool* activation_flag
) {
124 const uint32 kMsgID
= AutofillMsg_SetLoggingState::ID
;
125 const IPC::Message
* message
=
126 process()->sink().GetFirstMessageMatching(kMsgID
);
129 base::Tuple
<bool> param
;
130 AutofillMsg_SetLoggingState::Read(message
, ¶m
);
131 *activation_flag
= base::get
<0>(param
);
132 process()->sink().ClearMessages();
136 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressNoReceiver
) {
137 ChromePasswordManagerClient
* client
= GetClient();
139 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(0);
140 // Before attaching the receiver, no text should be passed.
141 client
->LogSavePasswordProgress(kTestText
);
142 EXPECT_FALSE(client
->IsLoggingActive());
145 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressAttachReceiver
) {
146 ChromePasswordManagerClient
* client
= GetClient();
147 EXPECT_FALSE(client
->IsLoggingActive());
149 // After attaching the logger, text should be passed.
150 service_
->RegisterReceiver(&receiver_
);
151 EXPECT_TRUE(client
->IsLoggingActive());
152 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(1);
153 client
->LogSavePasswordProgress(kTestText
);
154 service_
->UnregisterReceiver(&receiver_
);
155 EXPECT_FALSE(client
->IsLoggingActive());
158 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressDetachReceiver
) {
159 ChromePasswordManagerClient
* client
= GetClient();
161 service_
->RegisterReceiver(&receiver_
);
162 EXPECT_TRUE(client
->IsLoggingActive());
163 service_
->UnregisterReceiver(&receiver_
);
164 EXPECT_FALSE(client
->IsLoggingActive());
166 // After detaching the logger, no text should be passed.
167 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(0);
168 client
->LogSavePasswordProgress(kTestText
);
171 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressNotifyRenderer
) {
172 ChromePasswordManagerClient
* client
= GetClient();
173 bool logging_active
= false;
175 // Initially, the logging should be off, so no IPC messages.
176 EXPECT_FALSE(WasLoggingActivationMessageSent(&logging_active
));
178 service_
->RegisterReceiver(&receiver_
);
179 EXPECT_TRUE(client
->IsLoggingActive());
180 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
181 EXPECT_TRUE(logging_active
);
183 service_
->UnregisterReceiver(&receiver_
);
184 EXPECT_FALSE(client
->IsLoggingActive());
185 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
186 EXPECT_FALSE(logging_active
);
189 TEST_F(ChromePasswordManagerClientTest
, AnswerToPingsAboutLoggingState_Active
) {
190 service_
->RegisterReceiver(&receiver_
);
192 process()->sink().ClearMessages();
194 // Ping the client for logging activity update.
195 AutofillHostMsg_PasswordAutofillAgentConstructed
msg(0);
196 static_cast<content::WebContentsObserver
*>(GetClient())->OnMessageReceived(
197 msg
, web_contents()->GetMainFrame());
199 bool logging_active
= false;
200 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
201 EXPECT_TRUE(logging_active
);
203 service_
->UnregisterReceiver(&receiver_
);
206 TEST_F(ChromePasswordManagerClientTest
,
207 AnswerToPingsAboutLoggingState_Inactive
) {
208 process()->sink().ClearMessages();
210 // Ping the client for logging activity update.
211 AutofillHostMsg_PasswordAutofillAgentConstructed
msg(0);
212 static_cast<content::WebContentsObserver
*>(GetClient())->OnMessageReceived(
213 msg
, web_contents()->GetMainFrame());
215 bool logging_active
= true;
216 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
217 EXPECT_FALSE(logging_active
);
220 TEST_F(ChromePasswordManagerClientTest
,
221 IsAutomaticPasswordSavingEnabledDefaultBehaviourTest
) {
222 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
225 TEST_F(ChromePasswordManagerClientTest
,
226 IsAutomaticPasswordSavingEnabledWhenFlagIsSetTest
) {
227 base::CommandLine::ForCurrentProcess()->AppendSwitch(
228 password_manager::switches::kEnableAutomaticPasswordSaving
);
229 if (chrome::GetChannel() == version_info::Channel::UNKNOWN
)
230 EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled());
232 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
235 TEST_F(ChromePasswordManagerClientTest
, LogToAReceiver
) {
236 ChromePasswordManagerClient
* client
= GetClient();
237 service_
->RegisterReceiver(&receiver_
);
238 EXPECT_TRUE(client
->IsLoggingActive());
240 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(1);
241 client
->LogSavePasswordProgress(kTestText
);
243 service_
->UnregisterReceiver(&receiver_
);
244 EXPECT_FALSE(client
->IsLoggingActive());
247 TEST_F(ChromePasswordManagerClientTest
, IsFillingEnabledForCurrentPage
) {
248 ChromePasswordManagerClient
* client
= GetClient();
250 GURL("https://accounts.google.com/ServiceLogin?continue="
251 "https://passwords.google.com/settings&rart=123"));
252 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
254 // Password site is inaccesible via HTTP, but because of HSTS the following
255 // link should still continue to https://passwords.google.com.
257 GURL("https://accounts.google.com/ServiceLogin?continue="
258 "http://passwords.google.com/settings&rart=123"));
259 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
260 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
262 // Specifying default port still passes.
264 GURL("https://accounts.google.com/ServiceLogin?continue="
265 "https://passwords.google.com:443/settings&rart=123"));
266 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
267 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
269 // Encoded URL is considered the same.
271 GURL("https://accounts.google.com/ServiceLogin?continue="
272 "https://passwords.%67oogle.com/settings&rart=123"));
273 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
274 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
276 // Make sure testing sites are disabled as well.
278 GURL("https://accounts.google.com/Login?continue="
279 "https://passwords-ac-testing.corp.google.com/settings&rart=456"));
280 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
282 // Fully qualified domain name is considered a different hostname by GURL.
283 // Ideally this would not be the case, but this quirk can be avoided by
284 // verification on the server. This test is simply documentation of this
287 GURL("https://accounts.google.com/ServiceLogin?continue="
288 "https://passwords.google.com./settings&rart=123"));
289 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
291 // Not a transactional reauth page.
293 GURL("https://accounts.google.com/ServiceLogin?continue="
294 "https://passwords.google.com/settings"));
295 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
297 // Should be enabled for other transactional reauth pages.
299 GURL("https://accounts.google.com/ServiceLogin?continue="
300 "https://mail.google.com&rart=234"));
301 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
303 // Reauth pages are only on accounts.google.com
305 GURL("https://other.site.com/ServiceLogin?continue="
306 "https://passwords.google.com&rart=234"));
307 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
310 TEST_F(ChromePasswordManagerClientTest
, GetPasswordSyncState
) {
311 ChromePasswordManagerClient
* client
= GetClient();
313 ProfileSyncServiceMock
* mock_sync_service
=
314 static_cast<ProfileSyncServiceMock
*>(
315 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
316 profile(), ProfileSyncServiceMock::BuildMockProfileSyncService
));
318 syncer::ModelTypeSet active_types
;
319 active_types
.Put(syncer::PASSWORDS
);
320 EXPECT_CALL(*mock_sync_service
, HasSyncSetupCompleted())
321 .WillRepeatedly(Return(true));
322 EXPECT_CALL(*mock_sync_service
, IsSyncActive()).WillRepeatedly(Return(true));
323 EXPECT_CALL(*mock_sync_service
, GetActiveDataTypes())
324 .WillRepeatedly(Return(active_types
));
325 EXPECT_CALL(*mock_sync_service
, IsUsingSecondaryPassphrase())
326 .WillRepeatedly(Return(false));
328 // Passwords are syncing and custom passphrase isn't used.
329 EXPECT_EQ(password_manager::SYNCING_NORMAL_ENCRYPTION
,
330 client
->GetPasswordSyncState());
332 // Again, using a custom passphrase.
333 EXPECT_CALL(*mock_sync_service
, IsUsingSecondaryPassphrase())
334 .WillRepeatedly(Return(true));
336 EXPECT_EQ(password_manager::SYNCING_WITH_CUSTOM_PASSPHRASE
,
337 client
->GetPasswordSyncState());
339 // Report correctly if we aren't syncing passwords.
340 active_types
.Remove(syncer::PASSWORDS
);
341 active_types
.Put(syncer::BOOKMARKS
);
342 EXPECT_CALL(*mock_sync_service
, GetActiveDataTypes())
343 .WillRepeatedly(Return(active_types
));
345 EXPECT_EQ(password_manager::NOT_SYNCING_PASSWORDS
,
346 client
->GetPasswordSyncState());
348 // Again, without a custom passphrase.
349 EXPECT_CALL(*mock_sync_service
, IsUsingSecondaryPassphrase())
350 .WillRepeatedly(Return(false));
352 EXPECT_EQ(password_manager::NOT_SYNCING_PASSWORDS
,
353 client
->GetPasswordSyncState());
356 TEST_F(ChromePasswordManagerClientTest
, IsOffTheRecordTest
) {
357 ChromePasswordManagerClient
* client
= GetClient();
359 profile()->ForceIncognito(true);
360 EXPECT_TRUE(client
->IsOffTheRecord());
362 profile()->ForceIncognito(false);
363 EXPECT_FALSE(client
->IsOffTheRecord());
366 TEST_F(ChromePasswordManagerClientTest
,
367 SavingDependsOnManagerEnabledPreference
) {
368 // Test that saving passwords depends on the password manager enabled
370 ChromePasswordManagerClient
* client
= GetClient();
371 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
372 new base::FundamentalValue(true));
373 EXPECT_TRUE(client
->IsSavingAndFillingEnabledForCurrentPage());
374 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
375 new base::FundamentalValue(false));
376 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
379 TEST_F(ChromePasswordManagerClientTest
,
380 FillingDependsOnManagerEnabledPreferenceAndExperimentEnabled
) {
381 // Test that filing of passwords depends on the password manager enabled
382 // preference and is the user participated in behavior change experiment.
383 ChromePasswordManagerClient
* client
= GetClient();
384 EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup(
385 kPasswordManagerSettingsBehaviourChangeEnabledGroupName
);
386 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
387 new base::FundamentalValue(true));
388 EXPECT_TRUE(client
->IsSavingAndFillingEnabledForCurrentPage());
389 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
390 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
391 new base::FundamentalValue(false));
392 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
393 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
396 TEST_F(ChromePasswordManagerClientTest
,
397 FillingDependsOnManagerEnabledPreferenceAndExperimentDisabled
) {
398 // Test that filing of passwords depends on the password manager enabled
399 // preference and is the user participated in behavior change experiment.
400 ChromePasswordManagerClient
* client
= GetClient();
401 EnforcePasswordManagerSettingsBehaviourChangeExperimentGroup(
402 kPasswordManagerSettingsBehaviourChangeDisabledGroupName
);
403 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
404 new base::FundamentalValue(true));
405 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
406 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
407 new base::FundamentalValue(false));
408 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
411 TEST_F(ChromePasswordManagerClientTest
, SavingAndFillingEnabledConditionsTest
) {
412 scoped_ptr
<MockChromePasswordManagerClient
> client(
413 new MockChromePasswordManagerClient(web_contents()));
414 // Functionality disabled if there is SSL errors.
415 EXPECT_CALL(*client
, DidLastPageLoadEncounterSSLErrors())
416 .WillRepeatedly(Return(true));
417 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
418 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
420 // Functionality disabled if there are SSL errors and the manager itself is
422 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
423 new base::FundamentalValue(false));
424 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
425 EXPECT_FALSE(client
->IsFillingEnabledForCurrentPage());
427 // Functionality disabled if there are no SSL errors, but the manager itself
429 EXPECT_CALL(*client
, DidLastPageLoadEncounterSSLErrors())
430 .WillRepeatedly(Return(false));
431 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
432 new base::FundamentalValue(false));
433 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
434 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
436 // Functionality enabled if there are no SSL errors and the manager is
438 EXPECT_CALL(*client
, DidLastPageLoadEncounterSSLErrors())
439 .WillRepeatedly(Return(false));
440 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
441 new base::FundamentalValue(true));
442 EXPECT_TRUE(client
->IsSavingAndFillingEnabledForCurrentPage());
443 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
445 // Functionality disabled in Incognito mode.
446 profile()->ForceIncognito(true);
447 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
448 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
450 // Functionality disabled in Incognito mode also when manager itself is
452 prefs()->SetUserPref(password_manager::prefs::kPasswordManagerSavingEnabled
,
453 new base::FundamentalValue(true));
454 EXPECT_FALSE(client
->IsSavingAndFillingEnabledForCurrentPage());
455 EXPECT_TRUE(client
->IsFillingEnabledForCurrentPage());
456 profile()->ForceIncognito(false);
459 TEST_F(ChromePasswordManagerClientTest
, GetLastCommittedEntryURL_Empty
) {
460 EXPECT_EQ(GURL::EmptyGURL(), GetClient()->GetLastCommittedEntryURL());
463 TEST_F(ChromePasswordManagerClientTest
, GetLastCommittedEntryURL
) {
465 "https://accounts.google.com/ServiceLogin?continue="
466 "https://passwords.google.com/settings&rart=123");
467 NavigateAndCommit(kUrl
);
468 EXPECT_EQ(kUrl
, GetClient()->GetLastCommittedEntryURL());