Roll src/third_party/WebKit c63b89c:29324ab (svn 202546:202547)
[chromium-blink-merge.git] / components / password_manager / content / browser / credential_manager_dispatcher.cc
blobbde0f0316da6145293a3251f367a3bd5b10dca4f
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/password_manager/content/browser/credential_manager_dispatcher.h"
7 #include "base/bind.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "components/autofill/core/common/password_form.h"
11 #include "components/password_manager/content/browser/content_password_manager_driver.h"
12 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
13 #include "components/password_manager/content/common/credential_manager_messages.h"
14 #include "components/password_manager/core/browser/affiliated_match_helper.h"
15 #include "components/password_manager/core/browser/password_manager_client.h"
16 #include "components/password_manager/core/browser/password_store.h"
17 #include "components/password_manager/core/common/credential_manager_types.h"
18 #include "components/password_manager/core/common/password_manager_pref_names.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/web_contents.h"
21 #include "ipc/ipc_message_macros.h"
23 namespace password_manager {
25 // CredentialManagerDispatcher -------------------------------------------------
27 CredentialManagerDispatcher::CredentialManagerDispatcher(
28 content::WebContents* web_contents,
29 PasswordManagerClient* client)
30 : WebContentsObserver(web_contents), client_(client), weak_factory_(this) {
31 DCHECK(web_contents);
32 auto_signin_enabled_.Init(prefs::kPasswordManagerAutoSignin,
33 client_->GetPrefs());
36 CredentialManagerDispatcher::~CredentialManagerDispatcher() {
39 bool CredentialManagerDispatcher::OnMessageReceived(
40 const IPC::Message& message) {
41 bool handled = true;
42 IPC_BEGIN_MESSAGE_MAP(CredentialManagerDispatcher, message)
43 IPC_MESSAGE_HANDLER(CredentialManagerHostMsg_Store, OnStore);
44 IPC_MESSAGE_HANDLER(CredentialManagerHostMsg_RequireUserMediation,
45 OnRequireUserMediation);
46 IPC_MESSAGE_HANDLER(CredentialManagerHostMsg_RequestCredential,
47 OnRequestCredential);
48 IPC_MESSAGE_UNHANDLED(handled = false)
49 IPC_END_MESSAGE_MAP()
50 return handled;
53 void CredentialManagerDispatcher::OnStore(
54 int request_id,
55 const password_manager::CredentialInfo& credential) {
56 DCHECK(credential.type != CredentialType::CREDENTIAL_TYPE_EMPTY);
57 DCHECK(request_id);
58 web_contents()->GetRenderViewHost()->Send(
59 new CredentialManagerMsg_AcknowledgeStore(
60 web_contents()->GetRenderViewHost()->GetRoutingID(), request_id));
62 if (!client_->IsSavingAndFillingEnabledForCurrentPage())
63 return;
65 scoped_ptr<autofill::PasswordForm> form(CreatePasswordFormFromCredentialInfo(
66 credential, web_contents()->GetLastCommittedURL().GetOrigin()));
67 form->skip_zero_click = !IsZeroClickAllowed();
69 // TODO(mkwst): This is a stub; we should be checking the PasswordStore to
70 // determine whether or not the credential exists, and calling UpdateLogin
71 // accordingly.
72 form_manager_.reset(new CredentialManagerPasswordFormManager(
73 client_, GetDriver(), *form, this));
76 void CredentialManagerDispatcher::OnProvisionalSaveComplete() {
77 DCHECK(form_manager_);
78 if (client_->IsSavingAndFillingEnabledForCurrentPage()) {
79 client_->PromptUserToSaveOrUpdatePassword(
80 form_manager_.Pass(), CredentialSourceType::CREDENTIAL_SOURCE_API,
81 false);
85 void CredentialManagerDispatcher::OnRequireUserMediation(int request_id) {
86 DCHECK(request_id);
88 PasswordStore* store = GetPasswordStore();
89 if (store) {
90 if (!pending_require_user_mediation_) {
91 pending_require_user_mediation_.reset(
92 new CredentialManagerPendingRequireUserMediationTask(
93 this, web_contents()->GetLastCommittedURL().GetOrigin()));
95 // This will result in a callback to
96 // CredentialManagerPendingRequireUserMediationTask::OnGetPasswordStoreResults().
97 store->GetAutofillableLogins(pending_require_user_mediation_.get());
98 } else {
99 pending_require_user_mediation_->AddOrigin(
100 web_contents()->GetLastCommittedURL().GetOrigin());
104 web_contents()->GetRenderViewHost()->Send(
105 new CredentialManagerMsg_AcknowledgeRequireUserMediation(
106 web_contents()->GetRenderViewHost()->GetRoutingID(), request_id));
109 void CredentialManagerDispatcher::OnRequestCredential(
110 int request_id,
111 bool zero_click_only,
112 const std::vector<GURL>& federations) {
113 DCHECK(request_id);
114 PasswordStore* store = GetPasswordStore();
115 if (pending_request_ || !store) {
116 web_contents()->GetRenderViewHost()->Send(
117 new CredentialManagerMsg_RejectCredentialRequest(
118 web_contents()->GetRenderViewHost()->GetRoutingID(), request_id,
119 pending_request_
120 ? blink::WebCredentialManagerError::ErrorTypePendingRequest
121 : blink::WebCredentialManagerError::
122 ErrorTypePasswordStoreUnavailable));
123 return;
126 // Return an empty credential if zero-click is required but disabled, or if
127 // the current page has TLS errors.
128 if ((zero_click_only && !IsZeroClickAllowed()) ||
129 client_->DidLastPageLoadEncounterSSLErrors()) {
130 web_contents()->GetRenderViewHost()->Send(
131 new CredentialManagerMsg_SendCredential(
132 web_contents()->GetRenderViewHost()->GetRoutingID(), request_id,
133 CredentialInfo()));
134 return;
137 if (store->affiliated_match_helper()) {
138 store->affiliated_match_helper()->GetAffiliatedAndroidRealms(
139 GetSynthesizedFormForOrigin(),
140 base::Bind(&CredentialManagerDispatcher::ScheduleRequestTask,
141 weak_factory_.GetWeakPtr(), request_id, zero_click_only,
142 federations));
143 } else {
144 std::vector<std::string> no_affiliated_realms;
145 ScheduleRequestTask(request_id, zero_click_only, federations,
146 no_affiliated_realms);
150 void CredentialManagerDispatcher::ScheduleRequestTask(
151 int request_id,
152 bool zero_click_only,
153 const std::vector<GURL>& federations,
154 const std::vector<std::string>& android_realms) {
155 DCHECK(GetPasswordStore());
156 pending_request_.reset(new CredentialManagerPendingRequestTask(
157 this, request_id, zero_click_only,
158 web_contents()->GetLastCommittedURL().GetOrigin(), federations,
159 android_realms));
161 // This will result in a callback to
162 // PendingRequestTask::OnGetPasswordStoreResults().
163 GetPasswordStore()->GetAutofillableLogins(pending_request_.get());
166 PasswordStore* CredentialManagerDispatcher::GetPasswordStore() {
167 return client_ ? client_->GetPasswordStore() : nullptr;
170 bool CredentialManagerDispatcher::IsZeroClickAllowed() const {
171 return *auto_signin_enabled_ && !client_->IsOffTheRecord();
174 GURL CredentialManagerDispatcher::GetOrigin() const {
175 return web_contents()->GetLastCommittedURL().GetOrigin();
178 base::WeakPtr<PasswordManagerDriver> CredentialManagerDispatcher::GetDriver() {
179 ContentPasswordManagerDriverFactory* driver_factory =
180 ContentPasswordManagerDriverFactory::FromWebContents(web_contents());
181 DCHECK(driver_factory);
182 PasswordManagerDriver* driver =
183 driver_factory->GetDriverForFrame(web_contents()->GetMainFrame());
184 return driver->AsWeakPtr();
187 void CredentialManagerDispatcher::SendCredential(int request_id,
188 const CredentialInfo& info) {
189 DCHECK(pending_request_);
190 DCHECK_EQ(pending_request_->id(), request_id);
192 if (PasswordStore* store = GetPasswordStore()) {
193 if (info.type != CredentialType::CREDENTIAL_TYPE_EMPTY &&
194 IsZeroClickAllowed()) {
195 scoped_ptr<autofill::PasswordForm> form(
196 CreatePasswordFormFromCredentialInfo(info,
197 pending_request_->origin()));
198 form->skip_zero_click = false;
199 store->UpdateLogin(*form);
203 web_contents()->GetRenderViewHost()->Send(
204 new CredentialManagerMsg_SendCredential(
205 web_contents()->GetRenderViewHost()->GetRoutingID(),
206 pending_request_->id(), info));
207 pending_request_.reset();
210 PasswordManagerClient* CredentialManagerDispatcher::client() const {
211 return client_;
214 autofill::PasswordForm
215 CredentialManagerDispatcher::GetSynthesizedFormForOrigin() const {
216 autofill::PasswordForm synthetic_form;
217 synthetic_form.origin = web_contents()->GetLastCommittedURL().GetOrigin();
218 synthetic_form.signon_realm = synthetic_form.origin.spec();
219 synthetic_form.scheme = autofill::PasswordForm::SCHEME_HTML;
220 synthetic_form.ssl_valid = synthetic_form.origin.SchemeIsCryptographic() &&
221 !client_->DidLastPageLoadEncounterSSLErrors();
222 return synthetic_form;
225 void CredentialManagerDispatcher::DoneRequiringUserMediation() {
226 DCHECK(pending_require_user_mediation_);
227 pending_require_user_mediation_.reset();
230 } // namespace password_manager