Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: chrome/browser/password_manager/password_manager_util_unittest.cc

Issue 2714543006: Clean Obsolete HTTP Data from the Password Store (Closed)
Patch Set: Add Unittest File Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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/password_manager_util.h"
6
7 #include <initializer_list>
8 #include <memory>
9
10 #include "base/memory/ptr_util.h"
11 #include "base/run_loop.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "chrome/browser/password_manager/password_store_factory.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "components/password_manager/core/browser/mock_password_store.h"
16 #include "components/password_manager/core/browser/password_manager_test_utils.h "
17 #include "components/password_manager/core/common/password_manager_pref_names.h"
18 #include "components/prefs/pref_service.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "net/http/transport_security_state.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "url/gurl.h"
24
25 using autofill::PasswordForm;
26 using password_manager::InteractionsStats;
27 using testing::Invoke;
28 using testing::Mock;
29 using testing::NiceMock;
30 using testing::_;
31
32 namespace password_manager_util {
33
34 namespace {
35
36 constexpr char kTestHttpURL[] = "http://example.org/";
37 constexpr char kTestHttpsURL[] = "https://example.org/";
38
39 PasswordForm CreateTestHTTPForm() {
40 PasswordForm form;
41 form.origin = GURL(kTestHttpURL);
42 form.signon_realm = form.origin.spec();
43 form.action = form.origin;
44 form.username_value = base::ASCIIToUTF16("user");
45 form.password_value = base::ASCIIToUTF16("password");
46 return form;
47 }
48
49 PasswordForm CreateTestHTTPSForm() {
50 PasswordForm form;
51 form.origin = GURL(kTestHttpsURL);
52 form.signon_realm = form.origin.spec();
53 form.action = form.origin;
54 form.username_value = base::ASCIIToUTF16("user");
55 form.password_value = base::ASCIIToUTF16("password");
56 return form;
57 }
58
59 InteractionsStats CreateTestHTTPStats() {
60 InteractionsStats stats;
61 stats.origin_domain = GURL(kTestHttpURL);
62 stats.username_value = base::ASCIIToUTF16("user");
63 return stats;
64 }
65
66 InteractionsStats CreateTestHTTPSStats() {
67 InteractionsStats stats;
68 stats.origin_domain = GURL(kTestHttpsURL);
69 stats.username_value = base::ASCIIToUTF16("user");
70 return stats;
71 }
72
73 std::vector<std::unique_ptr<PasswordForm>> MakeResults(
74 const std::vector<PasswordForm>& forms) {
75 std::vector<std::unique_ptr<PasswordForm>> results;
76 results.reserve(forms.size());
77 for (const auto& form : forms)
78 results.push_back(base::MakeUnique<PasswordForm>(form));
79 return results;
80 }
81
82 // Auxiliary class to automatically set and reset the HSTS state for a given
83 // host.
84 class HSTSStateManager {
85 public:
86 HSTSStateManager(net::TransportSecurityState* state,
87 bool is_hsts,
88 const std::string& host);
89 ~HSTSStateManager();
90
91 private:
92 net::TransportSecurityState* state_;
93 const bool is_hsts_;
94 const std::string host_;
95 };
96
97 HSTSStateManager::HSTSStateManager(net::TransportSecurityState* state,
98 bool is_hsts,
99 const std::string& host)
100 : state_(state), is_hsts_(is_hsts), host_(host) {
101 if (is_hsts_) {
102 base::Time expiry = base::Time::Max();
103 bool include_subdomains = false;
104 state_->AddHSTS(host_, expiry, include_subdomains);
105 }
106 }
107
108 HSTSStateManager::~HSTSStateManager() {
109 if (is_hsts_)
110 state_->DeleteDynamicDataForHost(host_);
111 }
112
113 } // namespace
114
115 class PasswordManagerUtilTest : public testing::Test {
116 public:
117 PasswordManagerUtilTest();
118
119 TestingProfile& profile() { return profile_; }
120 password_manager::MockPasswordStore* store() { return store_; }
121 net::TransportSecurityState* GetTransportSecurityState();
122
123 private:
124 content::TestBrowserThreadBundle thread_bundle_;
125 TestingProfile profile_;
126 password_manager::MockPasswordStore* store_;
127 };
128
129 PasswordManagerUtilTest::PasswordManagerUtilTest() {
130 PasswordStoreFactory::GetInstance()->SetTestingFactory(
131 &profile_, password_manager::BuildPasswordStore<
132 content::BrowserContext,
133 NiceMock<password_manager::MockPasswordStore>>);
134
135 store_ = static_cast<password_manager::MockPasswordStore*>(
136 PasswordStoreFactory::GetForProfile(&profile_,
137 ServiceAccessType::EXPLICIT_ACCESS)
vasilii 2017/03/23 17:39:26 Implicit access here
jdoerrie 2017/03/24 14:08:32 Done.
138 .get());
139 }
140
141 net::TransportSecurityState*
142 PasswordManagerUtilTest::GetTransportSecurityState() {
143 return profile()
144 .GetRequestContext()
145 ->GetURLRequestContext()
146 ->transport_security_state();
147 }
148
149 TEST_F(PasswordManagerUtilTest, TestPostHSTSQueryForHostAndProfile) {
150 const GURL test_origin(kTestHttpsURL);
151 for (bool is_hsts : {false, true}) {
152 SCOPED_TRACE(testing::Message()
153 << std::boolalpha << "is_hsts: " << is_hsts);
154
155 HSTSStateManager manager(GetTransportSecurityState(), is_hsts,
156 test_origin.host());
157 // Post query and ensure callback gets run.
vasilii 2017/03/23 17:39:26 Would ba cool to verify that the callback was exec
jdoerrie 2017/03/24 14:08:31 Done.
158 PostHSTSQueryForHostAndProfile(
159 test_origin, &profile(),
160 base::Bind([](bool expectation,
161 bool result) { EXPECT_EQ(expectation, result); },
162 is_hsts));
163 base::RunLoop().RunUntilIdle();
164 }
165 }
166
167 TEST_F(PasswordManagerUtilTest, TestBlacklistDeletion) {
168 for (bool is_http : {false, true}) {
169 for (bool is_blacklisted : {false, true}) {
vasilii 2017/03/23 17:39:26 I didn't get the value of the test for is_blacklis
jdoerrie 2017/03/24 14:08:31 Done.
170 for (bool is_hsts : {false, true}) {
171 SCOPED_TRACE(testing::Message()
172 << std::boolalpha
173 << "(is_http, is_blacklisted, is_hsts): (" << is_http
174 << ", " << is_blacklisted << ", " << is_hsts << ")");
175
176 const bool should_be_deleted = is_http && is_blacklisted && is_hsts;
177
178 PasswordForm form =
179 is_http ? CreateTestHTTPForm() : CreateTestHTTPSForm();
180 form.blacklisted_by_user = is_blacklisted;
181
182 HSTSStateManager manager(GetTransportSecurityState(), is_hsts,
183 form.origin.host());
184
185 EXPECT_CALL(*store(), FillBlacklistLogins(_))
186 .WillOnce(Invoke(
187 [&form](std::vector<std::unique_ptr<autofill::PasswordForm>>*
188 forms) {
189 *forms = MakeResults({form});
190 return true;
191 }));
192
193 EXPECT_CALL(*store(), RemoveLogin(form)).Times(should_be_deleted);
194
195 // Initiate clean up and make sure all aync tasks are run until
196 // completion.
197 DelayCleanObsoleteHttpDataForProfile(&profile(), 0);
198 base::RunLoop().RunUntilIdle();
199
200 // Verify and clear all expectations as well as the preference.
201 Mock::VerifyAndClearExpectations(store());
202 profile().GetPrefs()->SetBoolean(
203 password_manager::prefs::kWasObsoleteHttpDataCleaned, false);
vasilii 2017/03/23 17:39:26 Do you want to check the value of the pref? Same b
jdoerrie 2017/03/24 14:08:31 Done.
204 }
205 }
206 }
207 }
208
209 TEST_F(PasswordManagerUtilTest, TestAutofillableDeletion) {
210 for (bool is_hsts : {false, true}) {
211 for (bool same_host : {false, true}) {
212 for (bool same_user : {false, true}) {
213 for (bool same_pass : {false, true}) {
214 SCOPED_TRACE(testing::Message()
215 << std::boolalpha
216 << "(is_hsts, same_host, same_user, same_pass): ("
217 << is_hsts << ", " << same_host << ", " << same_user
218 << ", " << same_pass);
219
220 const bool should_be_deleted =
221 is_hsts && same_host && same_user && same_pass;
222
223 PasswordForm http_form = CreateTestHTTPForm();
224 PasswordForm https_form = CreateTestHTTPSForm();
225
226 if (!same_host) {
227 GURL::Replacements rep;
228 rep.SetHostStr("a-totally-different-host");
229 http_form.origin = http_form.origin.ReplaceComponents(rep);
230 }
231
232 if (!same_user) {
233 http_form.username_value =
234 https_form.username_value + base::ASCIIToUTF16("-different");
vasilii 2017/03/23 17:39:26 Optional: simple assignment would be more readable
jdoerrie 2017/03/24 14:08:31 Done.
235 }
236
237 if (!same_pass) {
238 http_form.password_value =
239 https_form.password_value + base::ASCIIToUTF16("-different");
240 }
241
242 HSTSStateManager manager(GetTransportSecurityState(), is_hsts,
243 https_form.origin.host());
244
245 EXPECT_CALL(*store(), FillAutofillableLogins(_))
246 .WillOnce(Invoke(
247 [&http_form, &https_form](
248 std::vector<std::unique_ptr<autofill::PasswordForm>>*
249 forms) {
250 *forms = MakeResults({http_form, https_form});
251 return true;
252 }));
253
254 EXPECT_CALL(*store(), RemoveLogin(http_form))
255 .Times(should_be_deleted);
256
257 // Initiate clean up and make sure all aync tasks are run until
258 // completion.
259 DelayCleanObsoleteHttpDataForProfile(&profile(), 0);
260 base::RunLoop().RunUntilIdle();
261
262 // Verify and clear all expectations as well as the preference.
263 Mock::VerifyAndClearExpectations(store());
264 profile().GetPrefs()->SetBoolean(
265 password_manager::prefs::kWasObsoleteHttpDataCleaned, false);
266 }
267 }
268 }
269 }
270 }
271
272 TEST_F(PasswordManagerUtilTest, TestSiteStatsDeletion) {
273 for (bool is_http : {false, true}) {
274 for (bool is_hsts : {false, true}) {
275 SCOPED_TRACE(testing::Message()
276 << std::boolalpha << "(is_http, is_hsts): (" << is_http
277 << ", " << is_hsts);
278
279 const bool should_be_deleted = is_http && is_hsts;
280
281 InteractionsStats stats =
282 is_http ? CreateTestHTTPStats() : CreateTestHTTPSStats();
283
284 HSTSStateManager manager(GetTransportSecurityState(), is_hsts,
285 stats.origin_domain.host());
286
287 EXPECT_CALL(*store(), GetAllSiteStatsImpl()).WillOnce(Invoke([&stats]() {
288 return std::vector<InteractionsStats>({stats});
289 }));
290 EXPECT_CALL(*store(), RemoveSiteStatsImpl(stats.origin_domain))
291 .Times(should_be_deleted);
292
293 // Initiate clean up and make sure all aync tasks are run until
294 // completion.
295 DelayCleanObsoleteHttpDataForProfile(&profile(), 0);
296 base::RunLoop().RunUntilIdle();
297
298 // Verify and clear all expectations as well as the preference.
299 Mock::VerifyAndClearExpectations(store());
300 profile().GetPrefs()->SetBoolean(
301 password_manager::prefs::kWasObsoleteHttpDataCleaned, false);
302 }
303 }
304 }
305
306 } // namespace password_manager_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698