Home | History | Annotate | Download | only in renderer
      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