diff options
author | gcasto@chromium.org <gcasto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 01:09:12 +0000 |
---|---|---|
committer | gcasto@chromium.org <gcasto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 01:09:12 +0000 |
commit | 0660a8c72b2841655ae2e0b852e7f8aca4b602b3 (patch) | |
tree | d56f2fa87ad6a35815e30f322f915b83757b0752 /components | |
parent | dcf99f46e7eeee2c2633d0eabb2f4dd21a5aaa79 (diff) | |
download | chromium_src-0660a8c72b2841655ae2e0b852e7f8aca4b602b3.zip chromium_src-0660a8c72b2841655ae2e0b852e7f8aca4b602b3.tar.gz chromium_src-0660a8c72b2841655ae2e0b852e7f8aca4b602b3.tar.bz2 |
[password autofill] Remove references to PasswordForm from RenderViewImpl
autofill::PasswordAutofillAgent now manages submitted passwords instead. Browser side classes other than PasswordManager which want to monitor these submits do so via registering a callback with PasswordManager::AddSubmissionsCallback().
This is the first step in moving content::PasswordForm to autofill::PasswordForm.
BUG=263121
Review URL: https://chromiumcodereview.appspot.com/19705013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217900 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
3 files changed, 76 insertions, 0 deletions
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index b6294ab..c2f8267 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc @@ -24,6 +24,7 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebSecurityOrigin.h" +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/base/keycodes/keyboard_codes.h" @@ -428,6 +429,65 @@ void PasswordAutofillAgent::FrameWillClose(WebKit::WebFrame* frame) { FrameClosing(frame); } +void PasswordAutofillAgent::WillSendSubmitEvent( + WebKit::WebFrame* frame, + const WebKit::WebFormElement& form) { + // Some login forms have onSubmit handlers that put a hash of the password + // into a hidden field and then clear the password (http://crbug.com/28910). + // This method gets called before any of those handlers run, so save away + // a copy of the password in case it gets lost. + provisionally_saved_forms_[frame].reset( + content::CreatePasswordForm(form).release()); +} + +void PasswordAutofillAgent::WillSubmitForm(WebKit::WebFrame* frame, + const WebKit::WebFormElement& form) { + scoped_ptr<content::PasswordForm> submitted_form = + content::CreatePasswordForm(form); + + // If there is a provisionally saved password, copy over the previous + // password value so we get the user's typed password, not the value that + // may have been transformed for submit. + // TODO(gcasto): Do we need to have this action equality check? Is it trying + // to prevent accidentally copying over passwords from a different form? + if (submitted_form) { + if (provisionally_saved_forms_[frame].get() && + submitted_form->action == provisionally_saved_forms_[frame]->action) { + submitted_form->password_value = + provisionally_saved_forms_[frame]->password_value; + } + + // Some observers depend on sending this information now instead of when + // the frame starts loading. If there are redirects that cause a new + // RenderView to be instantiated (such as redirects to the WebStore) + // we will never get to finish the load. + Send(new AutofillHostMsg_PasswordFormSubmitted(routing_id(), + *submitted_form)); + // Remove reference since we have already submitted this form. + provisionally_saved_forms_.erase(frame); + } +} + +void PasswordAutofillAgent::DidStartProvisionalLoad(WebKit::WebFrame* frame) { + if (!frame->parent()) { + // If the navigation is not triggered by a user gesture, e.g. by some ajax + // callback, then inherit the submitted password form from the previous + // state. This fixes the no password save issue for ajax login, tracked in + // [http://crbug/43219]. Note that there are still some sites that this + // fails for because they use some element other than a submit button to + // trigger submission (which means WillSendSubmitEvent will not be called). + if (!WebKit::WebUserGestureIndicator::isProcessingUserGesture() && + provisionally_saved_forms_[frame].get()) { + Send(new AutofillHostMsg_PasswordFormSubmitted( + routing_id(), + *provisionally_saved_forms_[frame])); + provisionally_saved_forms_.erase(frame); + } + // Clear the whole map during main frame navigation. + provisionally_saved_forms_.clear(); + } +} + void PasswordAutofillAgent::OnFillPasswordForm( const PasswordFormFillData& form_data) { if (usernames_usage_ == NOTHING_TO_AUTOFILL) { diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index 30fef62..f151920 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h @@ -8,6 +8,7 @@ #include <map> #include <vector> +#include "base/memory/linked_ptr.h" #include "base/memory/weak_ptr.h" #include "components/autofill/core/common/password_form_fill_data.h" #include "content/public/renderer/render_view_observer.h" @@ -67,14 +68,21 @@ class PasswordAutofillAgent : public content::RenderViewObserver { PasswordInfo() : backspace_pressed_last(false) {} }; typedef std::map<WebKit::WebElement, PasswordInfo> LoginToPasswordInfoMap; + typedef std::map<WebKit::WebFrame*, + linked_ptr<content::PasswordForm> > FrameToPasswordFormMap; // RenderViewObserver: virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void DidStartProvisionalLoad(WebKit::WebFrame* frame) OVERRIDE; virtual void DidStartLoading() OVERRIDE; virtual void DidFinishDocumentLoad(WebKit::WebFrame* frame) OVERRIDE; virtual void DidFinishLoad(WebKit::WebFrame* frame) OVERRIDE; virtual void FrameDetached(WebKit::WebFrame* frame) OVERRIDE; virtual void FrameWillClose(WebKit::WebFrame* frame) OVERRIDE; + virtual void WillSendSubmitEvent(WebKit::WebFrame* frame, + const WebKit::WebFormElement& form) OVERRIDE; + virtual void WillSubmitForm(WebKit::WebFrame* frame, + const WebKit::WebFormElement& form) OVERRIDE; // RenderView IPC handlers: void OnFillPasswordForm(const PasswordFormFillData& form_data); @@ -123,6 +131,10 @@ class PasswordAutofillAgent : public content::RenderViewObserver { // Pointer to the WebView. Used to access page scale factor. WebKit::WebView* web_view_; + // Set if the user might be submitting a password form on the current page, + // but the submit may still fail (i.e. doesn't pass JavaScript validation). + FrameToPasswordFormMap provisionally_saved_forms_; + base::WeakPtrFactory<PasswordAutofillAgent> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgent); diff --git a/components/autofill/core/common/autofill_messages.h b/components/autofill/core/common/autofill_messages.h index 13524df..b17ae64 100644 --- a/components/autofill/core/common/autofill_messages.h +++ b/components/autofill/core/common/autofill_messages.h @@ -212,6 +212,10 @@ IPC_MESSAGE_ROUTED1(AutofillHostMsg_PasswordFormsParsed, IPC_MESSAGE_ROUTED1(AutofillHostMsg_PasswordFormsRendered, std::vector<content::PasswordForm> /* forms */) +// Notification that this password form was submitted by the user. +IPC_MESSAGE_ROUTED1(AutofillHostMsg_PasswordFormSubmitted, + content::PasswordForm /* form */) + // Notification that a form has been submitted. The user hit the button. IPC_MESSAGE_ROUTED2(AutofillHostMsg_FormSubmitted, autofill::FormData /* form */, |