Index: components/password_manager/content/browser/content_credential_manager_dispatcher.cc |
diff --git a/components/password_manager/content/browser/content_credential_manager_dispatcher.cc b/components/password_manager/content/browser/content_credential_manager_dispatcher.cc |
index 186a1e9af45f95d26599536a43c5fbf96870accc..86203896ad0504c0d10c13d9db59e19a2f869d0b 100644 |
--- a/components/password_manager/content/browser/content_credential_manager_dispatcher.cc |
+++ b/components/password_manager/content/browser/content_credential_manager_dispatcher.cc |
@@ -5,6 +5,7 @@ |
#include "components/password_manager/content/browser/content_credential_manager_dispatcher.h" |
#include "base/bind.h" |
+#include "base/memory/scoped_vector.h" |
#include "base/strings/string16.h" |
#include "base/strings/utf_string_conversions.h" |
#include "components/autofill/core/common/password_form.h" |
@@ -21,12 +22,26 @@ |
namespace password_manager { |
+struct ContentCredentialManagerDispatcher::PendingRequestParameters { |
+ PendingRequestParameters(int request_id, |
+ bool request_zero_click_only, |
+ GURL request_origin, |
+ const std::vector<GURL>& request_federations) |
+ : id(request_id), |
+ zero_click_only(request_zero_click_only), |
+ origin(request_origin), |
+ federations(request_federations) {} |
+ |
+ int id; |
+ bool zero_click_only; |
+ GURL origin; |
+ std::vector<GURL> federations; |
+}; |
+ |
ContentCredentialManagerDispatcher::ContentCredentialManagerDispatcher( |
content::WebContents* web_contents, |
PasswordManagerClient* client) |
- : WebContentsObserver(web_contents), |
- client_(client), |
- pending_request_id_(0) { |
+ : WebContentsObserver(web_contents), client_(client) { |
DCHECK(web_contents); |
} |
@@ -93,43 +108,59 @@ void ContentCredentialManagerDispatcher::OnNotifySignedOut(int request_id) { |
void ContentCredentialManagerDispatcher::OnRequestCredential( |
int request_id, |
- bool /* zero_click_only */, |
- const std::vector<GURL>& /* federations */) { |
+ bool zero_click_only, |
+ const std::vector<GURL>& federations) { |
DCHECK(request_id); |
PasswordStore* store = GetPasswordStore(); |
- if (pending_request_id_ || !store) { |
+ if (pending_request_ || !store) { |
web_contents()->GetRenderViewHost()->Send( |
new CredentialManagerMsg_RejectCredentialRequest( |
- web_contents()->GetRenderViewHost()->GetRoutingID(), |
- request_id, |
- pending_request_id_ |
+ web_contents()->GetRenderViewHost()->GetRoutingID(), request_id, |
+ pending_request_ |
? blink::WebCredentialManagerError::ErrorTypePendingRequest |
: blink::WebCredentialManagerError:: |
ErrorTypePasswordStoreUnavailable)); |
return; |
} |
- pending_request_id_ = request_id; |
- |
- // TODO(mkwst): we should deal with federated login types. |
- autofill::PasswordForm form; |
- form.scheme = autofill::PasswordForm::SCHEME_HTML; |
- form.origin = web_contents()->GetLastCommittedURL().GetOrigin(); |
- form.signon_realm = form.origin.spec(); |
+ pending_request_.reset(new PendingRequestParameters( |
+ request_id, zero_click_only, |
+ web_contents()->GetLastCommittedURL().GetOrigin(), federations)); |
- store->GetLogins(form, PasswordStore::DISALLOW_PROMPT, this); |
+ store->GetAutofillableLogins(this); |
} |
void ContentCredentialManagerDispatcher::OnGetPasswordStoreResults( |
const std::vector<autofill::PasswordForm*>& results) { |
- DCHECK(pending_request_id_); |
- |
- if (results.empty() || |
- !client_->PromptUserToChooseCredentials(results, base::Bind( |
- &ContentCredentialManagerDispatcher::SendCredential, |
- base::Unretained(this), |
- pending_request_id_))) { |
- SendCredential(pending_request_id_, CredentialInfo()); |
+ DCHECK(pending_request_); |
+ |
+ // We own the PasswordForm instances, so we're responsible for cleaning |
+ // up the instances we don't add to |filtered_results|. We'll dump them |
+ // into a ScopedVector and allow it to delete the PasswordForms upon |
+ // destruction. |
+ std::vector<autofill::PasswordForm*> filtered_results; |
+ ScopedVector<autofill::PasswordForm> discarded_results; |
+ for (autofill::PasswordForm* form : results) { |
+ // TODO(mkwst): Extend this filter to include federations. |
+ if (form->origin == pending_request_->origin) { |
+ filtered_results.push_back(form); |
+ } else { |
+ discarded_results.push_back(form); |
+ } |
+ } |
+ |
+ if (filtered_results.empty() || |
+ web_contents()->GetLastCommittedURL().GetOrigin() != |
+ pending_request_->origin) { |
+ SendCredential(pending_request_->id, CredentialInfo()); |
+ return; |
+ } |
+ |
+ if (!client_->PromptUserToChooseCredentials( |
+ filtered_results, |
+ base::Bind(&ContentCredentialManagerDispatcher::SendCredential, |
+ base::Unretained(this), pending_request_->id))) { |
+ SendCredential(pending_request_->id, CredentialInfo()); |
} |
} |
@@ -149,14 +180,13 @@ ContentCredentialManagerDispatcher::GetDriver() { |
void ContentCredentialManagerDispatcher::SendCredential( |
int request_id, const CredentialInfo& info) { |
- DCHECK(pending_request_id_); |
- DCHECK_EQ(pending_request_id_, request_id); |
+ DCHECK(pending_request_); |
+ DCHECK_EQ(pending_request_->id, request_id); |
web_contents()->GetRenderViewHost()->Send( |
new CredentialManagerMsg_SendCredential( |
web_contents()->GetRenderViewHost()->GetRoutingID(), |
- pending_request_id_, |
- info)); |
- pending_request_id_ = 0; |
+ pending_request_->id, info)); |
+ pending_request_.reset(); |
} |
} // namespace password_manager |