Home | History | Annotate | Download | only in passwords
      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.
      4 
      5 #ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
      6 #define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
      7 
      8 #include "base/gtest_prod_util.h"
      9 #include "base/memory/scoped_vector.h"
     10 #include "base/timer/elapsed_timer.h"
     11 #include "components/autofill/core/common/password_form.h"
     12 #include "components/password_manager/core/browser/password_form_manager.h"
     13 #include "components/password_manager/core/browser/password_store.h"
     14 #include "components/password_manager/core/browser/password_store_change.h"
     15 #include "components/password_manager/core/common/password_manager_ui.h"
     16 #include "content/public/browser/navigation_details.h"
     17 #include "content/public/browser/web_contents_observer.h"
     18 #include "content/public/browser/web_contents_user_data.h"
     19 
     20 namespace content {
     21 class WebContents;
     22 }
     23 
     24 class ManagePasswordsIcon;
     25 
     26 // Per-tab class to control the Omnibox password icon and bubble.
     27 class ManagePasswordsUIController
     28     : public content::WebContentsObserver,
     29       public content::WebContentsUserData<ManagePasswordsUIController>,
     30       public password_manager::PasswordStore::Observer {
     31  public:
     32   virtual ~ManagePasswordsUIController();
     33 
     34   // Called when the user submits a form containing login information, so we
     35   // can handle later requests to save or blacklist that login information.
     36   // This stores the provided object in form_manager_ and triggers the UI to
     37   // prompt the user about whether they would like to save the password.
     38   void OnPasswordSubmitted(password_manager::PasswordFormManager* form_manager);
     39 
     40   // Called when a form is autofilled with login information, so we can manage
     41   // password credentials for the current site which are stored in
     42   // |password_form_map|. This stores a copy of |password_form_map| and shows
     43   // the manage password icon.
     44   void OnPasswordAutofilled(const autofill::PasswordFormMap& password_form_map);
     45 
     46   // Called when a form is _not_ autofilled due to user blacklisting. This
     47   // stores a copy of |password_form_map| so that we can offer the user the
     48   // ability to reenable the manager for this form.
     49   void OnBlacklistBlockedAutofill(
     50       const autofill::PasswordFormMap& password_form_map);
     51 
     52   // PasswordStore::Observer implementation.
     53   virtual void OnLoginsChanged(
     54       const password_manager::PasswordStoreChangeList& changes) OVERRIDE;
     55 
     56   // Called from the model when the user chooses to save a password; passes the
     57   // action off to the FormManager. The controller MUST be in a pending state,
     58   // and WILL be in MANAGE_STATE after this method executes.
     59   virtual void SavePassword();
     60 
     61   // Called from the model when the user chooses to never save passwords; passes
     62   // the action off to the FormManager. The controller MUST be in a pending
     63   // state, and WILL be in BLACKLIST_STATE after this method executes.
     64   virtual void NeverSavePassword();
     65 
     66   // Called from the model when the user chooses to unblacklist the site. The
     67   // controller MUST be in BLACKLIST_STATE, and WILL be in MANAGE_STATE after
     68   // this method executes.
     69   virtual void UnblacklistSite();
     70 
     71   // Open a new tab, pointing to the password manager settings page.
     72   virtual void NavigateToPasswordManagerSettingsPage();
     73 
     74   virtual const autofill::PasswordForm& PendingCredentials() const;
     75 
     76   // Set the state of the Omnibox icon, and possibly show the associated bubble
     77   // without user interaction.
     78   virtual void UpdateIconAndBubbleState(ManagePasswordsIcon* icon);
     79 
     80   password_manager::ui::State state() const { return state_; }
     81 
     82   // True if a password is sitting around, waiting for a user to decide whether
     83   // or not to save it.
     84   bool PasswordPendingUserDecision() const;
     85 
     86   const autofill::PasswordFormMap best_matches() const {
     87     return password_form_map_;
     88   }
     89 
     90   const GURL& origin() const { return origin_; }
     91 
     92  protected:
     93   explicit ManagePasswordsUIController(
     94       content::WebContents* web_contents);
     95 
     96   // content::WebContentsObserver:
     97   virtual void DidNavigateMainFrame(
     98       const content::LoadCommittedDetails& details,
     99       const content::FrameNavigateParams& params) OVERRIDE;
    100 
    101   // All previously stored credentials for a specific site. Set by
    102   // OnPasswordSubmitted(), OnPasswordAutofilled(), or
    103   // OnBlacklistBlockedAutofill(). Protected, not private, so we can mess with
    104   // the value in ManagePasswordsUIControllerMock.
    105   autofill::PasswordFormMap password_form_map_;
    106 
    107   // We create copies of PasswordForm objects that come in via OnLoginsChanged()
    108   // and store them in this vector as well as in |password_form_map_| to ensure
    109   // that we destroy them correctly.
    110   ScopedVector<autofill::PasswordForm> new_password_forms_;
    111 
    112   // The current state of the password manager. Protected so we can manipulate
    113   // the value in tests.
    114   password_manager::ui::State state_;
    115 
    116   // Used to measure the amount of time on a page; if it's less than some
    117   // reasonable limit, then don't close the bubble upon navigation. We create
    118   // (and destroy) the timer in DidNavigateMainFrame.
    119   scoped_ptr<base::ElapsedTimer> timer_;
    120 
    121  private:
    122   friend class content::WebContentsUserData<ManagePasswordsUIController>;
    123 
    124   // Shows the password bubble without user interaction. The controller MUST
    125   // be in PENDING_PASSWORD_AND_BUBBLE_STATE.
    126   void ShowBubbleWithoutUserInteraction();
    127 
    128   // Called when a passwordform is autofilled, when a new passwordform is
    129   // submitted, or when a navigation occurs to update the visibility of the
    130   // manage passwords icon and bubble.
    131   void UpdateBubbleAndIconVisibility();
    132 
    133   // content::WebContentsObserver:
    134   virtual void WebContentsDestroyed() OVERRIDE;
    135 
    136   // Set by OnPasswordSubmitted() when the user submits a form containing login
    137   // information.  If the user responds to a subsequent "Do you want to save
    138   // this password?" prompt, we ask this object to save or blacklist the
    139   // associated login information in Chrome's password store.
    140   scoped_ptr<password_manager::PasswordFormManager> form_manager_;
    141 
    142   // Stores whether autofill was blocked due to a user's decision to blacklist
    143   // the current site ("Never save passwords for this site").
    144   bool autofill_blocked_;
    145 
    146   // The origin of the form we're currently dealing with; we'll use this to
    147   // determine which PasswordStore changes we should care about when updating
    148   // |password_form_map_|.
    149   GURL origin_;
    150 
    151   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsUIController);
    152 };
    153 
    154 #endif  // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
    155