| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/ui/passwords/password_manager_presenter.h" | 5 #include "chrome/browser/ui/passwords/password_manager_presenter.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 return "2"; | 70 return "2"; |
| 71 } | 71 } |
| 72 | 72 |
| 73 // Creates key for sorting password or password exception entries. | 73 // Creates key for sorting password or password exception entries. |
| 74 // The key is eTLD+1 followed by subdomains | 74 // The key is eTLD+1 followed by subdomains |
| 75 // (e.g. secure.accounts.example.com => example.com.accounts.secure). | 75 // (e.g. secure.accounts.example.com => example.com.accounts.secure). |
| 76 // If |username_and_password_in_key == true|, username and password is appended | 76 // If |username_and_password_in_key == true|, username and password is appended |
| 77 // to the key. The entry type code (non-Android, Android w/ or w/o affiliated | 77 // to the key. The entry type code (non-Android, Android w/ or w/o affiliated |
| 78 // web realm) is also appended to the key. | 78 // web realm) is also appended to the key. |
| 79 std::string CreateSortKey(const autofill::PasswordForm& form, | 79 std::string CreateSortKey(const autofill::PasswordForm& form, |
| 80 const std::string& languages, | |
| 81 bool username_and_password_in_key) { | 80 bool username_and_password_in_key) { |
| 82 bool is_android_uri = false; | 81 bool is_android_uri = false; |
| 83 bool is_clickable = false; | 82 bool is_clickable = false; |
| 84 GURL link_url; | 83 GURL link_url; |
| 85 std::string origin = password_manager::GetShownOriginAndLinkUrl( | 84 std::string origin = password_manager::GetShownOriginAndLinkUrl( |
| 86 form, languages, &is_android_uri, &link_url, &is_clickable); | 85 form, &is_android_uri, &link_url, &is_clickable); |
| 87 | 86 |
| 88 if (!is_clickable) { // e.g. android://com.example.r => r.example.com. | 87 if (!is_clickable) { // e.g. android://com.example.r => r.example.com. |
| 89 origin = SplitByDotAndReverse( | 88 origin = SplitByDotAndReverse( |
| 90 StringPiece(&origin[kAndroidAppSchemeAndDelimiterLength], | 89 StringPiece(&origin[kAndroidAppSchemeAndDelimiterLength], |
| 91 origin.length() - kAndroidAppSchemeAndDelimiterLength)); | 90 origin.length() - kAndroidAppSchemeAndDelimiterLength)); |
| 92 } | 91 } |
| 93 | 92 |
| 94 std::string site_name = | 93 std::string site_name = |
| 95 net::registry_controlled_domains::GetDomainAndRegistry( | 94 net::registry_controlled_domains::GetDomainAndRegistry( |
| 96 origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); | 95 origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 109 // Since Android and non-Android entries shouldn't be merged into one entry, | 108 // Since Android and non-Android entries shouldn't be merged into one entry, |
| 110 // add the entry type code to the sort key. | 109 // add the entry type code to the sort key. |
| 111 key += | 110 key += |
| 112 kSortKeyPartsSeparator + GetEntryTypeCode(is_android_uri, is_clickable); | 111 kSortKeyPartsSeparator + GetEntryTypeCode(is_android_uri, is_clickable); |
| 113 return key; | 112 return key; |
| 114 } | 113 } |
| 115 | 114 |
| 116 // Finds duplicates of |form| in |duplicates|, removes them from |store| and | 115 // Finds duplicates of |form| in |duplicates|, removes them from |store| and |
| 117 // from |duplicates|. | 116 // from |duplicates|. |
| 118 void RemoveDuplicates(const autofill::PasswordForm& form, | 117 void RemoveDuplicates(const autofill::PasswordForm& form, |
| 119 const std::string& languages, | |
| 120 DuplicatesMap* duplicates, | 118 DuplicatesMap* duplicates, |
| 121 PasswordStore* store, | 119 PasswordStore* store, |
| 122 bool username_and_password_in_key) { | 120 bool username_and_password_in_key) { |
| 123 std::string key = | 121 std::string key = |
| 124 CreateSortKey(form, languages, username_and_password_in_key); | 122 CreateSortKey(form, username_and_password_in_key); |
| 125 std::pair<DuplicatesMap::iterator, DuplicatesMap::iterator> dups = | 123 std::pair<DuplicatesMap::iterator, DuplicatesMap::iterator> dups = |
| 126 duplicates->equal_range(key); | 124 duplicates->equal_range(key); |
| 127 for (DuplicatesMap::iterator it = dups.first; it != dups.second; ++it) | 125 for (DuplicatesMap::iterator it = dups.first; it != dups.second; ++it) |
| 128 store->RemoveLogin(*it->second); | 126 store->RemoveLogin(*it->second); |
| 129 duplicates->erase(key); | 127 duplicates->erase(key); |
| 130 } | 128 } |
| 131 | 129 |
| 132 } // namespace | 130 } // namespace |
| 133 | 131 |
| 134 PasswordManagerPresenter::PasswordManagerPresenter( | 132 PasswordManagerPresenter::PasswordManagerPresenter( |
| 135 PasswordUIView* password_view) | 133 PasswordUIView* password_view) |
| 136 : populater_(this), | 134 : populater_(this), |
| 137 exception_populater_(this), | 135 exception_populater_(this), |
| 138 password_view_(password_view) { | 136 password_view_(password_view) { |
| 139 DCHECK(password_view_); | 137 DCHECK(password_view_); |
| 140 } | 138 } |
| 141 | 139 |
| 142 PasswordManagerPresenter::~PasswordManagerPresenter() { | 140 PasswordManagerPresenter::~PasswordManagerPresenter() { |
| 143 PasswordStore* store = GetPasswordStore(); | 141 PasswordStore* store = GetPasswordStore(); |
| 144 if (store) | 142 if (store) |
| 145 store->RemoveObserver(this); | 143 store->RemoveObserver(this); |
| 146 } | 144 } |
| 147 | 145 |
| 148 void PasswordManagerPresenter::Initialize() { | 146 void PasswordManagerPresenter::Initialize() { |
| 149 PasswordStore* store = GetPasswordStore(); | 147 PasswordStore* store = GetPasswordStore(); |
| 150 if (store) | 148 if (store) |
| 151 store->AddObserver(this); | 149 store->AddObserver(this); |
| 152 | |
| 153 languages_ = password_view_->GetProfile()->GetPrefs()-> | |
| 154 GetString(prefs::kAcceptLanguages); | |
| 155 } | 150 } |
| 156 | 151 |
| 157 void PasswordManagerPresenter::OnLoginsChanged( | 152 void PasswordManagerPresenter::OnLoginsChanged( |
| 158 const password_manager::PasswordStoreChangeList& changes) { | 153 const password_manager::PasswordStoreChangeList& changes) { |
| 159 // Entire list is updated for convenience. | 154 // Entire list is updated for convenience. |
| 160 UpdatePasswordLists(); | 155 UpdatePasswordLists(); |
| 161 } | 156 } |
| 162 | 157 |
| 163 PasswordStore* PasswordManagerPresenter::GetPasswordStore() { | 158 PasswordStore* PasswordManagerPresenter::GetPasswordStore() { |
| 164 return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(), | 159 return PasswordStoreFactory::GetForProfile(password_view_->GetProfile(), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 185 // |index| out of bounds might come from a compromised renderer | 180 // |index| out of bounds might come from a compromised renderer |
| 186 // (http://crbug.com/362054), or the user removed a password while a request | 181 // (http://crbug.com/362054), or the user removed a password while a request |
| 187 // to the store is in progress (i.e. |password_list_| is empty). | 182 // to the store is in progress (i.e. |password_list_| is empty). |
| 188 // Don't let it crash the browser. | 183 // Don't let it crash the browser. |
| 189 return; | 184 return; |
| 190 } | 185 } |
| 191 PasswordStore* store = GetPasswordStore(); | 186 PasswordStore* store = GetPasswordStore(); |
| 192 if (!store) | 187 if (!store) |
| 193 return; | 188 return; |
| 194 | 189 |
| 195 RemoveDuplicates(*password_list_[index], languages_, &password_duplicates_, | 190 RemoveDuplicates(*password_list_[index], &password_duplicates_, |
| 196 store, true); | 191 store, true); |
| 197 store->RemoveLogin(*password_list_[index]); | 192 store->RemoveLogin(*password_list_[index]); |
| 198 content::RecordAction( | 193 content::RecordAction( |
| 199 base::UserMetricsAction("PasswordManager_RemoveSavedPassword")); | 194 base::UserMetricsAction("PasswordManager_RemoveSavedPassword")); |
| 200 } | 195 } |
| 201 | 196 |
| 202 void PasswordManagerPresenter::RemovePasswordException(size_t index) { | 197 void PasswordManagerPresenter::RemovePasswordException(size_t index) { |
| 203 if (index >= password_exception_list_.size()) { | 198 if (index >= password_exception_list_.size()) { |
| 204 // |index| out of bounds might come from a compromised renderer | 199 // |index| out of bounds might come from a compromised renderer |
| 205 // (http://crbug.com/362054), or the user removed a password exception while | 200 // (http://crbug.com/362054), or the user removed a password exception while |
| 206 // a request to the store is in progress (i.e. |password_exception_list_| | 201 // a request to the store is in progress (i.e. |password_exception_list_| |
| 207 // is empty). Don't let it crash the browser. | 202 // is empty). Don't let it crash the browser. |
| 208 return; | 203 return; |
| 209 } | 204 } |
| 210 PasswordStore* store = GetPasswordStore(); | 205 PasswordStore* store = GetPasswordStore(); |
| 211 if (!store) | 206 if (!store) |
| 212 return; | 207 return; |
| 213 RemoveDuplicates(*password_exception_list_[index], languages_, | 208 RemoveDuplicates(*password_exception_list_[index], |
| 214 &password_exception_duplicates_, store, false); | 209 &password_exception_duplicates_, store, false); |
| 215 store->RemoveLogin(*password_exception_list_[index]); | 210 store->RemoveLogin(*password_exception_list_[index]); |
| 216 content::RecordAction( | 211 content::RecordAction( |
| 217 base::UserMetricsAction("PasswordManager_RemovePasswordException")); | 212 base::UserMetricsAction("PasswordManager_RemovePasswordException")); |
| 218 } | 213 } |
| 219 | 214 |
| 220 void PasswordManagerPresenter::RequestShowPassword(size_t index) { | 215 void PasswordManagerPresenter::RequestShowPassword(size_t index) { |
| 221 #if !defined(OS_ANDROID) // This is never called on Android. | 216 #if !defined(OS_ANDROID) // This is never called on Android. |
| 222 if (index >= password_list_.size()) { | 217 if (index >= password_list_.size()) { |
| 223 // |index| out of bounds might come from a compromised renderer | 218 // |index| out of bounds might come from a compromised renderer |
| (...skipping 25 matching lines...) Expand all Loading... |
| 249 } | 244 } |
| 250 if (password_manager::sync_util::IsSyncAccountCredential( | 245 if (password_manager::sync_util::IsSyncAccountCredential( |
| 251 *password_list_[index], sync_service, | 246 *password_list_[index], sync_service, |
| 252 SigninManagerFactory::GetForProfile(password_view_->GetProfile()))) { | 247 SigninManagerFactory::GetForProfile(password_view_->GetProfile()))) { |
| 253 content::RecordAction( | 248 content::RecordAction( |
| 254 base::UserMetricsAction("PasswordManager_SyncCredentialShown")); | 249 base::UserMetricsAction("PasswordManager_SyncCredentialShown")); |
| 255 } | 250 } |
| 256 | 251 |
| 257 // Call back the front end to reveal the password. | 252 // Call back the front end to reveal the password. |
| 258 std::string origin_url = password_manager::GetHumanReadableOrigin( | 253 std::string origin_url = password_manager::GetHumanReadableOrigin( |
| 259 *password_list_[index], languages_); | 254 *password_list_[index]); |
| 260 password_view_->ShowPassword( | 255 password_view_->ShowPassword( |
| 261 index, | 256 index, |
| 262 origin_url, | 257 origin_url, |
| 263 base::UTF16ToUTF8(password_list_[index]->username_value), | 258 base::UTF16ToUTF8(password_list_[index]->username_value), |
| 264 password_list_[index]->password_value); | 259 password_list_[index]->password_value); |
| 265 #endif | 260 #endif |
| 266 } | 261 } |
| 267 | 262 |
| 268 const autofill::PasswordForm* PasswordManagerPresenter::GetPassword( | 263 const autofill::PasswordForm* PasswordManagerPresenter::GetPassword( |
| 269 size_t index) { | 264 size_t index) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 291 | 286 |
| 292 void PasswordManagerPresenter::SetPasswordList() { | 287 void PasswordManagerPresenter::SetPasswordList() { |
| 293 password_view_->SetPasswordList(password_list_); | 288 password_view_->SetPasswordList(password_list_); |
| 294 } | 289 } |
| 295 | 290 |
| 296 void PasswordManagerPresenter::SetPasswordExceptionList() { | 291 void PasswordManagerPresenter::SetPasswordExceptionList() { |
| 297 password_view_->SetPasswordExceptionList(password_exception_list_); | 292 password_view_->SetPasswordExceptionList(password_exception_list_); |
| 298 } | 293 } |
| 299 | 294 |
| 300 void PasswordManagerPresenter::SortEntriesAndHideDuplicates( | 295 void PasswordManagerPresenter::SortEntriesAndHideDuplicates( |
| 301 const std::string& languages, | |
| 302 std::vector<scoped_ptr<autofill::PasswordForm>>* list, | 296 std::vector<scoped_ptr<autofill::PasswordForm>>* list, |
| 303 DuplicatesMap* duplicates, | 297 DuplicatesMap* duplicates, |
| 304 bool username_and_password_in_key) { | 298 bool username_and_password_in_key) { |
| 305 std::vector<std::pair<std::string, scoped_ptr<autofill::PasswordForm>>> pairs; | 299 std::vector<std::pair<std::string, scoped_ptr<autofill::PasswordForm>>> pairs; |
| 306 pairs.reserve(list->size()); | 300 pairs.reserve(list->size()); |
| 307 for (auto& form : *list) { | 301 for (auto& form : *list) { |
| 308 pairs.push_back(std::make_pair( | 302 pairs.push_back(std::make_pair( |
| 309 CreateSortKey(*form, languages, username_and_password_in_key), | 303 CreateSortKey(*form, username_and_password_in_key), std::move(form))); |
| 310 std::move(form))); | |
| 311 } | 304 } |
| 312 | 305 |
| 313 std::sort( | 306 std::sort( |
| 314 pairs.begin(), pairs.end(), | 307 pairs.begin(), pairs.end(), |
| 315 [](const std::pair<std::string, scoped_ptr<autofill::PasswordForm>>& left, | 308 [](const std::pair<std::string, scoped_ptr<autofill::PasswordForm>>& left, |
| 316 const std::pair<std::string, scoped_ptr<autofill::PasswordForm>>& | 309 const std::pair<std::string, scoped_ptr<autofill::PasswordForm>>& |
| 317 right) { return left.first < right.first; }); | 310 right) { return left.first < right.first; }); |
| 318 | 311 |
| 319 list->clear(); | 312 list->clear(); |
| 320 duplicates->clear(); | 313 duplicates->clear(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 347 store->GetAutofillableLoginsWithAffiliatedRealms(this); | 340 store->GetAutofillableLoginsWithAffiliatedRealms(this); |
| 348 } else { | 341 } else { |
| 349 LOG(ERROR) << "No password store! Cannot display passwords."; | 342 LOG(ERROR) << "No password store! Cannot display passwords."; |
| 350 } | 343 } |
| 351 } | 344 } |
| 352 | 345 |
| 353 void PasswordManagerPresenter::PasswordListPopulater::OnGetPasswordStoreResults( | 346 void PasswordManagerPresenter::PasswordListPopulater::OnGetPasswordStoreResults( |
| 354 ScopedVector<autofill::PasswordForm> results) { | 347 ScopedVector<autofill::PasswordForm> results) { |
| 355 page_->password_list_ = | 348 page_->password_list_ = |
| 356 password_manager_util::ConvertScopedVector(std::move(results)); | 349 password_manager_util::ConvertScopedVector(std::move(results)); |
| 357 page_->SortEntriesAndHideDuplicates(page_->languages_, &page_->password_list_, | 350 page_->SortEntriesAndHideDuplicates(&page_->password_list_, |
| 358 &page_->password_duplicates_, | 351 &page_->password_duplicates_, |
| 359 true /* use username and password */); | 352 true /* use username and password */); |
| 360 page_->SetPasswordList(); | 353 page_->SetPasswordList(); |
| 361 } | 354 } |
| 362 | 355 |
| 363 PasswordManagerPresenter::PasswordExceptionListPopulater:: | 356 PasswordManagerPresenter::PasswordExceptionListPopulater:: |
| 364 PasswordExceptionListPopulater(PasswordManagerPresenter* page) | 357 PasswordExceptionListPopulater(PasswordManagerPresenter* page) |
| 365 : ListPopulater(page) { | 358 : ListPopulater(page) { |
| 366 } | 359 } |
| 367 | 360 |
| 368 void PasswordManagerPresenter::PasswordExceptionListPopulater::Populate() { | 361 void PasswordManagerPresenter::PasswordExceptionListPopulater::Populate() { |
| 369 PasswordStore* store = page_->GetPasswordStore(); | 362 PasswordStore* store = page_->GetPasswordStore(); |
| 370 if (store != NULL) { | 363 if (store != NULL) { |
| 371 cancelable_task_tracker()->TryCancelAll(); | 364 cancelable_task_tracker()->TryCancelAll(); |
| 372 store->GetBlacklistLoginsWithAffiliatedRealms(this); | 365 store->GetBlacklistLoginsWithAffiliatedRealms(this); |
| 373 } else { | 366 } else { |
| 374 LOG(ERROR) << "No password store! Cannot display exceptions."; | 367 LOG(ERROR) << "No password store! Cannot display exceptions."; |
| 375 } | 368 } |
| 376 } | 369 } |
| 377 | 370 |
| 378 void PasswordManagerPresenter::PasswordExceptionListPopulater:: | 371 void PasswordManagerPresenter::PasswordExceptionListPopulater:: |
| 379 OnGetPasswordStoreResults(ScopedVector<autofill::PasswordForm> results) { | 372 OnGetPasswordStoreResults(ScopedVector<autofill::PasswordForm> results) { |
| 380 page_->password_exception_list_ = | 373 page_->password_exception_list_ = |
| 381 password_manager_util::ConvertScopedVector(std::move(results)); | 374 password_manager_util::ConvertScopedVector(std::move(results)); |
| 382 page_->SortEntriesAndHideDuplicates( | 375 page_->SortEntriesAndHideDuplicates(&page_->password_exception_list_, |
| 383 page_->languages_, &page_->password_exception_list_, | |
| 384 &page_->password_exception_duplicates_, | 376 &page_->password_exception_duplicates_, |
| 385 false /* don't use username and password*/); | 377 false /* don't use username and password*/); |
| 386 page_->SetPasswordExceptionList(); | 378 page_->SetPasswordExceptionList(); |
| 387 } | 379 } |
| OLD | NEW |