• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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.
4 
5 #ifndef COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_
6 #define COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_
7 
8 #include <map>
9 #include <vector>
10 
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "components/autofill/core/common/password_form_fill_data.h"
14 #include "content/public/renderer/render_view_observer.h"
15 #include "third_party/WebKit/public/web/WebInputElement.h"
16 
17 namespace blink {
18 class WebInputElement;
19 class WebKeyboardEvent;
20 class WebSecurityOrigin;
21 class WebView;
22 }
23 
24 namespace autofill {
25 
26 // This class is responsible for filling password forms.
27 // There is one PasswordAutofillAgent per RenderView.
28 class PasswordAutofillAgent : public content::RenderViewObserver {
29  public:
30   explicit PasswordAutofillAgent(content::RenderView* render_view);
31   virtual ~PasswordAutofillAgent();
32 
33   // WebViewClient editor related calls forwarded by the RenderView.
34   // If they return true, it indicates the event was consumed and should not
35   // be used for any other autofill activity.
36   bool TextFieldDidEndEditing(const blink::WebInputElement& element);
37   bool TextDidChangeInTextField(const blink::WebInputElement& element);
38   bool TextFieldHandlingKeyDown(const blink::WebInputElement& element,
39                                 const blink::WebKeyboardEvent& event);
40 
41   // Fills the username and password fields of this form with the given values.
42   // Returns true if the fields were filled, false otherwise.
43   bool FillSuggestion(const blink::WebNode& node,
44                       const blink::WebString& username,
45                       const blink::WebString& password);
46 
47   // Previews the username and password fields of this form with the given
48   // values. Returns true if the fields were previewed, false otherwise.
49   bool PreviewSuggestion(const blink::WebNode& node,
50                          const blink::WebString& username,
51                          const blink::WebString& password);
52 
53   // Clears the preview for the username and password fields, restoring both to
54   // their previous filled state. Return false if no login information was
55   // found for the form.
56   bool DidClearAutofillSelection(const blink::WebNode& node);
57   // Shows an Autofill popup with username suggestions for |element|. If
58   // |show_all| is |true|, will show all possible suggestions for that element,
59   // otherwise shows suggestions based on current value of |element|.
60   // Returns true if any suggestions were shown, false otherwise.
61   bool ShowSuggestions(const blink::WebInputElement& element, bool show_all);
62 
63   // Called when new form controls are inserted.
64   void OnDynamicFormsSeen(blink::WebFrame* frame);
65 
66   // Called when the user first interacts with the page after a load. This is a
67   // signal to make autofilled values of password input elements accessible to
68   // JavaScript.
69   void FirstUserGestureObserved();
70 
71  protected:
72   virtual bool OriginCanAccessPasswordManager(
73       const blink::WebSecurityOrigin& origin);
74 
75  private:
76   enum OtherPossibleUsernamesUsage {
77     NOTHING_TO_AUTOFILL,
78     OTHER_POSSIBLE_USERNAMES_ABSENT,
79     OTHER_POSSIBLE_USERNAMES_PRESENT,
80     OTHER_POSSIBLE_USERNAME_SHOWN,
81     OTHER_POSSIBLE_USERNAME_SELECTED,
82     OTHER_POSSIBLE_USERNAMES_MAX
83   };
84 
85   // Ways to restrict which passwords are saved in ProvisionallySavePassword.
86   enum ProvisionallySaveRestriction {
87     RESTRICTION_NONE,
88     RESTRICTION_NON_EMPTY_PASSWORD
89   };
90 
91   struct PasswordInfo {
92     blink::WebInputElement password_field;
93     PasswordFormFillData fill_data;
94     bool backspace_pressed_last;
95     // The user manually edited the password more recently than the username was
96     // changed.
97     bool password_was_edited_last;
98     PasswordInfo();
99   };
100   typedef std::map<blink::WebElement, PasswordInfo> LoginToPasswordInfoMap;
101   typedef std::map<blink::WebElement, blink::WebElement> PasswordToLoginMap;
102   typedef std::map<blink::WebFrame*,
103                    linked_ptr<PasswordForm> > FrameToPasswordFormMap;
104 
105   // This class keeps track of autofilled password input elements and makes sure
106   // the autofilled password value is not accessible to JavaScript code until
107   // the user interacts with the page.
108   class PasswordValueGatekeeper {
109    public:
110     PasswordValueGatekeeper();
111     ~PasswordValueGatekeeper();
112 
113     // Call this for every autofilled password field, so that the gatekeeper
114     // protects the value accordingly.
115     void RegisterElement(blink::WebInputElement* element);
116 
117     // Call this to notify the gatekeeper that the user interacted with the
118     // page.
119     void OnUserGesture();
120 
121     // Call this to reset the gatekeeper on a new page navigation.
122     void Reset();
123 
124    private:
125     // Make the value of |element| accessible to JavaScript code.
126     void ShowValue(blink::WebInputElement* element);
127 
128     bool was_user_gesture_seen_;
129     std::vector<blink::WebInputElement> elements_;
130 
131     DISALLOW_COPY_AND_ASSIGN(PasswordValueGatekeeper);
132   };
133 
134   // RenderViewObserver:
135   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
136   virtual void DidStartProvisionalLoad(blink::WebLocalFrame* frame) OVERRIDE;
137   virtual void DidStartLoading() OVERRIDE;
138   virtual void DidFinishDocumentLoad(blink::WebLocalFrame* frame) OVERRIDE;
139   virtual void DidFinishLoad(blink::WebLocalFrame* frame) OVERRIDE;
140   virtual void DidStopLoading() OVERRIDE;
141   virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
142   virtual void FrameWillClose(blink::WebFrame* frame) OVERRIDE;
143   virtual void WillSendSubmitEvent(blink::WebLocalFrame* frame,
144                                    const blink::WebFormElement& form) OVERRIDE;
145   virtual void WillSubmitForm(blink::WebLocalFrame* frame,
146                               const blink::WebFormElement& form) OVERRIDE;
147 
148   // RenderView IPC handlers:
149   void OnFillPasswordForm(const PasswordFormFillData& form_data);
150   void OnSetLoggingState(bool active);
151 
152   // Scans the given frame for password forms and sends them up to the browser.
153   // If |only_visible| is true, only forms visible in the layout are sent.
154   void SendPasswordForms(blink::WebFrame* frame, bool only_visible);
155 
156   void GetSuggestions(const PasswordFormFillData& fill_data,
157                       const base::string16& input,
158                       std::vector<base::string16>* suggestions,
159                       std::vector<base::string16>* realms,
160                       bool show_all);
161 
162   bool ShowSuggestionPopup(const PasswordFormFillData& fill_data,
163                            const blink::WebInputElement& user_input,
164                            bool show_all);
165 
166   // Attempts to fill |username_element| and |password_element| with the
167   // |fill_data|.  Will use the data corresponding to the preferred username,
168   // unless the |username_element| already has a value set.  In that case,
169   // attempts to fill the password matching the already filled username, if
170   // such a password exists.
171   void FillFormOnPasswordRecieved(const PasswordFormFillData& fill_data,
172                                   blink::WebInputElement username_element,
173                                   blink::WebInputElement password_element);
174 
175   bool FillUserNameAndPassword(blink::WebInputElement* username_element,
176                                blink::WebInputElement* password_element,
177                                const PasswordFormFillData& fill_data,
178                                bool exact_username_match,
179                                bool set_selection);
180 
181   // Fills |login_input| and |password| with the most relevant suggestion from
182   // |fill_data| and shows a popup with other suggestions.
183   void PerformInlineAutocomplete(
184       const blink::WebInputElement& username,
185       const blink::WebInputElement& password,
186       const PasswordFormFillData& fill_data);
187 
188   // Invoked when the passed frame is closing.  Gives us a chance to clear any
189   // reference we may have to elements in that frame.
190   void FrameClosing(const blink::WebFrame* frame);
191 
192   // Finds login information for a |node| that was previously filled.
193   bool FindLoginInfo(const blink::WebNode& node,
194                      blink::WebInputElement* found_input,
195                      PasswordInfo** found_password);
196 
197   // Clears the preview for the username and password fields, restoring both to
198   // their previous filled state.
199   void ClearPreview(blink::WebInputElement* username,
200                     blink::WebInputElement* password);
201 
202   // If |provisionally_saved_forms_| contains a form for |current_frame| or its
203   // children, return such frame.
204   blink::WebFrame* CurrentOrChildFrameWithSavedForms(
205       const blink::WebFrame* current_frame);
206 
207   // Extracts a PasswordForm from |form| and saves it as
208   // |provisionally_saved_forms_[frame]|, as long as it satisfies |restriction|.
209   void ProvisionallySavePassword(blink::WebLocalFrame* frame,
210                                  const blink::WebFormElement& form,
211                                  ProvisionallySaveRestriction restriction);
212 
213   // The logins we have filled so far with their associated info.
214   LoginToPasswordInfoMap login_to_password_info_;
215   // A (sort-of) reverse map to |login_to_password_info_|.
216   PasswordToLoginMap password_to_username_;
217 
218   // Used for UMA stats.
219   OtherPossibleUsernamesUsage usernames_usage_;
220 
221   // Pointer to the WebView. Used to access page scale factor.
222   blink::WebView* web_view_;
223 
224   // Set if the user might be submitting a password form on the current page,
225   // but the submit may still fail (i.e. doesn't pass JavaScript validation).
226   FrameToPasswordFormMap provisionally_saved_forms_;
227 
228   PasswordValueGatekeeper gatekeeper_;
229 
230   // True indicates that user debug information should be logged.
231   bool logging_state_active_;
232 
233   // True indicates that the username field was autofilled, false otherwise.
234   bool was_username_autofilled_;
235   // True indicates that the password field was autofilled, false otherwise.
236   bool was_password_autofilled_;
237 
238   // Records original starting point of username element's selection range
239   // before preview.
240   int username_selection_start_;
241 
242   // True indicates that all frames in a page have been rendered.
243   bool did_stop_loading_;
244 
245   base::WeakPtrFactory<PasswordAutofillAgent> weak_ptr_factory_;
246 
247   DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgent);
248 };
249 
250 }  // namespace autofill
251 
252 #endif  // COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_AUTOFILL_AGENT_H_
253