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

Side by Side Diff: chrome/browser/password_manager/native_backend_gnome_x.cc

Issue 906973007: PasswordStore: Clean up expectations about rewriting vectors of forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments addressed, except for dropping clear() (yet) Created 5 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/password_manager/native_backend_gnome_x.h" 5 #include "chrome/browser/password_manager/native_backend_gnome_x.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <gnome-keyring.h> 8 #include <gnome-keyring.h>
9 9
10 #include <map> 10 #include <map>
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 form->federation_url = GURL(string_attr_map["federation_url"]); 156 form->federation_url = GURL(string_attr_map["federation_url"]);
157 form->skip_zero_click = uint_attr_map["skip_zero_click"]; 157 form->skip_zero_click = uint_attr_map["skip_zero_click"];
158 form->generation_upload_status = 158 form->generation_upload_status =
159 static_cast<PasswordForm::GenerationUploadStatus>( 159 static_cast<PasswordForm::GenerationUploadStatus>(
160 uint_attr_map["generation_upload_status"]); 160 uint_attr_map["generation_upload_status"]);
161 DeserializeFormDataFromBase64String(string_attr_map["form_data"], 161 DeserializeFormDataFromBase64String(string_attr_map["form_data"],
162 &form->form_data); 162 &form->form_data);
163 return form.Pass(); 163 return form.Pass();
164 } 164 }
165 165
166 // Parse all the results from the given GList into a 166 // Converts native credentials in |found| to PasswordForms. If not NULL,
167 // ScopedVector<autofill::PasswordForm>, and free the GList. PasswordForms are
168 // allocated on the heap, and should be deleted by the consumer. If not NULL,
169 // |lookup_form| is used to filter out results -- only credentials with signon 167 // |lookup_form| is used to filter out results -- only credentials with signon
170 // realms passing the PSL matching against |lookup_form->signon_realm| will be 168 // realms passing the PSL matching against |lookup_form->signon_realm| will be
171 // kept. PSL matched results get their signon_realm, origin, and action 169 // kept. PSL matched results get their signon_realm, origin, and action
172 // rewritten to those of |lookup_form_|, with the original signon_realm saved 170 // rewritten to those of |lookup_form_|, with the original signon_realm saved
173 // into the result's original_signon_realm data member. 171 // into the result's original_signon_realm data member.
174 void ConvertFormList(GList* found, 172 ScopedVector<PasswordForm> ConvertFormList(GList* found,
175 const PasswordForm* lookup_form, 173 const PasswordForm* lookup_form) {
176 ScopedVector<autofill::PasswordForm>* forms) { 174 ScopedVector<PasswordForm> forms;
177 password_manager::PSLDomainMatchMetric psl_domain_match_metric = 175 password_manager::PSLDomainMatchMetric psl_domain_match_metric =
178 password_manager::PSL_DOMAIN_MATCH_NONE; 176 password_manager::PSL_DOMAIN_MATCH_NONE;
179 for (GList* element = g_list_first(found); element; 177 for (GList* element = g_list_first(found); element;
180 element = g_list_next(element)) { 178 element = g_list_next(element)) {
181 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data); 179 GnomeKeyringFound* data = static_cast<GnomeKeyringFound*>(element->data);
182 GnomeKeyringAttributeList* attrs = data->attributes; 180 GnomeKeyringAttributeList* attrs = data->attributes;
183 181
184 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs)); 182 scoped_ptr<PasswordForm> form(FormFromAttributes(attrs));
185 if (form) { 183 if (form) {
186 if (lookup_form && form->signon_realm != lookup_form->signon_realm) { 184 if (lookup_form && form->signon_realm != lookup_form->signon_realm) {
187 // This is not an exact match, we try PSL matching. 185 // This is not an exact match, we try PSL matching.
188 if (lookup_form->scheme != PasswordForm::SCHEME_HTML || 186 if (lookup_form->scheme != PasswordForm::SCHEME_HTML ||
189 form->scheme != PasswordForm::SCHEME_HTML || 187 form->scheme != PasswordForm::SCHEME_HTML ||
190 !(password_manager::IsPublicSuffixDomainMatch( 188 !(password_manager::IsPublicSuffixDomainMatch(
191 lookup_form->signon_realm, form->signon_realm))) { 189 lookup_form->signon_realm, form->signon_realm))) {
192 continue; 190 continue;
193 } 191 }
194 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND; 192 psl_domain_match_metric = password_manager::PSL_DOMAIN_MATCH_FOUND;
195 form->original_signon_realm = form->signon_realm; 193 form->original_signon_realm = form->signon_realm;
196 form->signon_realm = lookup_form->signon_realm; 194 form->signon_realm = lookup_form->signon_realm;
197 form->origin = lookup_form->origin; 195 form->origin = lookup_form->origin;
198 form->action = lookup_form->action; 196 form->action = lookup_form->action;
199 } 197 }
200 if (data->secret) { 198 if (data->secret) {
201 form->password_value = UTF8ToUTF16(data->secret); 199 form->password_value = UTF8ToUTF16(data->secret);
202 } else { 200 } else {
203 LOG(WARNING) << "Unable to access password from list element!"; 201 LOG(WARNING) << "Unable to access password from list element!";
204 } 202 }
205 forms->push_back(form.release()); 203 forms.push_back(form.release());
206 } else { 204 } else {
207 LOG(WARNING) << "Could not initialize PasswordForm from attributes!"; 205 LOG(WARNING) << "Could not initialize PasswordForm from attributes!";
208 } 206 }
209 } 207 }
210 if (lookup_form) { 208 if (lookup_form) {
211 const GURL signon_realm(lookup_form->signon_realm); 209 const GURL signon_realm(lookup_form->signon_realm);
212 std::string registered_domain = 210 std::string registered_domain =
213 password_manager::GetRegistryControlledDomain(signon_realm); 211 password_manager::GetRegistryControlledDomain(signon_realm);
214 UMA_HISTOGRAM_ENUMERATION( 212 UMA_HISTOGRAM_ENUMERATION(
215 "PasswordManager.PslDomainMatchTriggering", 213 "PasswordManager.PslDomainMatchTriggering",
216 password_manager::ShouldPSLDomainMatchingApply(registered_domain) 214 password_manager::ShouldPSLDomainMatchingApply(registered_domain)
217 ? psl_domain_match_metric 215 ? psl_domain_match_metric
218 : password_manager::PSL_DOMAIN_MATCH_NOT_USED, 216 : password_manager::PSL_DOMAIN_MATCH_NOT_USED,
219 password_manager::PSL_DOMAIN_MATCH_COUNT); 217 password_manager::PSL_DOMAIN_MATCH_COUNT);
220 } 218 }
219 return forms.Pass();
221 } 220 }
222 221
223 // Schema is analagous to the fields in PasswordForm. 222 // Schema is analagous to the fields in PasswordForm.
224 const GnomeKeyringPasswordSchema kGnomeSchema = { 223 const GnomeKeyringPasswordSchema kGnomeSchema = {
225 GNOME_KEYRING_ITEM_GENERIC_SECRET, { 224 GNOME_KEYRING_ITEM_GENERIC_SECRET, {
226 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 225 { "origin_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
227 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 226 { "action_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
228 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 227 { "username_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
229 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 228 { "username_value", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
230 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, 229 { "password_element", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 void UpdateLoginSearch(const PasswordForm& form, const char* app_string); 276 void UpdateLoginSearch(const PasswordForm& form, const char* app_string);
278 void RemoveLogin(const PasswordForm& form, const char* app_string); 277 void RemoveLogin(const PasswordForm& form, const char* app_string);
279 void GetLogins(const PasswordForm& form, const char* app_string); 278 void GetLogins(const PasswordForm& form, const char* app_string);
280 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string); 279 void GetLoginsList(uint32_t blacklisted_by_user, const char* app_string);
281 void GetAllLogins(const char* app_string); 280 void GetAllLogins(const char* app_string);
282 281
283 // Use after AddLogin, RemoveLogin. 282 // Use after AddLogin, RemoveLogin.
284 GnomeKeyringResult WaitResult(); 283 GnomeKeyringResult WaitResult();
285 284
286 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList, 285 // Use after AddLoginSearch, UpdateLoginSearch, GetLogins, GetLoginsList,
287 // GetAllLogins. 286 // GetAllLogins. Replaces the content of |forms| with found logins.
288 GnomeKeyringResult WaitResult(ScopedVector<autofill::PasswordForm>* forms); 287 GnomeKeyringResult WaitResult(ScopedVector<PasswordForm>* forms);
289 288
290 private: 289 private:
291 struct GnomeKeyringAttributeListFreeDeleter { 290 struct GnomeKeyringAttributeListFreeDeleter {
292 inline void operator()(void* list) const { 291 inline void operator()(void* list) const {
293 gnome_keyring_attribute_list_free( 292 gnome_keyring_attribute_list_free(
294 static_cast<GnomeKeyringAttributeList*>(list)); 293 static_cast<GnomeKeyringAttributeList*>(list));
295 } 294 }
296 }; 295 };
297 296
298 typedef scoped_ptr<GnomeKeyringAttributeList, 297 typedef scoped_ptr<GnomeKeyringAttributeList,
299 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList; 298 GnomeKeyringAttributeListFreeDeleter> ScopedAttributeList;
300 299
301 // Helper methods to abbreviate Gnome Keyring long API names. 300 // Helper methods to abbreviate Gnome Keyring long API names.
302 static void AppendString(ScopedAttributeList* list, 301 static void AppendString(ScopedAttributeList* list,
303 const char* name, 302 const char* name,
304 const char* value); 303 const char* value);
305 static void AppendString(ScopedAttributeList* list, 304 static void AppendString(ScopedAttributeList* list,
306 const char* name, 305 const char* name,
307 const std::string& value); 306 const std::string& value);
308 static void AppendUint32(ScopedAttributeList* list, 307 static void AppendUint32(ScopedAttributeList* list,
309 const char* name, 308 const char* name,
310 guint32 value); 309 guint32 value);
311 310
312 // All these callbacks are called on UI thread. 311 // All these callbacks are called on UI thread.
313 static void OnOperationDone(GnomeKeyringResult result, gpointer data); 312 static void OnOperationDone(GnomeKeyringResult result, gpointer data);
314 313
314 // This is marked as static, but acts on the GKRMethod instance that |data|
315 // points to. Saves |result| to |result_|. If the result is OK, overwrites
316 // |forms_| with the found credentials. Clears |forms_| otherwise.
315 static void OnOperationGetList(GnomeKeyringResult result, GList* list, 317 static void OnOperationGetList(GnomeKeyringResult result, GList* list,
316 gpointer data); 318 gpointer data);
317 319
318 base::WaitableEvent event_; 320 base::WaitableEvent event_;
319 GnomeKeyringResult result_; 321 GnomeKeyringResult result_;
320 ScopedVector<autofill::PasswordForm> forms_; 322 ScopedVector<PasswordForm> forms_;
321 // If the credential search is specified by a single form and needs to use PSL 323 // If the credential search is specified by a single form and needs to use PSL
322 // matching, then the specifying form is stored in |lookup_form_|. If PSL 324 // matching, then the specifying form is stored in |lookup_form_|. If PSL
323 // matching is used to find a result, then the results signon realm, origin 325 // matching is used to find a result, then the results signon realm, origin
324 // and action are stored are replaced by those of |lookup_form_|. 326 // and action are stored are replaced by those of |lookup_form_|.
325 // Additionally, |lookup_form_->signon_realm| is also used to narrow down the 327 // Additionally, |lookup_form_->signon_realm| is also used to narrow down the
326 // found logins to those which indeed PSL-match the look-up. And finally, 328 // found logins to those which indeed PSL-match the look-up. And finally,
327 // |lookup_form_| set to NULL means that PSL matching is not required. 329 // |lookup_form_| set to NULL means that PSL matching is not required.
328 scoped_ptr<PasswordForm> lookup_form_; 330 scoped_ptr<PasswordForm> lookup_form_;
329 }; 331 };
330 332
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 /*data=*/this, 476 /*data=*/this,
475 /*destroy_data=*/nullptr); 477 /*destroy_data=*/nullptr);
476 } 478 }
477 479
478 GnomeKeyringResult GKRMethod::WaitResult() { 480 GnomeKeyringResult GKRMethod::WaitResult() {
479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
480 event_.Wait(); 482 event_.Wait();
481 return result_; 483 return result_;
482 } 484 }
483 485
484 GnomeKeyringResult GKRMethod::WaitResult( 486 GnomeKeyringResult GKRMethod::WaitResult(ScopedVector<PasswordForm>* forms) {
485 ScopedVector<autofill::PasswordForm>* forms) {
486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
487 event_.Wait(); 488 event_.Wait();
488 if (forms->empty()) { 489 forms->swap(forms_);
489 // Normal case. Avoid extra allocation by swapping.
490 forms->swap(forms_);
491 } else {
492 // Rare case. Append forms_ to *forms.
493 forms->insert(forms->end(), forms_.begin(), forms_.end());
494 forms_.weak_clear();
495 }
496 return result_; 490 return result_;
497 } 491 }
498 492
499 // static 493 // static
500 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list, 494 void GKRMethod::AppendString(GKRMethod::ScopedAttributeList* list,
501 const char* name, 495 const char* name,
502 const char* value) { 496 const char* value) {
503 gnome_keyring_attribute_list_append_string(list->get(), name, value); 497 gnome_keyring_attribute_list_append_string(list->get(), name, value);
504 } 498 }
505 499
(...skipping 16 matching lines...) Expand all
522 GKRMethod* method = static_cast<GKRMethod*>(data); 516 GKRMethod* method = static_cast<GKRMethod*>(data);
523 method->result_ = result; 517 method->result_ = result;
524 method->event_.Signal(); 518 method->event_.Signal();
525 } 519 }
526 520
527 // static 521 // static
528 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list, 522 void GKRMethod::OnOperationGetList(GnomeKeyringResult result, GList* list,
529 gpointer data) { 523 gpointer data) {
530 GKRMethod* method = static_cast<GKRMethod*>(data); 524 GKRMethod* method = static_cast<GKRMethod*>(data);
531 method->result_ = result; 525 method->result_ = result;
532 method->forms_.clear(); 526 method->forms_.clear();
engedy 2015/03/11 19:25:35 I am somewhat uneasy about this one, given this is
vabr (Chromium) 2015/03/12 15:30:50 Thanks for thinking this through, I agree that thi
engedy 2015/03/16 10:35:35 Acknowledged.
533 // |list| will be freed after this callback returns, so convert it now. 527 // |list| will be freed after this callback returns, so convert it now.
534 ConvertFormList(list, method->lookup_form_.get(), &method->forms_); 528 if (result == GNOME_KEYRING_RESULT_OK)
529 method->forms_ = ConvertFormList(list, method->lookup_form_.get());
535 method->lookup_form_.reset(); 530 method->lookup_form_.reset();
536 method->event_.Signal(); 531 method->event_.Signal();
537 } 532 }
538 533
534 // Generates a profile-specific app string based on profile_id.
535 std::string GetProfileSpecificAppString(LocalProfileId profile_id) {
536 // Originally, the application string was always just "chrome" and used only
537 // so that we had *something* to search for since GNOME Keyring won't search
538 // for nothing. Now we use it to distinguish passwords for different profiles.
539 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id);
540 }
541
539 } // namespace 542 } // namespace
540 543
541 NativeBackendGnome::NativeBackendGnome(LocalProfileId id) 544 NativeBackendGnome::NativeBackendGnome(LocalProfileId id)
542 : profile_id_(id) { 545 : profile_id_(id), app_string_(GetProfileSpecificAppString(id)) {
543 app_string_ = GetProfileSpecificAppString();
544 } 546 }
545 547
546 NativeBackendGnome::~NativeBackendGnome() { 548 NativeBackendGnome::~NativeBackendGnome() {
547 } 549 }
548 550
549 bool NativeBackendGnome::Init() { 551 bool NativeBackendGnome::Init() {
550 return LoadGnomeKeyring() && gnome_keyring_is_available(); 552 return LoadGnomeKeyring() && gnome_keyring_is_available();
551 } 553 }
552 554
553 bool NativeBackendGnome::RawAddLogin(const PasswordForm& form) { 555 bool NativeBackendGnome::RawAddLogin(const PasswordForm& form) {
(...skipping 18 matching lines...) Expand all
572 // on origin_url, username_element, username_value, password_element, submit 574 // on origin_url, username_element, username_value, password_element, submit
573 // element, and signon_realm first, remove that, and then add the new entry. 575 // element, and signon_realm first, remove that, and then add the new entry.
574 // We'd add the new one first, and then delete the original, but then the 576 // We'd add the new one first, and then delete the original, but then the
575 // delete might actually delete the newly-added entry! 577 // delete might actually delete the newly-added entry!
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 578 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
577 GKRMethod method; 579 GKRMethod method;
578 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 580 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
579 base::Bind(&GKRMethod::AddLoginSearch, 581 base::Bind(&GKRMethod::AddLoginSearch,
580 base::Unretained(&method), 582 base::Unretained(&method),
581 form, app_string_.c_str())); 583 form, app_string_.c_str()));
582 ScopedVector<autofill::PasswordForm> forms; 584 ScopedVector<PasswordForm> forms;
583 GnomeKeyringResult result = method.WaitResult(&forms); 585 GnomeKeyringResult result = method.WaitResult(&forms);
584 if (result != GNOME_KEYRING_RESULT_OK && 586 if (result != GNOME_KEYRING_RESULT_OK &&
585 result != GNOME_KEYRING_RESULT_NO_MATCH) { 587 result != GNOME_KEYRING_RESULT_NO_MATCH) {
586 LOG(ERROR) << "Keyring find failed: " 588 LOG(ERROR) << "Keyring find failed: "
587 << gnome_keyring_result_to_message(result); 589 << gnome_keyring_result_to_message(result);
588 return password_manager::PasswordStoreChangeList(); 590 return password_manager::PasswordStoreChangeList();
589 } 591 }
590 password_manager::PasswordStoreChangeList changes; 592 password_manager::PasswordStoreChangeList changes;
591 if (forms.size() > 0) { 593 if (forms.size() > 0) {
592 if (forms.size() > 1) { 594 if (forms.size() > 1) {
(...skipping 23 matching lines...) Expand all
616 // then add the new entry. We'd add the new one first, and then delete the 618 // then add the new entry. We'd add the new one first, and then delete the
617 // original, but then the delete might actually delete the newly-added entry! 619 // original, but then the delete might actually delete the newly-added entry!
618 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 620 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
619 DCHECK(changes); 621 DCHECK(changes);
620 changes->clear(); 622 changes->clear();
621 GKRMethod method; 623 GKRMethod method;
622 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 624 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
623 base::Bind(&GKRMethod::UpdateLoginSearch, 625 base::Bind(&GKRMethod::UpdateLoginSearch,
624 base::Unretained(&method), 626 base::Unretained(&method),
625 form, app_string_.c_str())); 627 form, app_string_.c_str()));
626 ScopedVector<autofill::PasswordForm> forms; 628 ScopedVector<PasswordForm> forms;
627 GnomeKeyringResult result = method.WaitResult(&forms); 629 GnomeKeyringResult result = method.WaitResult(&forms);
628 if (result != GNOME_KEYRING_RESULT_OK) { 630 if (result != GNOME_KEYRING_RESULT_OK) {
629 LOG(ERROR) << "Keyring find failed: " 631 LOG(ERROR) << "Keyring find failed: "
630 << gnome_keyring_result_to_message(result); 632 << gnome_keyring_result_to_message(result);
631 return false; 633 return false;
632 } 634 }
633 635
634 bool removed = false; 636 bool removed = false;
635 for (size_t i = 0; i < forms.size(); ++i) { 637 for (size_t i = 0; i < forms.size(); ++i) {
636 if (*forms[i] != form) { 638 if (*forms[i] != form) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 delete_begin, delete_end, CREATION_TIMESTAMP, changes); 678 delete_begin, delete_end, CREATION_TIMESTAMP, changes);
677 } 679 }
678 680
679 bool NativeBackendGnome::RemoveLoginsSyncedBetween( 681 bool NativeBackendGnome::RemoveLoginsSyncedBetween(
680 base::Time delete_begin, 682 base::Time delete_begin,
681 base::Time delete_end, 683 base::Time delete_end,
682 password_manager::PasswordStoreChangeList* changes) { 684 password_manager::PasswordStoreChangeList* changes) {
683 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes); 685 return RemoveLoginsBetween(delete_begin, delete_end, SYNC_TIMESTAMP, changes);
684 } 686 }
685 687
686 bool NativeBackendGnome::GetLogins( 688 bool NativeBackendGnome::GetLogins(const PasswordForm& form,
687 const PasswordForm& form, 689 ScopedVector<PasswordForm>* forms) {
688 ScopedVector<autofill::PasswordForm>* forms) {
689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
690 GKRMethod method; 691 GKRMethod method;
691 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 692 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
692 base::Bind(&GKRMethod::GetLogins, 693 base::Bind(&GKRMethod::GetLogins,
693 base::Unretained(&method), 694 base::Unretained(&method),
694 form, app_string_.c_str())); 695 form, app_string_.c_str()));
695 GnomeKeyringResult result = method.WaitResult(forms); 696 GnomeKeyringResult result = method.WaitResult(forms);
696 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 697 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
697 return true; 698 return true;
698 if (result != GNOME_KEYRING_RESULT_OK) { 699 if (result != GNOME_KEYRING_RESULT_OK) {
699 LOG(ERROR) << "Keyring find failed: " 700 LOG(ERROR) << "Keyring find failed: "
700 << gnome_keyring_result_to_message(result); 701 << gnome_keyring_result_to_message(result);
701 return false; 702 return false;
702 } 703 }
703 return true; 704 return true;
704 } 705 }
705 706
706 bool NativeBackendGnome::GetAutofillableLogins( 707 bool NativeBackendGnome::GetAutofillableLogins(
707 ScopedVector<autofill::PasswordForm>* forms) { 708 ScopedVector<PasswordForm>* forms) {
708 return GetLoginsList(true, forms); 709 return GetLoginsList(true, forms);
709 } 710 }
710 711
711 bool NativeBackendGnome::GetBlacklistLogins( 712 bool NativeBackendGnome::GetBlacklistLogins(ScopedVector<PasswordForm>* forms) {
712 ScopedVector<autofill::PasswordForm>* forms) {
713 return GetLoginsList(false, forms); 713 return GetLoginsList(false, forms);
714 } 714 }
715 715
716 bool NativeBackendGnome::GetLoginsList( 716 bool NativeBackendGnome::GetLoginsList(bool autofillable,
717 bool autofillable, 717 ScopedVector<PasswordForm>* forms) {
718 ScopedVector<autofill::PasswordForm>* forms) {
719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 718 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
720 719
721 uint32_t blacklisted_by_user = !autofillable; 720 uint32_t blacklisted_by_user = !autofillable;
722 721
723 GKRMethod method; 722 GKRMethod method;
724 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 723 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
725 base::Bind(&GKRMethod::GetLoginsList, 724 base::Bind(&GKRMethod::GetLoginsList,
726 base::Unretained(&method), 725 base::Unretained(&method),
727 blacklisted_by_user, app_string_.c_str())); 726 blacklisted_by_user, app_string_.c_str()));
728 GnomeKeyringResult result = method.WaitResult(forms); 727 GnomeKeyringResult result = method.WaitResult(forms);
729 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 728 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
730 return true; 729 return true;
731 if (result != GNOME_KEYRING_RESULT_OK) { 730 if (result != GNOME_KEYRING_RESULT_OK) {
732 LOG(ERROR) << "Keyring find failed: " 731 LOG(ERROR) << "Keyring find failed: "
733 << gnome_keyring_result_to_message(result); 732 << gnome_keyring_result_to_message(result);
734 return false; 733 return false;
735 } 734 }
736 return true; 735 return true;
737 } 736 }
738 737
739 bool NativeBackendGnome::GetAllLogins( 738 bool NativeBackendGnome::GetAllLogins(ScopedVector<PasswordForm>* forms) {
740 ScopedVector<autofill::PasswordForm>* forms) {
741 GKRMethod method; 739 GKRMethod method;
742 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 740 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
743 base::Bind(&GKRMethod::GetAllLogins, 741 base::Bind(&GKRMethod::GetAllLogins,
744 base::Unretained(&method), 742 base::Unretained(&method),
745 app_string_.c_str())); 743 app_string_.c_str()));
746 GnomeKeyringResult result = method.WaitResult(forms); 744 GnomeKeyringResult result = method.WaitResult(forms);
747 if (result == GNOME_KEYRING_RESULT_NO_MATCH) 745 if (result == GNOME_KEYRING_RESULT_NO_MATCH)
748 return true; 746 return true;
749 if (result != GNOME_KEYRING_RESULT_OK) { 747 if (result != GNOME_KEYRING_RESULT_OK) {
750 LOG(ERROR) << "Keyring find failed: " 748 LOG(ERROR) << "Keyring find failed: "
751 << gnome_keyring_result_to_message(result); 749 << gnome_keyring_result_to_message(result);
752 return false; 750 return false;
753 } 751 }
754 return true; 752 return true;
755 } 753 }
756 754
757 bool NativeBackendGnome::GetLoginsBetween( 755 bool NativeBackendGnome::GetLoginsBetween(base::Time get_begin,
758 base::Time get_begin, 756 base::Time get_end,
759 base::Time get_end, 757 TimestampToCompare date_to_compare,
760 TimestampToCompare date_to_compare, 758 ScopedVector<PasswordForm>* forms) {
761 ScopedVector<autofill::PasswordForm>* forms) {
762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
760 forms->clear();
763 // We could walk the list and add items as we find them, but it is much 761 // We could walk the list and add items as we find them, but it is much
764 // easier to build the list and then filter the results. 762 // easier to build the list and then filter the results.
765 ScopedVector<autofill::PasswordForm> all_forms; 763 ScopedVector<PasswordForm> all_forms;
766 if (!GetAllLogins(&all_forms)) 764 if (!GetAllLogins(&all_forms))
767 return false; 765 return false;
768 766
769 base::Time autofill::PasswordForm::*date_member = 767 base::Time PasswordForm::*date_member = date_to_compare == CREATION_TIMESTAMP
770 date_to_compare == CREATION_TIMESTAMP 768 ? &PasswordForm::date_created
771 ? &autofill::PasswordForm::date_created 769 : &PasswordForm::date_synced;
772 : &autofill::PasswordForm::date_synced;
773 for (auto& saved_form : all_forms) { 770 for (auto& saved_form : all_forms) {
774 if (get_begin <= saved_form->*date_member && 771 if (get_begin <= saved_form->*date_member &&
775 (get_end.is_null() || saved_form->*date_member < get_end)) { 772 (get_end.is_null() || saved_form->*date_member < get_end)) {
776 forms->push_back(saved_form); 773 forms->push_back(saved_form);
777 saved_form = nullptr; 774 saved_form = nullptr;
778 } 775 }
779 } 776 }
780 777
781 return true; 778 return true;
782 } 779 }
783 780
784 bool NativeBackendGnome::RemoveLoginsBetween( 781 bool NativeBackendGnome::RemoveLoginsBetween(
785 base::Time get_begin, 782 base::Time get_begin,
786 base::Time get_end, 783 base::Time get_end,
787 TimestampToCompare date_to_compare, 784 TimestampToCompare date_to_compare,
788 password_manager::PasswordStoreChangeList* changes) { 785 password_manager::PasswordStoreChangeList* changes) {
789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 786 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
790 DCHECK(changes); 787 DCHECK(changes);
791 changes->clear(); 788 changes->clear();
792 // We could walk the list and delete items as we find them, but it is much 789 // We could walk the list and delete items as we find them, but it is much
793 // easier to build the list and use RemoveLogin() to delete them. 790 // easier to build the list and use RemoveLogin() to delete them.
794 ScopedVector<autofill::PasswordForm> forms; 791 ScopedVector<PasswordForm> forms;
795 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms)) 792 if (!GetLoginsBetween(get_begin, get_end, date_to_compare, &forms))
796 return false; 793 return false;
797 794
798 bool ok = true; 795 bool ok = true;
799 for (size_t i = 0; i < forms.size(); ++i) { 796 for (size_t i = 0; i < forms.size(); ++i) {
800 if (RemoveLogin(*forms[i])) { 797 if (RemoveLogin(*forms[i])) {
801 changes->push_back(password_manager::PasswordStoreChange( 798 changes->push_back(password_manager::PasswordStoreChange(
802 password_manager::PasswordStoreChange::REMOVE, *forms[i])); 799 password_manager::PasswordStoreChange::REMOVE, *forms[i]));
803 } else { 800 } else {
804 ok = false; 801 ok = false;
805 } 802 }
806 } 803 }
807 return ok; 804 return ok;
808 } 805 }
809
810 std::string NativeBackendGnome::GetProfileSpecificAppString() const {
811 // Originally, the application string was always just "chrome" and used only
812 // so that we had *something* to search for since GNOME Keyring won't search
813 // for nothing. Now we use it to distinguish passwords for different profiles.
814 return base::StringPrintf("%s-%d", kGnomeKeyringAppString, profile_id_);
815 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698