Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / password_manager / chrome_password_manager_client_unittest.cc
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.
4
5 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
6
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"
25
26 using content::BrowserContext;
27 using content::WebContents;
28
29 namespace {
30
31 const char kTestText[] = "abcd1234";
32 const int kRequestId = 4;
33
34 class MockLogReceiver : public password_manager::LogReceiver {
35  public:
36   MOCK_METHOD1(LogSavePasswordProgress, void(const std::string&));
37 };
38
39 class TestChromePasswordManagerClient : public ChromePasswordManagerClient {
40  public:
41   explicit TestChromePasswordManagerClient(content::WebContents* web_contents)
42       : ChromePasswordManagerClient(web_contents, NULL),
43         is_sync_account_credential_(false) {}
44   virtual ~TestChromePasswordManagerClient() {}
45
46   virtual bool IsSyncAccountCredential(
47       const std::string& username,
48       const std::string& origin) const OVERRIDE {
49     return is_sync_account_credential_;
50   }
51
52   void set_is_sync_account_credential(bool is_sync_account_credential) {
53     is_sync_account_credential_ = is_sync_account_credential;
54   }
55
56  private:
57   bool is_sync_account_credential_;
58
59   DISALLOW_COPY_AND_ASSIGN(TestChromePasswordManagerClient);
60 };
61
62 }  // namespace
63
64 class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness {
65  public:
66   ChromePasswordManagerClientTest();
67
68   virtual void SetUp() OVERRIDE;
69
70  protected:
71   ChromePasswordManagerClient* GetClient();
72
73   // If the test IPC sink contains an AutofillMsg_SetLoggingState message, then
74   // copies its argument into |activation_flag| and returns true. Otherwise
75   // returns false.
76   bool WasLoggingActivationMessageSent(bool* activation_flag);
77
78   password_manager::PasswordManagerInternalsService* service_;
79
80   testing::StrictMock<MockLogReceiver> receiver_;
81 };
82
83 ChromePasswordManagerClientTest::ChromePasswordManagerClientTest()
84     : service_(NULL) {
85 }
86
87 void ChromePasswordManagerClientTest::SetUp() {
88   ChromeRenderViewHostTestHarness::SetUp();
89   ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
90       web_contents(), NULL);
91   service_ = password_manager::PasswordManagerInternalsServiceFactory::
92       GetForBrowserContext(profile());
93   ASSERT_TRUE(service_);
94 }
95
96 ChromePasswordManagerClient* ChromePasswordManagerClientTest::GetClient() {
97   return ChromePasswordManagerClient::FromWebContents(web_contents());
98 }
99
100 bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent(
101     bool* activation_flag) {
102   const uint32 kMsgID = AutofillMsg_SetLoggingState::ID;
103   const IPC::Message* message =
104       process()->sink().GetFirstMessageMatching(kMsgID);
105   if (!message)
106     return false;
107   Tuple1<bool> param;
108   AutofillMsg_SetLoggingState::Read(message, &param);
109   *activation_flag = param.a;
110   process()->sink().ClearMessages();
111   return true;
112 }
113
114 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNoReceiver) {
115   ChromePasswordManagerClient* client = GetClient();
116
117   EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
118   // Before attaching the receiver, no text should be passed.
119   client->LogSavePasswordProgress(kTestText);
120   EXPECT_FALSE(client->IsLoggingActive());
121 }
122
123 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressAttachReceiver) {
124   ChromePasswordManagerClient* client = GetClient();
125   EXPECT_FALSE(client->IsLoggingActive());
126
127   // After attaching the logger, text should be passed.
128   service_->RegisterReceiver(&receiver_);
129   EXPECT_TRUE(client->IsLoggingActive());
130   EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
131   client->LogSavePasswordProgress(kTestText);
132   service_->UnregisterReceiver(&receiver_);
133   EXPECT_FALSE(client->IsLoggingActive());
134 }
135
136 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressDetachReceiver) {
137   ChromePasswordManagerClient* client = GetClient();
138
139   service_->RegisterReceiver(&receiver_);
140   EXPECT_TRUE(client->IsLoggingActive());
141   service_->UnregisterReceiver(&receiver_);
142   EXPECT_FALSE(client->IsLoggingActive());
143
144   // After detaching the logger, no text should be passed.
145   EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
146   client->LogSavePasswordProgress(kTestText);
147 }
148
149 TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNotifyRenderer) {
150   ChromePasswordManagerClient* client = GetClient();
151   bool logging_active = false;
152
153   // Initially, the logging should be off, so no IPC messages.
154   EXPECT_FALSE(WasLoggingActivationMessageSent(&logging_active));
155
156   service_->RegisterReceiver(&receiver_);
157   EXPECT_TRUE(client->IsLoggingActive());
158   EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
159   EXPECT_TRUE(logging_active);
160
161   service_->UnregisterReceiver(&receiver_);
162   EXPECT_FALSE(client->IsLoggingActive());
163   EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
164   EXPECT_FALSE(logging_active);
165 }
166
167 TEST_F(ChromePasswordManagerClientTest, AnswerToPingsAboutLoggingState_Active) {
168   service_->RegisterReceiver(&receiver_);
169
170   process()->sink().ClearMessages();
171
172   // Ping the client for logging activity update.
173   AutofillHostMsg_PasswordAutofillAgentConstructed msg(0);
174   static_cast<IPC::Listener*>(GetClient())->OnMessageReceived(msg);
175
176   bool logging_active = false;
177   EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
178   EXPECT_TRUE(logging_active);
179
180   service_->UnregisterReceiver(&receiver_);
181 }
182
183 TEST_F(ChromePasswordManagerClientTest,
184        AnswerToPingsAboutLoggingState_Inactive) {
185   process()->sink().ClearMessages();
186
187   // Ping the client for logging activity update.
188   AutofillHostMsg_PasswordAutofillAgentConstructed msg(0);
189   static_cast<IPC::Listener*>(GetClient())->OnMessageReceived(msg);
190
191   bool logging_active = true;
192   EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
193   EXPECT_FALSE(logging_active);
194 }
195
196 TEST_F(ChromePasswordManagerClientTest,
197        IsAutomaticPasswordSavingEnabledDefaultBehaviourTest) {
198   EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
199 }
200
201 TEST_F(ChromePasswordManagerClientTest,
202        IsAutomaticPasswordSavingEnabledWhenFlagIsSetTest) {
203   CommandLine::ForCurrentProcess()->AppendSwitch(
204       password_manager::switches::kEnableAutomaticPasswordSaving);
205   if (chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_UNKNOWN)
206     EXPECT_TRUE(GetClient()->IsAutomaticPasswordSavingEnabled());
207   else
208     EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
209 }
210
211 TEST_F(ChromePasswordManagerClientTest, LogToAReceiver) {
212   ChromePasswordManagerClient* client = GetClient();
213   service_->RegisterReceiver(&receiver_);
214   EXPECT_TRUE(client->IsLoggingActive());
215
216   EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
217   client->LogSavePasswordProgress(kTestText);
218
219   service_->UnregisterReceiver(&receiver_);
220   EXPECT_FALSE(client->IsLoggingActive());
221 }
222
223 TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult_Reauth) {
224   // Make client disallow only reauth requests.
225   CommandLine* command_line = CommandLine::ForCurrentProcess();
226   command_line->AppendSwitch(
227       password_manager::switches::kDisallowAutofillSyncCredentialForReauth);
228   scoped_ptr<TestChromePasswordManagerClient> client(
229       new TestChromePasswordManagerClient(web_contents()));
230   autofill::PasswordForm form;
231
232   client->set_is_sync_account_credential(false);
233   NavigateAndCommit(
234       GURL("https://accounts.google.com/login?rart=123&continue=blah"));
235   EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
236
237   client->set_is_sync_account_credential(true);
238   NavigateAndCommit(
239       GURL("https://accounts.google.com/login?rart=123&continue=blah"));
240   EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
241
242   // This counts as a reauth url, though a valid URL should have a value for
243   // "rart"
244   NavigateAndCommit(GURL("https://accounts.google.com/addlogin?rart"));
245   EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
246
247   NavigateAndCommit(GURL("https://accounts.google.com/login?param=123"));
248   EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
249
250   NavigateAndCommit(GURL("https://site.com/login?rart=678"));
251   EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
252 }
253
254 TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult) {
255   // Normally the client should allow any credentials through, even if they
256   // are the sync credential.
257   scoped_ptr<TestChromePasswordManagerClient> client(
258       new TestChromePasswordManagerClient(web_contents()));
259   autofill::PasswordForm form;
260   client->set_is_sync_account_credential(true);
261   NavigateAndCommit(GURL("https://accounts.google.com/Login"));
262   EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
263
264   // Adding disallow switch should cause sync credential to be filtered.
265   CommandLine* command_line = CommandLine::ForCurrentProcess();
266   command_line->AppendSwitch(
267       password_manager::switches::kDisallowAutofillSyncCredential);
268   client.reset(new TestChromePasswordManagerClient(web_contents()));
269   client->set_is_sync_account_credential(true);
270   NavigateAndCommit(GURL("https://accounts.google.com/Login"));
271   EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
272 }
273
274 TEST_F(ChromePasswordManagerClientTest,
275        IsPasswordManagerEnabledForCurrentPage) {
276   ChromePasswordManagerClient* client = GetClient();
277   NavigateAndCommit(
278       GURL("https://accounts.google.com/ServiceLogin?continue="
279            "https://passwords.google.com/settings&rart=123"));
280   EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
281
282   // Password site is inaccesible via HTTP, but because of HSTS the following
283   // link should still continue to https://passwords.google.com.
284   NavigateAndCommit(
285       GURL("https://accounts.google.com/ServiceLogin?continue="
286            "http://passwords.google.com/settings&rart=123"));
287   EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
288
289   // Specifying default port still passes.
290   NavigateAndCommit(
291       GURL("https://accounts.google.com/ServiceLogin?continue="
292            "https://passwords.google.com:443/settings&rart=123"));
293   EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
294
295   // Encoded URL is considered the same.
296   NavigateAndCommit(
297       GURL("https://accounts.google.com/ServiceLogin?continue="
298            "https://passwords.%67oogle.com/settings&rart=123"));
299   EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
300
301   // Make sure testing sites are disabled as well.
302   NavigateAndCommit(
303       GURL("https://accounts.google.com/Login?continue="
304            "https://passwords-ac-testing.corp.google.com/settings&rart=456"));
305   EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
306
307   // Fully qualified domain name is considered a different hostname by GURL.
308   // Ideally this would not be the case, but this quirk can be avoided by
309   // verification on the server. This test is simply documentation of this
310   // behavior.
311   NavigateAndCommit(
312       GURL("https://accounts.google.com/ServiceLogin?continue="
313            "https://passwords.google.com./settings&rart=123"));
314   EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
315
316   // Not a transactional reauth page.
317   NavigateAndCommit(
318       GURL("https://accounts.google.com/ServiceLogin?continue="
319            "https://passwords.google.com/settings"));
320   EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
321
322   // Should be enabled for other transactional reauth pages.
323   NavigateAndCommit(
324       GURL("https://accounts.google.com/ServiceLogin?continue="
325            "https://mail.google.com&rart=234"));
326   EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
327
328   // Reauth pages are only on accounts.google.com
329   NavigateAndCommit(
330       GURL("https://other.site.com/ServiceLogin?continue="
331            "https://passwords.google.com&rart=234"));
332   EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
333 }
334
335 TEST_F(ChromePasswordManagerClientTest, CredentialManagerOnNotifyFailedSignIn) {
336   scoped_ptr<TestChromePasswordManagerClient> client(
337       new TestChromePasswordManagerClient(web_contents()));
338
339   password_manager::CredentialInfo info(base::ASCIIToUTF16("id"),
340                                         base::ASCIIToUTF16("name"),
341                                         GURL("https://example.com/image.png"));
342   client->OnNotifyFailedSignIn(kRequestId, info);
343
344   const uint32 kMsgID = CredentialManagerMsg_AcknowledgeFailedSignIn::ID;
345   const IPC::Message* message =
346       process()->sink().GetFirstMessageMatching(kMsgID);
347   EXPECT_TRUE(message);
348   process()->sink().ClearMessages();
349 }
350
351 TEST_F(ChromePasswordManagerClientTest, CredentialManagerOnNotifySignedIn) {
352   scoped_ptr<TestChromePasswordManagerClient> client(
353       new TestChromePasswordManagerClient(web_contents()));
354
355   password_manager::CredentialInfo info(base::ASCIIToUTF16("id"),
356                                         base::ASCIIToUTF16("name"),
357                                         GURL("https://example.com/image.png"));
358   client->OnNotifySignedIn(kRequestId, info);
359
360   const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedIn::ID;
361   const IPC::Message* message =
362       process()->sink().GetFirstMessageMatching(kMsgID);
363   EXPECT_TRUE(message);
364   process()->sink().ClearMessages();
365 }
366
367 TEST_F(ChromePasswordManagerClientTest, CredentialManagerOnNotifySignedOut) {
368   scoped_ptr<TestChromePasswordManagerClient> client(
369       new TestChromePasswordManagerClient(web_contents()));
370
371   client->OnNotifySignedOut(kRequestId);
372
373   const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedOut::ID;
374   const IPC::Message* message =
375       process()->sink().GetFirstMessageMatching(kMsgID);
376   EXPECT_TRUE(message);
377   process()->sink().ClearMessages();
378 }
379
380 TEST_F(ChromePasswordManagerClientTest, CredentialManagerOnRequestCredential) {
381   scoped_ptr<TestChromePasswordManagerClient> client(
382       new TestChromePasswordManagerClient(web_contents()));
383
384   std::vector<GURL> federations;
385   client->OnRequestCredential(kRequestId, false, federations);
386
387   const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
388   const IPC::Message* message =
389       process()->sink().GetFirstMessageMatching(kMsgID);
390   EXPECT_TRUE(message);
391   process()->sink().ClearMessages();
392 }