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

Side by Side Diff: components/password_manager/core/browser/form_fetcher_impl.cc

Issue 2912783002: Measure how often PSL and same-organization name credentials are suppressed. (Closed)
Patch Set: Fix stupid error. Created 3 years, 6 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/password_manager/core/browser/form_fetcher_impl.h" 5 #include "components/password_manager/core/browser/form_fetcher_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "components/autofill/core/common/password_form.h" 12 #include "components/autofill/core/common/password_form.h"
13 #include "components/password_manager/core/browser/browser_save_password_progres s_logger.h" 13 #include "components/password_manager/core/browser/browser_save_password_progres s_logger.h"
14 #include "components/password_manager/core/browser/credentials_filter.h" 14 #include "components/password_manager/core/browser/credentials_filter.h"
15 #include "components/password_manager/core/browser/password_manager_client.h" 15 #include "components/password_manager/core/browser/password_manager_client.h"
16 #include "components/password_manager/core/browser/password_manager_util.h" 16 #include "components/password_manager/core/browser/password_manager_util.h"
17 #include "components/password_manager/core/browser/password_store.h" 17 #include "components/password_manager/core/browser/password_store.h"
18 #include "components/password_manager/core/browser/psl_matching_helper.h"
18 #include "components/password_manager/core/browser/statistics_table.h" 19 #include "components/password_manager/core/browser/statistics_table.h"
19 20
20 using autofill::PasswordForm; 21 using autofill::PasswordForm;
21 22
22 // Shorten the name to spare line breaks. The code provides enough context 23 // Shorten the name to spare line breaks. The code provides enough context
23 // already. 24 // already.
24 using Logger = autofill::SavePasswordProgressLogger; 25 using Logger = autofill::SavePasswordProgressLogger;
25 26
26 namespace password_manager { 27 namespace password_manager {
27 28
(...skipping 11 matching lines...) Expand all
39 40
40 // Move out federated matches. 41 // Move out federated matches.
41 std::vector<std::unique_ptr<PasswordForm>> federated_matches; 42 std::vector<std::unique_ptr<PasswordForm>> federated_matches;
42 federated_matches.resize(store_results->end() - first_federated); 43 federated_matches.resize(store_results->end() - first_federated);
43 std::move(first_federated, store_results->end(), federated_matches.begin()); 44 std::move(first_federated, store_results->end(), federated_matches.begin());
44 45
45 store_results->erase(first_federated, store_results->end()); 46 store_results->erase(first_federated, store_results->end());
46 return federated_matches; 47 return federated_matches;
47 } 48 }
48 49
50 void SplitSuppressedFormsAndAssignTo(
51 const PasswordStore::FormDigest& observed_form_digest,
52 std::vector<std::unique_ptr<PasswordForm>> suppressed_forms,
kolos1 2017/05/30 07:02:29 Should we pass |suppressed_forms| by value, by not
engedy 2017/05/30 08:47:43 We do pass it by value.
kolos1 2017/05/30 09:16:36 oops, actually I suggested the opposite. I believe
engedy 2017/05/30 13:51:35 I dunno -- passing it by value allows for std::mov
53 std::vector<std::unique_ptr<PasswordForm>>* same_origin_https_forms,
54 std::vector<std::unique_ptr<PasswordForm>>* psl_matching_forms,
55 std::vector<std::unique_ptr<PasswordForm>>* same_organization_name_forms) {
kolos1 2017/05/30 07:02:29 Optional: add DCHECKs for vectors here
engedy 2017/05/30 08:47:43 Done.
56 same_origin_https_forms->clear();
57 psl_matching_forms->clear();
58 same_organization_name_forms->clear();
59 for (auto& form : suppressed_forms) {
60 switch (GetMatchResult(*form, observed_form_digest)) {
61 case MatchResult::PSL_MATCH:
62 psl_matching_forms->push_back(std::move(form));
63 break;
64 case MatchResult::NO_MATCH:
65 if (form->origin.host() != observed_form_digest.origin.host()) {
66 same_organization_name_forms->push_back(std::move(form));
67 } else if (form->origin.SchemeIs(url::kHttpsScheme) &&
68 observed_form_digest.origin.SchemeIs(url::kHttpScheme)) {
69 same_origin_https_forms->push_back(std::move(form));
70 } else {
71 // HTTP form suppressed on HTTPS observed page: The HTTP->HTTPS
72 // migration can leave tons of such HTTP forms behind, ignore these.
73 }
74 break;
75 case MatchResult::EXACT_MATCH:
76 case MatchResult::FEDERATED_MATCH:
77 case MatchResult::FEDERATED_PSL_MATCH:
78 NOTREACHED() << "Suppressed match cannot be exact or federated.";
79 break;
80 }
81 }
82 }
83
49 // Create a vector of const PasswordForm from a vector of 84 // Create a vector of const PasswordForm from a vector of
50 // unique_ptr<PasswordForm> by applying get() item-wise. 85 // unique_ptr<PasswordForm> by applying get() item-wise.
51 std::vector<const PasswordForm*> MakeWeakCopies( 86 std::vector<const PasswordForm*> MakeWeakCopies(
52 const std::vector<std::unique_ptr<PasswordForm>>& owning) { 87 const std::vector<std::unique_ptr<PasswordForm>>& owning) {
53 std::vector<const PasswordForm*> result(owning.size()); 88 std::vector<const PasswordForm*> result(owning.size());
54 std::transform( 89 std::transform(
55 owning.begin(), owning.end(), result.begin(), 90 owning.begin(), owning.end(), result.begin(),
56 [](const std::unique_ptr<PasswordForm>& ptr) { return ptr.get(); }); 91 [](const std::unique_ptr<PasswordForm>& ptr) { return ptr.get(); });
57 return result; 92 return result;
58 } 93 }
59 94
60 // Create a vector of unique_ptr<PasswordForm> from another such vector by 95 // Create a vector of unique_ptr<PasswordForm> from another such vector by
61 // copying the pointed-to forms. 96 // copying the pointed-to forms.
62 std::vector<std::unique_ptr<PasswordForm>> MakeCopies( 97 std::vector<std::unique_ptr<PasswordForm>> MakeCopies(
63 const std::vector<std::unique_ptr<PasswordForm>>& source) { 98 const std::vector<std::unique_ptr<PasswordForm>>& source) {
64 std::vector<std::unique_ptr<PasswordForm>> result(source.size()); 99 std::vector<std::unique_ptr<PasswordForm>> result(source.size());
65 std::transform(source.begin(), source.end(), result.begin(), 100 std::transform(source.begin(), source.end(), result.begin(),
66 [](const std::unique_ptr<PasswordForm>& ptr) { 101 [](const std::unique_ptr<PasswordForm>& ptr) {
67 return base::MakeUnique<PasswordForm>(*ptr); 102 return base::MakeUnique<PasswordForm>(*ptr);
68 }); 103 });
69 return result; 104 return result;
70 } 105 }
71 106
72 } // namespace 107 } // namespace
73 108
74 FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest, 109 FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest,
75 const PasswordManagerClient* client, 110 const PasswordManagerClient* client,
76 bool should_migrate_http_passwords, 111 bool should_migrate_http_passwords,
77 bool should_query_suppressed_https_forms) 112 bool should_query_suppressed_forms)
78 : form_digest_(std::move(form_digest)), 113 : form_digest_(std::move(form_digest)),
79 client_(client), 114 client_(client),
80 should_migrate_http_passwords_(should_migrate_http_passwords), 115 should_migrate_http_passwords_(should_migrate_http_passwords),
81 should_query_suppressed_https_forms_( 116 should_query_suppressed_forms_(should_query_suppressed_forms) {}
82 should_query_suppressed_https_forms) {}
83 117
84 FormFetcherImpl::~FormFetcherImpl() = default; 118 FormFetcherImpl::~FormFetcherImpl() = default;
85 119
86 void FormFetcherImpl::AddConsumer(FormFetcher::Consumer* consumer) { 120 void FormFetcherImpl::AddConsumer(FormFetcher::Consumer* consumer) {
87 DCHECK(consumer); 121 DCHECK(consumer);
88 consumers_.insert(consumer); 122 consumers_.insert(consumer);
89 if (state_ == State::NOT_WAITING) 123 if (state_ == State::NOT_WAITING)
90 consumer->ProcessMatches(weak_non_federated_, filtered_count_); 124 consumer->ProcessMatches(weak_non_federated_, filtered_count_);
91 } 125 }
92 126
(...skipping 11 matching lines...) Expand all
104 return interactions_stats_; 138 return interactions_stats_;
105 } 139 }
106 140
107 const std::vector<const PasswordForm*>& FormFetcherImpl::GetFederatedMatches() 141 const std::vector<const PasswordForm*>& FormFetcherImpl::GetFederatedMatches()
108 const { 142 const {
109 return weak_federated_; 143 return weak_federated_;
110 } 144 }
111 145
112 const std::vector<const PasswordForm*>& 146 const std::vector<const PasswordForm*>&
113 FormFetcherImpl::GetSuppressedHTTPSForms() const { 147 FormFetcherImpl::GetSuppressedHTTPSForms() const {
114 return weak_suppressed_https_forms_; 148 return weak_suppressed_same_origin_https_forms_;
115 } 149 }
116 150
117 bool FormFetcherImpl::DidCompleteQueryingSuppressedHTTPSForms() const { 151 const std::vector<const PasswordForm*>&
118 return did_complete_querying_suppressed_https_forms_; 152 FormFetcherImpl::GetSuppressedPSLMatchingForms() const {
153 return weak_suppressed_psl_matching_forms_;
154 }
155
156 const std::vector<const PasswordForm*>&
157 FormFetcherImpl::GetSuppressedSameOrganizationNameForms() const {
158 return weak_suppressed_same_organization_name_forms_;
159 }
160
161 bool FormFetcherImpl::DidCompleteQueryingSuppressedForms() const {
162 return did_complete_querying_suppressed_forms_;
119 } 163 }
120 164
121 void FormFetcherImpl::OnGetPasswordStoreResults( 165 void FormFetcherImpl::OnGetPasswordStoreResults(
122 std::vector<std::unique_ptr<PasswordForm>> results) { 166 std::vector<std::unique_ptr<PasswordForm>> results) {
123 DCHECK_EQ(State::WAITING, state_); 167 DCHECK_EQ(State::WAITING, state_);
124 168
125 if (need_to_refetch_) { 169 if (need_to_refetch_) {
126 // The received results are no longer up to date, need to re-request. 170 // The received results are no longer up to date, need to re-request.
127 state_ = State::NOT_WAITING; 171 state_ = State::NOT_WAITING;
128 Fetch(); 172 Fetch();
129 need_to_refetch_ = false; 173 need_to_refetch_ = false;
130 return; 174 return;
131 } 175 }
132 176
133 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; 177 std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
134 if (password_manager_util::IsLoggingActive(client_)) { 178 if (password_manager_util::IsLoggingActive(client_)) {
135 logger.reset( 179 logger.reset(
136 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); 180 new BrowserSavePasswordProgressLogger(client_->GetLogManager()));
137 logger->LogMessage(Logger::STRING_ON_GET_STORE_RESULTS_METHOD); 181 logger->LogMessage(Logger::STRING_ON_GET_STORE_RESULTS_METHOD);
138 logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size()); 182 logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size());
139 } 183 }
140 184
141 // If this is a non-secure Web origin (i.e. HTTP), kick off the discovery of 185 // If this is a non-secure Web origin (i.e. HTTP), kick off the discovery of
kolos1 2017/05/30 07:02:29 I believe we should change the comment.
engedy 2017/05/30 08:47:43 Oh yes. Done.
142 // credentials stored for the secure version of this origin (i.e. HTTPS), 186 // credentials stored for the secure version of this origin (i.e. HTTPS),
143 // regardless of whether there are some precisely matching |results|. 187 // regardless of whether there are some precisely matching |results|.
144 // 188 //
145 // These results are used only for recording metrics at PasswordFormManager 189 // These results are used only for recording metrics at PasswordFormManager
146 // desctruction time, this is why they are requested so late. 190 // desctruction time, this is why they are requested so late.
147 if (should_query_suppressed_https_forms_ && 191 if (should_query_suppressed_forms_ &&
148 form_digest_.scheme == PasswordForm::SCHEME_HTML && 192 form_digest_.scheme == PasswordForm::SCHEME_HTML &&
149 form_digest_.origin.SchemeIs(url::kHttpScheme)) { 193 GURL(form_digest_.signon_realm).SchemeIsHTTPOrHTTPS()) {
150 suppressed_https_form_fetcher_ = 194 suppressed_form_fetcher_ = base::MakeUnique<SuppressedFormFetcher>(
151 base::MakeUnique<SuppressedHTTPSFormFetcher>(form_digest_.signon_realm, 195 form_digest_.signon_realm, client_, this);
152 client_, this);
153 } 196 }
154 197
155 if (should_migrate_http_passwords_ && results.empty() && 198 if (should_migrate_http_passwords_ && results.empty() &&
156 form_digest_.origin.SchemeIs(url::kHttpsScheme)) { 199 form_digest_.origin.SchemeIs(url::kHttpsScheme)) {
157 http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( 200 http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>(
158 form_digest_.origin, client_, this); 201 form_digest_.origin, client_, this);
159 return; 202 return;
160 } 203 }
161 204
162 ProcessPasswordStoreResults(std::move(results)); 205 ProcessPasswordStoreResults(std::move(results));
163 } 206 }
164 207
165 void FormFetcherImpl::OnGetSiteStatistics( 208 void FormFetcherImpl::OnGetSiteStatistics(
166 std::vector<InteractionsStats> stats) { 209 std::vector<InteractionsStats> stats) {
167 // On Windows the password request may be resolved after the statistics due to 210 // On Windows the password request may be resolved after the statistics due to
168 // importing from IE. 211 // importing from IE.
169 interactions_stats_ = std::move(stats); 212 interactions_stats_ = std::move(stats);
170 } 213 }
171 214
172 void FormFetcherImpl::ProcessMigratedForms( 215 void FormFetcherImpl::ProcessMigratedForms(
173 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { 216 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) {
174 ProcessPasswordStoreResults(std::move(forms)); 217 ProcessPasswordStoreResults(std::move(forms));
175 } 218 }
176 219
177 void FormFetcherImpl::ProcessSuppressedHTTPSForms( 220 void FormFetcherImpl::ProcessSuppressedForms(
178 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { 221 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) {
179 did_complete_querying_suppressed_https_forms_ = true; 222 did_complete_querying_suppressed_forms_ = true;
180 223 SplitSuppressedFormsAndAssignTo(form_digest_, std::move(forms),
181 suppressed_https_forms_ = std::move(forms); 224 &suppressed_same_origin_https_forms_,
182 weak_suppressed_https_forms_ = MakeWeakCopies(suppressed_https_forms_); 225 &suppressed_psl_matching_forms_,
226 &suppressed_same_organization_name_forms_);
227 weak_suppressed_same_origin_https_forms_ =
228 MakeWeakCopies(suppressed_same_origin_https_forms_);
229 weak_suppressed_psl_matching_forms_ =
230 MakeWeakCopies(suppressed_psl_matching_forms_);
231 weak_suppressed_same_organization_name_forms_ =
232 MakeWeakCopies(suppressed_same_organization_name_forms_);
183 } 233 }
184 234
185 void FormFetcherImpl::Fetch() { 235 void FormFetcherImpl::Fetch() {
186 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; 236 std::unique_ptr<BrowserSavePasswordProgressLogger> logger;
187 if (password_manager_util::IsLoggingActive(client_)) { 237 if (password_manager_util::IsLoggingActive(client_)) {
188 logger.reset( 238 logger.reset(
189 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); 239 new BrowserSavePasswordProgressLogger(client_->GetLogManager()));
190 logger->LogMessage(Logger::STRING_FETCH_METHOD); 240 logger->LogMessage(Logger::STRING_FETCH_METHOD);
191 logger->LogNumber(Logger::STRING_FORM_FETCHER_STATE, 241 logger->LogNumber(Logger::STRING_FORM_FETCHER_STATE,
192 static_cast<int>(state_)); 242 static_cast<int>(state_));
(...skipping 23 matching lines...) Expand all
216 password_store->GetSiteStats(form_digest_.origin.GetOrigin(), this); 266 password_store->GetSiteStats(form_digest_.origin.GetOrigin(), this);
217 #endif 267 #endif
218 } 268 }
219 269
220 std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() { 270 std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() {
221 DCHECK_EQ(State::NOT_WAITING, state_); 271 DCHECK_EQ(State::NOT_WAITING, state_);
222 272
223 // Create the copy without the "HTTPS migration" activated. If it was needed, 273 // Create the copy without the "HTTPS migration" activated. If it was needed,
224 // then it was done by |this| already. 274 // then it was done by |this| already.
225 auto result = base::MakeUnique<FormFetcherImpl>( 275 auto result = base::MakeUnique<FormFetcherImpl>(
226 form_digest_, client_, false, should_query_suppressed_https_forms_); 276 form_digest_, client_, false, should_query_suppressed_forms_);
kolos1 2017/05/30 07:02:29 Shall we create a copy with SuppressedFormsFetcher
engedy 2017/05/30 08:47:43 The SuppressedFormFetcher has no state, so I guess
kolos1 2017/05/30 09:16:36 Sorry for confusing comment again :( HTTP migrati
engedy 2017/05/30 13:51:35 Added a unittest to enforce that no fetch is made
227 277
228 result->non_federated_ = MakeCopies(this->non_federated_); 278 result->non_federated_ = MakeCopies(this->non_federated_);
229 result->federated_ = MakeCopies(this->federated_); 279 result->federated_ = MakeCopies(this->federated_);
230 result->interactions_stats_ = this->interactions_stats_; 280 result->interactions_stats_ = this->interactions_stats_;
231 result->suppressed_https_forms_ = MakeCopies(this->suppressed_https_forms_); 281 result->suppressed_same_origin_https_forms_ =
282 MakeCopies(this->suppressed_same_origin_https_forms_);
283 result->suppressed_psl_matching_forms_ =
284 MakeCopies(this->suppressed_psl_matching_forms_);
285 result->suppressed_same_organization_name_forms_ =
286 MakeCopies(this->suppressed_same_organization_name_forms_);
232 287
233 result->weak_non_federated_ = MakeWeakCopies(result->non_federated_); 288 result->weak_non_federated_ = MakeWeakCopies(result->non_federated_);
234 result->weak_federated_ = MakeWeakCopies(result->federated_); 289 result->weak_federated_ = MakeWeakCopies(result->federated_);
235 result->weak_suppressed_https_forms_ = 290 result->weak_suppressed_same_origin_https_forms_ =
236 MakeWeakCopies(result->suppressed_https_forms_); 291 MakeWeakCopies(result->suppressed_same_origin_https_forms_);
292 result->weak_suppressed_psl_matching_forms_ =
293 MakeWeakCopies(result->suppressed_psl_matching_forms_);
294 result->weak_suppressed_same_organization_name_forms_ =
295 MakeWeakCopies(result->suppressed_same_organization_name_forms_);
237 296
238 result->filtered_count_ = this->filtered_count_; 297 result->filtered_count_ = this->filtered_count_;
239 result->state_ = this->state_; 298 result->state_ = this->state_;
240 result->need_to_refetch_ = this->need_to_refetch_; 299 result->need_to_refetch_ = this->need_to_refetch_;
241 300
242 // TODO(crbug.com/703565): remove std::move() once Xcode 9.0+ is required. 301 // TODO(crbug.com/703565): remove std::move() once Xcode 9.0+ is required.
243 return std::move(result); 302 return std::move(result);
244 } 303 }
245 304
246 void FormFetcherImpl::ProcessPasswordStoreResults( 305 void FormFetcherImpl::ProcessPasswordStoreResults(
(...skipping 11 matching lines...) Expand all
258 filtered_count_ = original_count - non_federated_.size(); 317 filtered_count_ = original_count - non_federated_.size();
259 318
260 weak_non_federated_ = MakeWeakCopies(non_federated_); 319 weak_non_federated_ = MakeWeakCopies(non_federated_);
261 weak_federated_ = MakeWeakCopies(federated_); 320 weak_federated_ = MakeWeakCopies(federated_);
262 321
263 for (FormFetcher::Consumer* consumer : consumers_) 322 for (FormFetcher::Consumer* consumer : consumers_)
264 consumer->ProcessMatches(weak_non_federated_, filtered_count_); 323 consumer->ProcessMatches(weak_non_federated_, filtered_count_);
265 } 324 }
266 325
267 } // namespace password_manager 326 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698