| 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 |