Home | History | Annotate | Download | only in browser
      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 #include "base/logging.h"
      6 #include "components/autofill/core/browser/autofill_driver.h"
      7 #include "components/autofill/core/browser/popup_item_ids.h"
      8 #include "components/autofill/core/common/autofill_data_validation.h"
      9 #include "components/password_manager/core/browser/password_autofill_manager.h"
     10 #include "components/password_manager/core/browser/password_manager_client.h"
     11 #include "components/password_manager/core/browser/password_manager_driver.h"
     12 
     13 namespace password_manager {
     14 
     15 ////////////////////////////////////////////////////////////////////////////////
     16 // PasswordAutofillManager, public:
     17 
     18 PasswordAutofillManager::PasswordAutofillManager(
     19     PasswordManagerClient* password_manager_client,
     20     autofill::AutofillClient* autofill_client)
     21     : password_manager_client_(password_manager_client),
     22       autofill_client_(autofill_client),
     23       weak_ptr_factory_(this) {
     24 }
     25 
     26 PasswordAutofillManager::~PasswordAutofillManager() {
     27 }
     28 
     29 bool PasswordAutofillManager::FillSuggestion(
     30     const autofill::FormFieldData& field,
     31     const base::string16& username) {
     32   autofill::PasswordFormFillData fill_data;
     33   base::string16 password;
     34   if (FindLoginInfo(field, &fill_data) &&
     35       GetPasswordForUsername(username, fill_data, &password)) {
     36     PasswordManagerDriver* driver = password_manager_client_->GetDriver();
     37     driver->FillSuggestion(username, password);
     38     return true;
     39   }
     40   return false;
     41 }
     42 
     43 bool PasswordAutofillManager::PreviewSuggestion(
     44     const autofill::FormFieldData& field,
     45     const base::string16& username) {
     46   autofill::PasswordFormFillData fill_data;
     47   base::string16 password;
     48   if (FindLoginInfo(field, &fill_data) &&
     49       GetPasswordForUsername(username, fill_data, &password)) {
     50     PasswordManagerDriver* driver = password_manager_client_->GetDriver();
     51     driver->PreviewSuggestion(username, password);
     52     return true;
     53   }
     54   return false;
     55 }
     56 
     57 void PasswordAutofillManager::OnAddPasswordFormMapping(
     58     const autofill::FormFieldData& field,
     59     const autofill::PasswordFormFillData& fill_data) {
     60   if (!autofill::IsValidFormFieldData(field) ||
     61       !autofill::IsValidPasswordFormFillData(fill_data))
     62     return;
     63 
     64   login_to_password_info_[field] = fill_data;
     65 }
     66 
     67 void PasswordAutofillManager::OnShowPasswordSuggestions(
     68     const autofill::FormFieldData& field,
     69     const gfx::RectF& bounds,
     70     const std::vector<base::string16>& suggestions,
     71     const std::vector<base::string16>& realms) {
     72   if (!autofill::IsValidString16Vector(suggestions) ||
     73       !autofill::IsValidString16Vector(realms) ||
     74       suggestions.size() != realms.size())
     75     return;
     76 
     77   form_field_ = field;
     78 
     79   if (suggestions.empty()) {
     80     autofill_client_->HideAutofillPopup();
     81     return;
     82   }
     83 
     84   std::vector<base::string16> empty(suggestions.size());
     85   std::vector<int> password_ids(suggestions.size(),
     86                                 autofill::POPUP_ITEM_ID_PASSWORD_ENTRY);
     87   autofill_client_->ShowAutofillPopup(bounds,
     88                                       field.text_direction,
     89                                       suggestions,
     90                                       realms,
     91                                       empty,
     92                                       password_ids,
     93                                       weak_ptr_factory_.GetWeakPtr());
     94 }
     95 
     96 void PasswordAutofillManager::Reset() {
     97   login_to_password_info_.clear();
     98 }
     99 
    100 bool PasswordAutofillManager::FillSuggestionForTest(
    101     const autofill::FormFieldData& field,
    102     const base::string16& username) {
    103   return FillSuggestion(field, username);
    104 }
    105 
    106 bool PasswordAutofillManager::PreviewSuggestionForTest(
    107     const autofill::FormFieldData& field,
    108     const base::string16& username) {
    109   return PreviewSuggestion(field, username);
    110 }
    111 
    112 void PasswordAutofillManager::OnPopupShown() {
    113 }
    114 
    115 void PasswordAutofillManager::OnPopupHidden() {
    116 }
    117 
    118 void PasswordAutofillManager::DidSelectSuggestion(const base::string16& value,
    119                                                   int identifier) {
    120   ClearPreviewedForm();
    121   bool success = PreviewSuggestion(form_field_, value);
    122   DCHECK(success);
    123 }
    124 
    125 void PasswordAutofillManager::DidAcceptSuggestion(const base::string16& value,
    126                                                   int identifier) {
    127   bool success = FillSuggestion(form_field_, value);
    128   DCHECK(success);
    129   autofill_client_->HideAutofillPopup();
    130 }
    131 
    132 void PasswordAutofillManager::RemoveSuggestion(const base::string16& value,
    133                                                int identifier) {
    134   NOTREACHED();
    135 }
    136 
    137 void PasswordAutofillManager::ClearPreviewedForm() {
    138   PasswordManagerDriver* driver = password_manager_client_->GetDriver();
    139   driver->ClearPreviewedForm();
    140 }
    141 
    142 ////////////////////////////////////////////////////////////////////////////////
    143 // PasswordAutofillManager, private:
    144 
    145 bool PasswordAutofillManager::GetPasswordForUsername(
    146     const base::string16& current_username,
    147     const autofill::PasswordFormFillData& fill_data,
    148     base::string16* password) {
    149   // TODO(dubroy): When password access requires some kind of authentication
    150   // (e.g. Keychain access on Mac OS), use |password_manager_client_| here to
    151   // fetch the actual password. See crbug.com/178358 for more context.
    152 
    153   // Look for any suitable matches to current field text.
    154   if (fill_data.basic_data.fields[0].value == current_username) {
    155     *password = fill_data.basic_data.fields[1].value;
    156     return true;
    157   }
    158 
    159   // Scan additional logins for a match.
    160   for (autofill::PasswordFormFillData::LoginCollection::const_iterator iter =
    161            fill_data.additional_logins.begin();
    162        iter != fill_data.additional_logins.end();
    163        ++iter) {
    164     if (iter->first == current_username) {
    165       *password = iter->second.password;
    166       return true;
    167     }
    168   }
    169 
    170   for (autofill::PasswordFormFillData::UsernamesCollection::const_iterator
    171            usernames_iter = fill_data.other_possible_usernames.begin();
    172        usernames_iter != fill_data.other_possible_usernames.end();
    173        ++usernames_iter) {
    174     for (size_t i = 0; i < usernames_iter->second.size(); ++i) {
    175       if (usernames_iter->second[i] == current_username) {
    176         *password = usernames_iter->first.password;
    177         return true;
    178       }
    179     }
    180   }
    181 
    182   return false;
    183 }
    184 
    185 bool PasswordAutofillManager::FindLoginInfo(
    186     const autofill::FormFieldData& field,
    187     autofill::PasswordFormFillData* found_password) {
    188   LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(field);
    189   if (iter == login_to_password_info_.end())
    190     return false;
    191 
    192   *found_password = iter->second;
    193   return true;
    194 }
    195 
    196 }  //  namespace password_manager
    197