1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file.
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/file_util.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/path_service.h"
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_number_conversions.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/utf_string_conversions.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/webdata/web_database.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/chrome_paths.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "testing/gtest/include/gtest/gtest.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/glue/password_form.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing base::Time;
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing base::TimeDelta;
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing webkit_glue::PasswordForm;
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass LoginsTableTest : public testing::Test {
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoginsTableTest() {}
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ~LoginsTableTest() {}
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected:
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void SetUp() {
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PathService::Get(chrome::DIR_TEST_DATA, &file_);
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string test_db = "TestWebDatabase" +
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        base::Int64ToString(Time::Now().ToTimeT()) +
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ".db";
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    file_ = file_.AppendASCII(test_db);
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    file_util::Delete(file_, false);
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void TearDown() {
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    file_util::Delete(file_, false);
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath file_;
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(LoginsTableTest);
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(LoginsTableTest, Logins) {
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WebDatabase db;
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(sql::INIT_OK, db.Init(file_));
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<PasswordForm*> result;
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify the database is empty.
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0U, result.size());
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Example password form.
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form;
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.origin = GURL("http://www.google.com/accounts/LoginAuth");
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.action = GURL("http://www.google.com/accounts/Login");
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.username_element = ASCIIToUTF16("Email");
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.username_value = ASCIIToUTF16("test@gmail.com");
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.password_element = ASCIIToUTF16("Passwd");
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.password_value = ASCIIToUTF16("test");
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.submit_element = ASCIIToUTF16("signIn");
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.signon_realm = "http://www.google.com/";
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.ssl_valid = false;
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.preferred = false;
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.scheme = PasswordForm::SCHEME_HTML;
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Add it and make sure it is there.
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->AddLogin(form));
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Match against an exact copy.
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form, &result));
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The example site changes...
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form2(form);
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form2.origin = GURL("http://www.google.com/new/accounts/LoginAuth");
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form2.submit_element = ASCIIToUTF16("reallySignIn");
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Match against an inexact copy
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form2, &result));
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Uh oh, the site changed origin & action URL's all at once!
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form3(form2);
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form3.action = GURL("http://www.google.com/new/accounts/Login");
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // signon_realm is the same, should match.
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form3, &result));
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Imagine the site moves to a secure server for login.
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form4(form3);
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form4.signon_realm = "https://www.google.com/";
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form4.ssl_valid = true;
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We have only an http record, so no match for this.
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form4, &result));
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0U, result.size());
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Let's imagine the user logs into the secure site.
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->AddLogin(form4));
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2U, result.size());
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[1];
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Now the match works
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form4, &result));
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The user chose to forget the original but not the new.
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->RemoveLogin(form));
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The old form wont match the new site (http vs https).
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form, &result));
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0U, result.size());
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The user's request for the HTTPS site is intercepted
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // by an attacker who presents an invalid SSL cert.
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form5(form4);
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form5.ssl_valid = 0;
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // It will match in this case.
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form5, &result));
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // User changes his password.
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form6(form5);
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form6.password_value = ASCIIToUTF16("test6");
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form6.preferred = true;
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We update, and check to make sure it matches the
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // old form, and there is only one record.
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->UpdateLogin(form6));
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // matches
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form5, &result));
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Only one record.
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // password element was updated.
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(form6.password_value, result[0]->password_value);
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Preferred login.
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(form6.preferred);
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete result[0];
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result.clear();
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Make sure everything can disappear.
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->RemoveLogin(form4));
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0U, result.size());
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic bool AddTimestampedLogin(WebDatabase* db, std::string url,
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                const std::string& unique_string,
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                const Time& time) {
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Example password form.
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form;
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.origin = GURL(url + std::string("/LoginAuth"));
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.username_element = ASCIIToUTF16(unique_string);
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.username_value = ASCIIToUTF16(unique_string);
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.password_element = ASCIIToUTF16(unique_string);
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.submit_element = ASCIIToUTF16("signIn");
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.signon_realm = url;
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.date_created = time;
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return db->GetLoginsTable()->AddLogin(form);
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic void ClearResults(std::vector<PasswordForm*>* results) {
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < results->size(); ++i) {
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete (*results)[i];
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  results->clear();
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(LoginsTableTest, ClearPrivateData_SavedPasswords) {
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WebDatabase db;
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(sql::INIT_OK, db.Init(file_));
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<PasswordForm*> result;
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify the database is empty.
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0U, result.size());
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Time now = Time::Now();
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TimeDelta one_day = TimeDelta::FromDays(1);
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create one with a 0 time.
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(AddTimestampedLogin(&db, "1", "foo1", Time()));
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create one for now and +/- 1 day.
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(AddTimestampedLogin(&db, "2", "foo2", now - one_day));
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(AddTimestampedLogin(&db, "3", "foo3", now));
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(AddTimestampedLogin(&db, "4", "foo4", now + one_day));
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify inserts worked.
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(4U, result.size());
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ClearResults(&result);
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Delete everything from today's date and on.
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  db.GetLoginsTable()->RemoveLoginsCreatedBetween(now, Time());
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should have deleted half of what we inserted.
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2U, result.size());
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ClearResults(&result);
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Delete with 0 date (should delete all).
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  db.GetLoginsTable()->RemoveLoginsCreatedBetween(Time(), Time());
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify nothing is left.
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0U, result.size());
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(LoginsTableTest, BlacklistedLogins) {
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WebDatabase db;
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(sql::INIT_OK, db.Init(file_));
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<PasswordForm*> result;
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify the database is empty.
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(0U, result.size());
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Save a form as blacklisted.
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PasswordForm form;
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.origin = GURL("http://www.google.com/accounts/LoginAuth");
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.action = GURL("http://www.google.com/accounts/Login");
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.username_element = ASCIIToUTF16("Email");
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.password_element = ASCIIToUTF16("Passwd");
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.submit_element = ASCIIToUTF16("signIn");
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.signon_realm = "http://www.google.com/";
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.ssl_valid = false;
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.preferred = true;
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.blacklisted_by_user = true;
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  form.scheme = PasswordForm::SCHEME_HTML;
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->AddLogin(form));
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Get all non-blacklisted logins (should be none).
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, false));
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(0U, result.size());
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // GetLogins should give the blacklisted result.
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetLogins(form, &result));
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ClearResults(&result);
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // So should GetAll including blacklisted.
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(db.GetLoginsTable()->GetAllLogins(&result, true));
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1U, result.size());
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ClearResults(&result);
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
279