OLD | NEW |
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 Loading... |
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, |
| 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) { |
| 56 DCHECK(same_origin_https_forms); |
| 57 DCHECK(psl_matching_forms); |
| 58 DCHECK(same_organization_name_forms); |
| 59 same_origin_https_forms->clear(); |
| 60 psl_matching_forms->clear(); |
| 61 same_organization_name_forms->clear(); |
| 62 for (auto& form : suppressed_forms) { |
| 63 switch (GetMatchResult(*form, observed_form_digest)) { |
| 64 case MatchResult::PSL_MATCH: |
| 65 psl_matching_forms->push_back(std::move(form)); |
| 66 break; |
| 67 case MatchResult::NO_MATCH: |
| 68 if (form->origin.host() != observed_form_digest.origin.host()) { |
| 69 same_organization_name_forms->push_back(std::move(form)); |
| 70 } else if (form->origin.SchemeIs(url::kHttpsScheme) && |
| 71 observed_form_digest.origin.SchemeIs(url::kHttpScheme)) { |
| 72 same_origin_https_forms->push_back(std::move(form)); |
| 73 } else { |
| 74 // HTTP form suppressed on HTTPS observed page: The HTTP->HTTPS |
| 75 // migration can leave tons of such HTTP forms behind, ignore these. |
| 76 } |
| 77 break; |
| 78 case MatchResult::EXACT_MATCH: |
| 79 case MatchResult::FEDERATED_MATCH: |
| 80 case MatchResult::FEDERATED_PSL_MATCH: |
| 81 NOTREACHED() << "Suppressed match cannot be exact or federated."; |
| 82 break; |
| 83 } |
| 84 } |
| 85 } |
| 86 |
49 // Create a vector of const PasswordForm from a vector of | 87 // Create a vector of const PasswordForm from a vector of |
50 // unique_ptr<PasswordForm> by applying get() item-wise. | 88 // unique_ptr<PasswordForm> by applying get() item-wise. |
51 std::vector<const PasswordForm*> MakeWeakCopies( | 89 std::vector<const PasswordForm*> MakeWeakCopies( |
52 const std::vector<std::unique_ptr<PasswordForm>>& owning) { | 90 const std::vector<std::unique_ptr<PasswordForm>>& owning) { |
53 std::vector<const PasswordForm*> result(owning.size()); | 91 std::vector<const PasswordForm*> result(owning.size()); |
54 std::transform( | 92 std::transform( |
55 owning.begin(), owning.end(), result.begin(), | 93 owning.begin(), owning.end(), result.begin(), |
56 [](const std::unique_ptr<PasswordForm>& ptr) { return ptr.get(); }); | 94 [](const std::unique_ptr<PasswordForm>& ptr) { return ptr.get(); }); |
57 return result; | 95 return result; |
58 } | 96 } |
59 | 97 |
60 // Create a vector of unique_ptr<PasswordForm> from another such vector by | 98 // Create a vector of unique_ptr<PasswordForm> from another such vector by |
61 // copying the pointed-to forms. | 99 // copying the pointed-to forms. |
62 std::vector<std::unique_ptr<PasswordForm>> MakeCopies( | 100 std::vector<std::unique_ptr<PasswordForm>> MakeCopies( |
63 const std::vector<std::unique_ptr<PasswordForm>>& source) { | 101 const std::vector<std::unique_ptr<PasswordForm>>& source) { |
64 std::vector<std::unique_ptr<PasswordForm>> result(source.size()); | 102 std::vector<std::unique_ptr<PasswordForm>> result(source.size()); |
65 std::transform(source.begin(), source.end(), result.begin(), | 103 std::transform(source.begin(), source.end(), result.begin(), |
66 [](const std::unique_ptr<PasswordForm>& ptr) { | 104 [](const std::unique_ptr<PasswordForm>& ptr) { |
67 return base::MakeUnique<PasswordForm>(*ptr); | 105 return base::MakeUnique<PasswordForm>(*ptr); |
68 }); | 106 }); |
69 return result; | 107 return result; |
70 } | 108 } |
71 | 109 |
72 } // namespace | 110 } // namespace |
73 | 111 |
74 FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest, | 112 FormFetcherImpl::FormFetcherImpl(PasswordStore::FormDigest form_digest, |
75 const PasswordManagerClient* client, | 113 const PasswordManagerClient* client, |
76 bool should_migrate_http_passwords, | 114 bool should_migrate_http_passwords, |
77 bool should_query_suppressed_https_forms) | 115 bool should_query_suppressed_forms) |
78 : form_digest_(std::move(form_digest)), | 116 : form_digest_(std::move(form_digest)), |
79 client_(client), | 117 client_(client), |
80 should_migrate_http_passwords_(should_migrate_http_passwords), | 118 should_migrate_http_passwords_(should_migrate_http_passwords), |
81 should_query_suppressed_https_forms_( | 119 should_query_suppressed_forms_(should_query_suppressed_forms) {} |
82 should_query_suppressed_https_forms) {} | |
83 | 120 |
84 FormFetcherImpl::~FormFetcherImpl() = default; | 121 FormFetcherImpl::~FormFetcherImpl() = default; |
85 | 122 |
86 void FormFetcherImpl::AddConsumer(FormFetcher::Consumer* consumer) { | 123 void FormFetcherImpl::AddConsumer(FormFetcher::Consumer* consumer) { |
87 DCHECK(consumer); | 124 DCHECK(consumer); |
88 consumers_.insert(consumer); | 125 consumers_.insert(consumer); |
89 if (state_ == State::NOT_WAITING) | 126 if (state_ == State::NOT_WAITING) |
90 consumer->ProcessMatches(weak_non_federated_, filtered_count_); | 127 consumer->ProcessMatches(weak_non_federated_, filtered_count_); |
91 } | 128 } |
92 | 129 |
(...skipping 11 matching lines...) Expand all Loading... |
104 return interactions_stats_; | 141 return interactions_stats_; |
105 } | 142 } |
106 | 143 |
107 const std::vector<const PasswordForm*>& FormFetcherImpl::GetFederatedMatches() | 144 const std::vector<const PasswordForm*>& FormFetcherImpl::GetFederatedMatches() |
108 const { | 145 const { |
109 return weak_federated_; | 146 return weak_federated_; |
110 } | 147 } |
111 | 148 |
112 const std::vector<const PasswordForm*>& | 149 const std::vector<const PasswordForm*>& |
113 FormFetcherImpl::GetSuppressedHTTPSForms() const { | 150 FormFetcherImpl::GetSuppressedHTTPSForms() const { |
114 return weak_suppressed_https_forms_; | 151 return weak_suppressed_same_origin_https_forms_; |
115 } | 152 } |
116 | 153 |
117 bool FormFetcherImpl::DidCompleteQueryingSuppressedHTTPSForms() const { | 154 const std::vector<const PasswordForm*>& |
118 return did_complete_querying_suppressed_https_forms_; | 155 FormFetcherImpl::GetSuppressedPSLMatchingForms() const { |
| 156 return weak_suppressed_psl_matching_forms_; |
| 157 } |
| 158 |
| 159 const std::vector<const PasswordForm*>& |
| 160 FormFetcherImpl::GetSuppressedSameOrganizationNameForms() const { |
| 161 return weak_suppressed_same_organization_name_forms_; |
| 162 } |
| 163 |
| 164 bool FormFetcherImpl::DidCompleteQueryingSuppressedForms() const { |
| 165 return did_complete_querying_suppressed_forms_; |
119 } | 166 } |
120 | 167 |
121 void FormFetcherImpl::OnGetPasswordStoreResults( | 168 void FormFetcherImpl::OnGetPasswordStoreResults( |
122 std::vector<std::unique_ptr<PasswordForm>> results) { | 169 std::vector<std::unique_ptr<PasswordForm>> results) { |
123 DCHECK_EQ(State::WAITING, state_); | 170 DCHECK_EQ(State::WAITING, state_); |
124 | 171 |
125 if (need_to_refetch_) { | 172 if (need_to_refetch_) { |
126 // The received results are no longer up to date, need to re-request. | 173 // The received results are no longer up to date, need to re-request. |
127 state_ = State::NOT_WAITING; | 174 state_ = State::NOT_WAITING; |
128 Fetch(); | 175 Fetch(); |
129 need_to_refetch_ = false; | 176 need_to_refetch_ = false; |
130 return; | 177 return; |
131 } | 178 } |
132 | 179 |
133 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; | 180 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; |
134 if (password_manager_util::IsLoggingActive(client_)) { | 181 if (password_manager_util::IsLoggingActive(client_)) { |
135 logger.reset( | 182 logger.reset( |
136 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); | 183 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); |
137 logger->LogMessage(Logger::STRING_ON_GET_STORE_RESULTS_METHOD); | 184 logger->LogMessage(Logger::STRING_ON_GET_STORE_RESULTS_METHOD); |
138 logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size()); | 185 logger->LogNumber(Logger::STRING_NUMBER_RESULTS, results.size()); |
139 } | 186 } |
140 | 187 |
141 // If this is a non-secure Web origin (i.e. HTTP), kick off the discovery of | 188 // Kick off the discovery of suppressed credentials, regardless of whether |
142 // credentials stored for the secure version of this origin (i.e. HTTPS), | 189 // there are some precisely matching |results|. These results are used only |
143 // regardless of whether there are some precisely matching |results|. | 190 // for recording metrics at PasswordFormManager desctruction time, this is why |
144 // | 191 // they are requested this late. |
145 // These results are used only for recording metrics at PasswordFormManager | 192 if (should_query_suppressed_forms_ && |
146 // desctruction time, this is why they are requested so late. | |
147 if (should_query_suppressed_https_forms_ && | |
148 form_digest_.scheme == PasswordForm::SCHEME_HTML && | 193 form_digest_.scheme == PasswordForm::SCHEME_HTML && |
149 form_digest_.origin.SchemeIs(url::kHttpScheme)) { | 194 GURL(form_digest_.signon_realm).SchemeIsHTTPOrHTTPS()) { |
150 suppressed_https_form_fetcher_ = | 195 suppressed_form_fetcher_ = base::MakeUnique<SuppressedFormFetcher>( |
151 base::MakeUnique<SuppressedHTTPSFormFetcher>(form_digest_.signon_realm, | 196 form_digest_.signon_realm, client_, this); |
152 client_, this); | |
153 } | 197 } |
154 | 198 |
155 if (should_migrate_http_passwords_ && results.empty() && | 199 if (should_migrate_http_passwords_ && results.empty() && |
156 form_digest_.origin.SchemeIs(url::kHttpsScheme)) { | 200 form_digest_.origin.SchemeIs(url::kHttpsScheme)) { |
157 http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( | 201 http_migrator_ = base::MakeUnique<HttpPasswordStoreMigrator>( |
158 form_digest_.origin, client_, this); | 202 form_digest_.origin, client_, this); |
159 return; | 203 return; |
160 } | 204 } |
161 | 205 |
162 ProcessPasswordStoreResults(std::move(results)); | 206 ProcessPasswordStoreResults(std::move(results)); |
163 } | 207 } |
164 | 208 |
165 void FormFetcherImpl::OnGetSiteStatistics( | 209 void FormFetcherImpl::OnGetSiteStatistics( |
166 std::vector<InteractionsStats> stats) { | 210 std::vector<InteractionsStats> stats) { |
167 // On Windows the password request may be resolved after the statistics due to | 211 // On Windows the password request may be resolved after the statistics due to |
168 // importing from IE. | 212 // importing from IE. |
169 interactions_stats_ = std::move(stats); | 213 interactions_stats_ = std::move(stats); |
170 } | 214 } |
171 | 215 |
172 void FormFetcherImpl::ProcessMigratedForms( | 216 void FormFetcherImpl::ProcessMigratedForms( |
173 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { | 217 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { |
174 ProcessPasswordStoreResults(std::move(forms)); | 218 ProcessPasswordStoreResults(std::move(forms)); |
175 } | 219 } |
176 | 220 |
177 void FormFetcherImpl::ProcessSuppressedHTTPSForms( | 221 void FormFetcherImpl::ProcessSuppressedForms( |
178 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { | 222 std::vector<std::unique_ptr<autofill::PasswordForm>> forms) { |
179 did_complete_querying_suppressed_https_forms_ = true; | 223 did_complete_querying_suppressed_forms_ = true; |
180 | 224 SplitSuppressedFormsAndAssignTo(form_digest_, std::move(forms), |
181 suppressed_https_forms_ = std::move(forms); | 225 &suppressed_same_origin_https_forms_, |
182 weak_suppressed_https_forms_ = MakeWeakCopies(suppressed_https_forms_); | 226 &suppressed_psl_matching_forms_, |
| 227 &suppressed_same_organization_name_forms_); |
| 228 weak_suppressed_same_origin_https_forms_ = |
| 229 MakeWeakCopies(suppressed_same_origin_https_forms_); |
| 230 weak_suppressed_psl_matching_forms_ = |
| 231 MakeWeakCopies(suppressed_psl_matching_forms_); |
| 232 weak_suppressed_same_organization_name_forms_ = |
| 233 MakeWeakCopies(suppressed_same_organization_name_forms_); |
183 } | 234 } |
184 | 235 |
185 void FormFetcherImpl::Fetch() { | 236 void FormFetcherImpl::Fetch() { |
186 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; | 237 std::unique_ptr<BrowserSavePasswordProgressLogger> logger; |
187 if (password_manager_util::IsLoggingActive(client_)) { | 238 if (password_manager_util::IsLoggingActive(client_)) { |
188 logger.reset( | 239 logger.reset( |
189 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); | 240 new BrowserSavePasswordProgressLogger(client_->GetLogManager())); |
190 logger->LogMessage(Logger::STRING_FETCH_METHOD); | 241 logger->LogMessage(Logger::STRING_FETCH_METHOD); |
191 logger->LogNumber(Logger::STRING_FORM_FETCHER_STATE, | 242 logger->LogNumber(Logger::STRING_FORM_FETCHER_STATE, |
192 static_cast<int>(state_)); | 243 static_cast<int>(state_)); |
(...skipping 23 matching lines...) Expand all Loading... |
216 password_store->GetSiteStats(form_digest_.origin.GetOrigin(), this); | 267 password_store->GetSiteStats(form_digest_.origin.GetOrigin(), this); |
217 #endif | 268 #endif |
218 } | 269 } |
219 | 270 |
220 std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() { | 271 std::unique_ptr<FormFetcher> FormFetcherImpl::Clone() { |
221 DCHECK_EQ(State::NOT_WAITING, state_); | 272 DCHECK_EQ(State::NOT_WAITING, state_); |
222 | 273 |
223 // Create the copy without the "HTTPS migration" activated. If it was needed, | 274 // Create the copy without the "HTTPS migration" activated. If it was needed, |
224 // then it was done by |this| already. | 275 // then it was done by |this| already. |
225 auto result = base::MakeUnique<FormFetcherImpl>( | 276 auto result = base::MakeUnique<FormFetcherImpl>( |
226 form_digest_, client_, false, should_query_suppressed_https_forms_); | 277 form_digest_, client_, false, should_query_suppressed_forms_); |
227 | 278 |
228 result->non_federated_ = MakeCopies(this->non_federated_); | 279 result->non_federated_ = MakeCopies(this->non_federated_); |
229 result->federated_ = MakeCopies(this->federated_); | 280 result->federated_ = MakeCopies(this->federated_); |
230 result->interactions_stats_ = this->interactions_stats_; | 281 result->interactions_stats_ = this->interactions_stats_; |
231 result->suppressed_https_forms_ = MakeCopies(this->suppressed_https_forms_); | 282 result->suppressed_same_origin_https_forms_ = |
| 283 MakeCopies(this->suppressed_same_origin_https_forms_); |
| 284 result->suppressed_psl_matching_forms_ = |
| 285 MakeCopies(this->suppressed_psl_matching_forms_); |
| 286 result->suppressed_same_organization_name_forms_ = |
| 287 MakeCopies(this->suppressed_same_organization_name_forms_); |
232 | 288 |
233 result->weak_non_federated_ = MakeWeakCopies(result->non_federated_); | 289 result->weak_non_federated_ = MakeWeakCopies(result->non_federated_); |
234 result->weak_federated_ = MakeWeakCopies(result->federated_); | 290 result->weak_federated_ = MakeWeakCopies(result->federated_); |
235 result->weak_suppressed_https_forms_ = | 291 result->weak_suppressed_same_origin_https_forms_ = |
236 MakeWeakCopies(result->suppressed_https_forms_); | 292 MakeWeakCopies(result->suppressed_same_origin_https_forms_); |
| 293 result->weak_suppressed_psl_matching_forms_ = |
| 294 MakeWeakCopies(result->suppressed_psl_matching_forms_); |
| 295 result->weak_suppressed_same_organization_name_forms_ = |
| 296 MakeWeakCopies(result->suppressed_same_organization_name_forms_); |
237 | 297 |
238 result->filtered_count_ = this->filtered_count_; | 298 result->filtered_count_ = this->filtered_count_; |
239 result->state_ = this->state_; | 299 result->state_ = this->state_; |
240 result->need_to_refetch_ = this->need_to_refetch_; | 300 result->need_to_refetch_ = this->need_to_refetch_; |
241 | 301 |
242 // TODO(crbug.com/703565): remove std::move() once Xcode 9.0+ is required. | 302 // TODO(crbug.com/703565): remove std::move() once Xcode 9.0+ is required. |
243 return std::move(result); | 303 return std::move(result); |
244 } | 304 } |
245 | 305 |
246 void FormFetcherImpl::ProcessPasswordStoreResults( | 306 void FormFetcherImpl::ProcessPasswordStoreResults( |
(...skipping 11 matching lines...) Expand all Loading... |
258 filtered_count_ = original_count - non_federated_.size(); | 318 filtered_count_ = original_count - non_federated_.size(); |
259 | 319 |
260 weak_non_federated_ = MakeWeakCopies(non_federated_); | 320 weak_non_federated_ = MakeWeakCopies(non_federated_); |
261 weak_federated_ = MakeWeakCopies(federated_); | 321 weak_federated_ = MakeWeakCopies(federated_); |
262 | 322 |
263 for (FormFetcher::Consumer* consumer : consumers_) | 323 for (FormFetcher::Consumer* consumer : consumers_) |
264 consumer->ProcessMatches(weak_non_federated_, filtered_count_); | 324 consumer->ProcessMatches(weak_non_federated_, filtered_count_); |
265 } | 325 } |
266 | 326 |
267 } // namespace password_manager | 327 } // namespace password_manager |
OLD | NEW |