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/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/common/chrome_version_info.h"
11 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "components/autofill/content/common/autofill_messages.h"
14 #include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
15 #include "components/password_manager/content/common/credential_manager_messages.h"
16 #include "components/password_manager/content/common/credential_manager_types.h"
17 #include "components/password_manager/core/browser/log_receiver.h"
18 #include "components/password_manager/core/browser/password_manager_internals_service.h"
19 #include "components/password_manager/core/common/password_manager_switches.h"
20 #include "content/public/browser/browser_context.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/test/mock_render_process_host.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 using content::BrowserContext
;
27 using content::WebContents
;
31 const char kTestText
[] = "abcd1234";
33 class MockLogReceiver
: public password_manager::LogReceiver
{
35 MOCK_METHOD1(LogSavePasswordProgress
, void(const std::string
&));
38 class TestChromePasswordManagerClient
: public ChromePasswordManagerClient
{
40 explicit TestChromePasswordManagerClient(content::WebContents
* web_contents
)
41 : ChromePasswordManagerClient(web_contents
, NULL
),
42 is_sync_account_credential_(false) {}
43 virtual ~TestChromePasswordManagerClient() {}
45 virtual bool IsSyncAccountCredential(
46 const std::string
& username
,
47 const std::string
& origin
) const override
{
48 return is_sync_account_credential_
;
51 void set_is_sync_account_credential(bool is_sync_account_credential
) {
52 is_sync_account_credential_
= is_sync_account_credential
;
56 bool is_sync_account_credential_
;
58 DISALLOW_COPY_AND_ASSIGN(TestChromePasswordManagerClient
);
63 class ChromePasswordManagerClientTest
: public ChromeRenderViewHostTestHarness
{
65 ChromePasswordManagerClientTest();
67 virtual void SetUp() override
;
70 ChromePasswordManagerClient
* GetClient();
72 // If the test IPC sink contains an AutofillMsg_SetLoggingState message, then
73 // copies its argument into |activation_flag| and returns true. Otherwise
75 bool WasLoggingActivationMessageSent(bool* activation_flag
);
77 password_manager::PasswordManagerInternalsService
* service_
;
79 testing::StrictMock
<MockLogReceiver
> receiver_
;
82 ChromePasswordManagerClientTest::ChromePasswordManagerClientTest()
86 void ChromePasswordManagerClientTest::SetUp() {
87 ChromeRenderViewHostTestHarness::SetUp();
88 ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
89 web_contents(), NULL
);
90 service_
= password_manager::PasswordManagerInternalsServiceFactory::
91 GetForBrowserContext(profile());
92 ASSERT_TRUE(service_
);
95 ChromePasswordManagerClient
* ChromePasswordManagerClientTest::GetClient() {
96 return ChromePasswordManagerClient::FromWebContents(web_contents());
99 bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent(
100 bool* activation_flag
) {
101 const uint32 kMsgID
= AutofillMsg_SetLoggingState::ID
;
102 const IPC::Message
* message
=
103 process()->sink().GetFirstMessageMatching(kMsgID
);
107 AutofillMsg_SetLoggingState::Read(message
, ¶m
);
108 *activation_flag
= param
.a
;
109 process()->sink().ClearMessages();
113 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressNoReceiver
) {
114 ChromePasswordManagerClient
* client
= GetClient();
116 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(0);
117 // Before attaching the receiver, no text should be passed.
118 client
->LogSavePasswordProgress(kTestText
);
119 EXPECT_FALSE(client
->IsLoggingActive());
122 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressAttachReceiver
) {
123 ChromePasswordManagerClient
* client
= GetClient();
124 EXPECT_FALSE(client
->IsLoggingActive());
126 // After attaching the logger, text should be passed.
127 service_
->RegisterReceiver(&receiver_
);
128 EXPECT_TRUE(client
->IsLoggingActive());
129 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(1);
130 client
->LogSavePasswordProgress(kTestText
);
131 service_
->UnregisterReceiver(&receiver_
);
132 EXPECT_FALSE(client
->IsLoggingActive());
135 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressDetachReceiver
) {
136 ChromePasswordManagerClient
* client
= GetClient();
138 service_
->RegisterReceiver(&receiver_
);
139 EXPECT_TRUE(client
->IsLoggingActive());
140 service_
->UnregisterReceiver(&receiver_
);
141 EXPECT_FALSE(client
->IsLoggingActive());
143 // After detaching the logger, no text should be passed.
144 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(0);
145 client
->LogSavePasswordProgress(kTestText
);
148 TEST_F(ChromePasswordManagerClientTest
, LogSavePasswordProgressNotifyRenderer
) {
149 ChromePasswordManagerClient
* client
= GetClient();
150 bool logging_active
= false;
152 // Initially, the logging should be off, so no IPC messages.
153 EXPECT_FALSE(WasLoggingActivationMessageSent(&logging_active
));
155 service_
->RegisterReceiver(&receiver_
);
156 EXPECT_TRUE(client
->IsLoggingActive());
157 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
158 EXPECT_TRUE(logging_active
);
160 service_
->UnregisterReceiver(&receiver_
);
161 EXPECT_FALSE(client
->IsLoggingActive());
162 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
163 EXPECT_FALSE(logging_active
);
166 TEST_F(ChromePasswordManagerClientTest
, AnswerToPingsAboutLoggingState_Active
) {
167 service_
->RegisterReceiver(&receiver_
);
169 process()->sink().ClearMessages();
171 // Ping the client for logging activity update.
172 AutofillHostMsg_PasswordAutofillAgentConstructed
msg(0);
173 static_cast<IPC::Listener
*>(GetClient())->OnMessageReceived(msg
);
175 bool logging_active
= false;
176 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
177 EXPECT_TRUE(logging_active
);
179 service_
->UnregisterReceiver(&receiver_
);
182 TEST_F(ChromePasswordManagerClientTest
,
183 AnswerToPingsAboutLoggingState_Inactive
) {
184 process()->sink().ClearMessages();
186 // Ping the client for logging activity update.
187 AutofillHostMsg_PasswordAutofillAgentConstructed
msg(0);
188 static_cast<IPC::Listener
*>(GetClient())->OnMessageReceived(msg
);
190 bool logging_active
= true;
191 EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active
));
192 EXPECT_FALSE(logging_active
);
195 TEST_F(ChromePasswordManagerClientTest
,
196 IsAutomaticPasswordSavingEnabledDefaultBehaviourTest
) {
197 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
200 TEST_F(ChromePasswordManagerClientTest
,
201 IsAutomaticPasswordSavingEnabledWhenFlagIsSetTest
) {
202 CommandLine::ForCurrentProcess()->AppendSwitch(
203 password_manager::switches::kEnableAutomaticPasswordSaving
);
204 if (chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_UNKNOWN
)
205 EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled());
207 EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
210 TEST_F(ChromePasswordManagerClientTest
, LogToAReceiver
) {
211 ChromePasswordManagerClient
* client
= GetClient();
212 service_
->RegisterReceiver(&receiver_
);
213 EXPECT_TRUE(client
->IsLoggingActive());
215 EXPECT_CALL(receiver_
, LogSavePasswordProgress(kTestText
)).Times(1);
216 client
->LogSavePasswordProgress(kTestText
);
218 service_
->UnregisterReceiver(&receiver_
);
219 EXPECT_FALSE(client
->IsLoggingActive());
222 TEST_F(ChromePasswordManagerClientTest
, ShouldFilterAutofillResult_Reauth
) {
223 // Make client disallow only reauth requests.
224 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
225 command_line
->AppendSwitch(
226 password_manager::switches::kDisallowAutofillSyncCredentialForReauth
);
227 scoped_ptr
<TestChromePasswordManagerClient
> client(
228 new TestChromePasswordManagerClient(web_contents()));
229 autofill::PasswordForm form
;
231 client
->set_is_sync_account_credential(false);
233 GURL("https://accounts.google.com/login?rart=123&continue=blah"));
234 EXPECT_FALSE(client
->ShouldFilterAutofillResult(form
));
236 client
->set_is_sync_account_credential(true);
238 GURL("https://accounts.google.com/login?rart=123&continue=blah"));
239 EXPECT_TRUE(client
->ShouldFilterAutofillResult(form
));
241 // This counts as a reauth url, though a valid URL should have a value for
243 NavigateAndCommit(GURL("https://accounts.google.com/addlogin?rart"));
244 EXPECT_TRUE(client
->ShouldFilterAutofillResult(form
));
246 NavigateAndCommit(GURL("https://accounts.google.com/login?param=123"));
247 EXPECT_FALSE(client
->ShouldFilterAutofillResult(form
));
249 NavigateAndCommit(GURL("https://site.com/login?rart=678"));
250 EXPECT_FALSE(client
->ShouldFilterAutofillResult(form
));
253 TEST_F(ChromePasswordManagerClientTest
, ShouldFilterAutofillResult
) {
254 // Normally the client should allow any credentials through, even if they
255 // are the sync credential.
256 scoped_ptr
<TestChromePasswordManagerClient
> client(
257 new TestChromePasswordManagerClient(web_contents()));
258 autofill::PasswordForm form
;
259 client
->set_is_sync_account_credential(true);
260 NavigateAndCommit(GURL("https://accounts.google.com/Login"));
261 EXPECT_FALSE(client
->ShouldFilterAutofillResult(form
));
263 // Adding disallow switch should cause sync credential to be filtered.
264 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
265 command_line
->AppendSwitch(
266 password_manager::switches::kDisallowAutofillSyncCredential
);
267 client
.reset(new TestChromePasswordManagerClient(web_contents()));
268 client
->set_is_sync_account_credential(true);
269 NavigateAndCommit(GURL("https://accounts.google.com/Login"));
270 EXPECT_TRUE(client
->ShouldFilterAutofillResult(form
));
273 TEST_F(ChromePasswordManagerClientTest
,
274 IsPasswordManagerEnabledForCurrentPage
) {
275 ChromePasswordManagerClient
* client
= GetClient();
277 GURL("https://accounts.google.com/ServiceLogin?continue="
278 "https://passwords.google.com/settings&rart=123"));
279 EXPECT_FALSE(client
->IsPasswordManagerEnabledForCurrentPage());
281 // Password site is inaccesible via HTTP, but because of HSTS the following
282 // link should still continue to https://passwords.google.com.
284 GURL("https://accounts.google.com/ServiceLogin?continue="
285 "http://passwords.google.com/settings&rart=123"));
286 EXPECT_FALSE(client
->IsPasswordManagerEnabledForCurrentPage());
288 // Specifying default port still passes.
290 GURL("https://accounts.google.com/ServiceLogin?continue="
291 "https://passwords.google.com:443/settings&rart=123"));
292 EXPECT_FALSE(client
->IsPasswordManagerEnabledForCurrentPage());
294 // Encoded URL is considered the same.
296 GURL("https://accounts.google.com/ServiceLogin?continue="
297 "https://passwords.%67oogle.com/settings&rart=123"));
298 EXPECT_FALSE(client
->IsPasswordManagerEnabledForCurrentPage());
300 // Make sure testing sites are disabled as well.
302 GURL("https://accounts.google.com/Login?continue="
303 "https://passwords-ac-testing.corp.google.com/settings&rart=456"));
304 EXPECT_FALSE(client
->IsPasswordManagerEnabledForCurrentPage());
306 // Fully qualified domain name is considered a different hostname by GURL.
307 // Ideally this would not be the case, but this quirk can be avoided by
308 // verification on the server. This test is simply documentation of this
311 GURL("https://accounts.google.com/ServiceLogin?continue="
312 "https://passwords.google.com./settings&rart=123"));
313 EXPECT_TRUE(client
->IsPasswordManagerEnabledForCurrentPage());
315 // Not a transactional reauth page.
317 GURL("https://accounts.google.com/ServiceLogin?continue="
318 "https://passwords.google.com/settings"));
319 EXPECT_TRUE(client
->IsPasswordManagerEnabledForCurrentPage());
321 // Should be enabled for other transactional reauth pages.
323 GURL("https://accounts.google.com/ServiceLogin?continue="
324 "https://mail.google.com&rart=234"));
325 EXPECT_TRUE(client
->IsPasswordManagerEnabledForCurrentPage());
327 // Reauth pages are only on accounts.google.com
329 GURL("https://other.site.com/ServiceLogin?continue="
330 "https://passwords.google.com&rart=234"));
331 EXPECT_TRUE(client
->IsPasswordManagerEnabledForCurrentPage());