summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorgcasto@chromium.org <gcasto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 01:09:12 +0000
committergcasto@chromium.org <gcasto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 01:09:12 +0000
commit0660a8c72b2841655ae2e0b852e7f8aca4b602b3 (patch)
treed56f2fa87ad6a35815e30f322f915b83757b0752 /components
parentdcf99f46e7eeee2c2633d0eabb2f4dd21a5aaa79 (diff)
downloadchromium_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')
-rw-r--r--components/autofill/content/renderer/password_autofill_agent.cc60
-rw-r--r--components/autofill/content/renderer/password_autofill_agent.h12
-rw-r--r--components/autofill/core/common/autofill_messages.h4
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 */,