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

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

Powered by Google App Engine
This is Rietveld 408576698