• 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 #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 
PasswordAutofillManager(PasswordManagerClient * password_manager_client,autofill::AutofillClient * autofill_client)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 
~PasswordAutofillManager()26 PasswordAutofillManager::~PasswordAutofillManager() {
27 }
28 
FillSuggestion(const autofill::FormFieldData & field,const base::string16 & username)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 
PreviewSuggestion(const autofill::FormFieldData & field,const base::string16 & username)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 
OnAddPasswordFormMapping(const autofill::FormFieldData & field,const autofill::PasswordFormFillData & fill_data)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 
OnShowPasswordSuggestions(const autofill::FormFieldData & field,const gfx::RectF & bounds,const std::vector<base::string16> & suggestions,const std::vector<base::string16> & realms)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 
Reset()96 void PasswordAutofillManager::Reset() {
97   login_to_password_info_.clear();
98 }
99 
FillSuggestionForTest(const autofill::FormFieldData & field,const base::string16 & username)100 bool PasswordAutofillManager::FillSuggestionForTest(
101     const autofill::FormFieldData& field,
102     const base::string16& username) {
103   return FillSuggestion(field, username);
104 }
105 
PreviewSuggestionForTest(const autofill::FormFieldData & field,const base::string16 & username)106 bool PasswordAutofillManager::PreviewSuggestionForTest(
107     const autofill::FormFieldData& field,
108     const base::string16& username) {
109   return PreviewSuggestion(field, username);
110 }
111 
OnPopupShown()112 void PasswordAutofillManager::OnPopupShown() {
113 }
114 
OnPopupHidden()115 void PasswordAutofillManager::OnPopupHidden() {
116 }
117 
DidSelectSuggestion(const base::string16 & value,int identifier)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 
DidAcceptSuggestion(const base::string16 & value,int identifier)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 
RemoveSuggestion(const base::string16 & value,int identifier)132 void PasswordAutofillManager::RemoveSuggestion(const base::string16& value,
133                                                int identifier) {
134   NOTREACHED();
135 }
136 
ClearPreviewedForm()137 void PasswordAutofillManager::ClearPreviewedForm() {
138   PasswordManagerDriver* driver = password_manager_client_->GetDriver();
139   driver->ClearPreviewedForm();
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 // PasswordAutofillManager, private:
144 
GetPasswordForUsername(const base::string16 & current_username,const autofill::PasswordFormFillData & fill_data,base::string16 * password)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 
FindLoginInfo(const autofill::FormFieldData & field,autofill::PasswordFormFillData * found_password)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