Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: chrome/browser/password_manager/password_manager.cc

Issue 9564001: Clean up password manager code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More test compile fixes... Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/password_manager/password_manager.h" 5 #include "chrome/browser/password_manager/password_manager.h"
6 6
7 #include <vector>
8
9 #include "base/stl_util.h"
10 #include "base/threading/platform_thread.h" 7 #include "base/threading/platform_thread.h"
11 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/password_manager/password_form_manager.h" 9 #include "chrome/browser/password_manager/password_form_manager.h"
13 #include "chrome/browser/password_manager/password_manager_delegate.h" 10 #include "chrome/browser/password_manager/password_manager_delegate.h"
14 #include "chrome/browser/prefs/pref_service.h" 11 #include "chrome/browser/prefs/pref_service.h"
15 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/autofill_messages.h" 13 #include "chrome/common/autofill_messages.h"
17 #include "chrome/common/pref_names.h" 14 #include "chrome/common/pref_names.h"
18 #include "content/public/browser/user_metrics.h" 15 #include "content/public/browser/user_metrics.h"
19 #include "content/public/common/frame_navigate_params.h" 16 #include "content/public/common/frame_navigate_params.h"
20 #include "grit/generated_resources.h" 17 #include "grit/generated_resources.h"
21 18
22 using content::UserMetricsAction; 19 using content::UserMetricsAction;
23 using content::WebContents; 20 using content::WebContents;
24 using webkit::forms::PasswordForm; 21 using webkit::forms::PasswordForm;
25 using webkit::forms::PasswordFormMap; 22 using webkit::forms::PasswordFormMap;
26 23
27 // static 24 namespace {
28 void PasswordManager::RegisterUserPrefs(PrefService* prefs) {
29 prefs->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
30 true,
31 PrefService::SYNCABLE_PREF);
32 prefs->RegisterBooleanPref(prefs::kPasswordManagerAllowShowPasswords,
33 true,
34 PrefService::UNSYNCABLE_PREF);
35 }
36 25
37 // This routine is called when PasswordManagers are constructed. 26 // This routine is called when PasswordManagers are constructed.
38 // 27 //
39 // Currently we report metrics only once at startup. We require 28 // Currently we report metrics only once at startup. We require
40 // that this is only ever called from a single thread in order to 29 // that this is only ever called from a single thread in order to
41 // avoid needing to lock (a static boolean flag is then sufficient to 30 // avoid needing to lock (a static boolean flag is then sufficient to
42 // guarantee running only once). 31 // guarantee running only once).
43 static void ReportMetrics(bool password_manager_enabled) { 32 void ReportMetrics(bool password_manager_enabled) {
44 static base::PlatformThreadId initial_thread_id = 33 static base::PlatformThreadId initial_thread_id =
45 base::PlatformThread::CurrentId(); 34 base::PlatformThread::CurrentId();
46 DCHECK(initial_thread_id == base::PlatformThread::CurrentId()); 35 DCHECK(initial_thread_id == base::PlatformThread::CurrentId());
47 36
48 static bool ran_once = false; 37 static bool ran_once = false;
49 if (ran_once) 38 if (ran_once)
50 return; 39 return;
51 ran_once = true; 40 ran_once = true;
52 41
42 // TODO(isherman): This does not actually measure a user action. It should be
43 // a boolean histogram.
53 if (password_manager_enabled) 44 if (password_manager_enabled)
54 content::RecordAction(UserMetricsAction("PasswordManager_Enabled")); 45 content::RecordAction(UserMetricsAction("PasswordManager_Enabled"));
55 else 46 else
56 content::RecordAction(UserMetricsAction("PasswordManager_Disabled")); 47 content::RecordAction(UserMetricsAction("PasswordManager_Disabled"));
57 } 48 }
58 49
50 } // anonymous namespace
51
52 // static
53 void PasswordManager::RegisterUserPrefs(PrefService* prefs) {
54 prefs->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
55 true,
56 PrefService::SYNCABLE_PREF);
57 prefs->RegisterBooleanPref(prefs::kPasswordManagerAllowShowPasswords,
58 true,
59 PrefService::UNSYNCABLE_PREF);
60 }
61
59 PasswordManager::PasswordManager(WebContents* web_contents, 62 PasswordManager::PasswordManager(WebContents* web_contents,
60 PasswordManagerDelegate* delegate) 63 PasswordManagerDelegate* delegate)
61 : content::WebContentsObserver(web_contents), 64 : content::WebContentsObserver(web_contents),
62 login_managers_deleter_(&pending_login_managers_),
63 delegate_(delegate), 65 delegate_(delegate),
64 observer_(NULL) { 66 observer_(NULL) {
65 DCHECK(delegate_); 67 DCHECK(delegate_);
66 password_manager_enabled_.Init(prefs::kPasswordManagerEnabled, 68 password_manager_enabled_.Init(prefs::kPasswordManagerEnabled,
67 delegate_->GetProfileForPasswordManager()->GetPrefs(), NULL); 69 delegate_->GetProfileForPasswordManager()->GetPrefs(), NULL);
68 70
69 ReportMetrics(*password_manager_enabled_); 71 ReportMetrics(*password_manager_enabled_);
70 } 72 }
71 73
72 PasswordManager::~PasswordManager() { 74 PasswordManager::~PasswordManager() {
73 } 75 }
74 76
75 void PasswordManager::ProvisionallySavePassword(PasswordForm form) { 77 void PasswordManager::ProvisionallySavePassword(const PasswordForm& form) {
76 if (!delegate_->GetProfileForPasswordManager() || 78 if (!IsEnabled())
77 delegate_->GetProfileForPasswordManager()->IsOffTheRecord() ||
78 !*password_manager_enabled_)
79 return; 79 return;
80 80
81 // No password to save? Then don't. 81 // No password to save? Then don't.
82 if (form.password_value.empty()) 82 if (form.password_value.empty())
83 return; 83 return;
84 84
85 LoginManagers::iterator iter;
86 PasswordFormManager* manager = NULL; 85 PasswordFormManager* manager = NULL;
87 for (iter = pending_login_managers_.begin(); 86 for (ScopedVector<PasswordFormManager>::iterator iter =
88 iter != pending_login_managers_.end(); iter++) { 87 pending_login_managers_.begin();
88 iter != pending_login_managers_.end(); ++iter) {
89 if ((*iter)->DoesManage(form)) { 89 if ((*iter)->DoesManage(form)) {
90 manager = *iter; 90 manager = *iter;
91 pending_login_managers_.weak_erase(iter);
91 break; 92 break;
92 } 93 }
93 } 94 }
94 // If we didn't find a manager, this means a form was submitted without 95 // If we didn't find a manager, this means a form was submitted without
95 // first loading the page containing the form. Don't offer to save 96 // first loading the page containing the form. Don't offer to save
96 // passwords in this case. 97 // passwords in this case.
97 if (!manager) 98 if (!manager)
98 return; 99 return;
99 100
100 // If we found a manager but it didn't finish matching yet, the user has 101 // If we found a manager but it didn't finish matching yet, the user has
101 // tried to submit credentials before we had time to even find matching 102 // tried to submit credentials before we had time to even find matching
102 // results for the given form and autofill. If this is the case, we just 103 // results for the given form and autofill. If this is the case, we just
103 // give up. 104 // give up.
104 if (!manager->HasCompletedMatching()) 105 if (!manager->HasCompletedMatching())
105 return; 106 return;
106 107
107 // Also get out of here if the user told us to 'never remember' passwords for 108 // Also get out of here if the user told us to 'never remember' passwords for
108 // this form. 109 // this form.
109 if (manager->IsBlacklisted()) 110 if (manager->IsBlacklisted())
110 return; 111 return;
111 112
112 form.ssl_valid = form.origin.SchemeIsSecure() && 113 PasswordForm provisionally_saved_form(form);
114 provisionally_saved_form.ssl_valid = form.origin.SchemeIsSecure() &&
113 !delegate_->DidLastPageLoadEncounterSSLErrors(); 115 !delegate_->DidLastPageLoadEncounterSSLErrors();
114 form.preferred = true; 116 provisionally_saved_form.preferred = true;
115 manager->ProvisionallySave(form); 117 manager->ProvisionallySave(provisionally_saved_form);
116 provisional_save_manager_.reset(manager); 118 provisional_save_manager_.reset(manager);
Mike Mammarella 2012/03/01 08:23:51 Do we want to clear pending_login_managers_ here,
Ilya Sherman 2012/03/01 08:39:18 AFAICT, this is only ever called from DidNavigateA
117 pending_login_managers_.erase(iter);
118 // We don't care about the rest of the forms on the page now that one
119 // was selected.
120 STLDeleteElements(&pending_login_managers_);
121 }
122
123 void PasswordManager::DidNavigate() {
124 // As long as this navigation isn't due to a currently pending
125 // password form submit, we're ready to reset and move on.
126 if (!provisional_save_manager_.get() && !pending_login_managers_.empty())
127 STLDeleteElements(&pending_login_managers_);
128 }
129
130 void PasswordManager::ClearProvisionalSave() {
131 provisional_save_manager_.reset();
132 } 119 }
133 120
134 void PasswordManager::SetObserver(LoginModelObserver* observer) { 121 void PasswordManager::SetObserver(LoginModelObserver* observer) {
135 observer_ = observer; 122 observer_ = observer;
136 } 123 }
137 124
138 void PasswordManager::DidStopLoading() { 125 void PasswordManager::DidStopLoading() {
139 if (!provisional_save_manager_.get()) 126 if (!provisional_save_manager_.get())
140 return; 127 return;
141 128
142 DCHECK(!delegate_->GetProfileForPasswordManager()->IsOffTheRecord()); 129 DCHECK(IsEnabled());
143 DCHECK(!provisional_save_manager_->IsBlacklisted());
144 130
145 if (!delegate_->GetProfileForPasswordManager())
146 return;
147 // Form is not completely valid - we do not support it. 131 // Form is not completely valid - we do not support it.
148 if (!provisional_save_manager_->HasValidPasswordForm()) 132 if (!provisional_save_manager_->HasValidPasswordForm())
149 return; 133 return;
150 134
151 provisional_save_manager_->SubmitPassed(); 135 provisional_save_manager_->SubmitPassed();
152 if (provisional_save_manager_->IsNewLogin()) { 136 if (provisional_save_manager_->IsNewLogin()) {
153 delegate_->AddSavePasswordInfoBar(provisional_save_manager_.release()); 137 delegate_->AddSavePasswordInfoBar(provisional_save_manager_.release());
154 } else { 138 } else {
155 // If the save is not a new username entry, then we just want to save this 139 // If the save is not a new username entry, then we just want to save this
156 // data (since the user already has related data saved), so don't prompt. 140 // data (since the user already has related data saved), so don't prompt.
157 provisional_save_manager_->Save(); 141 provisional_save_manager_->Save();
158 provisional_save_manager_.reset(); 142 provisional_save_manager_.reset();
159 } 143 }
160 } 144 }
161 145
162 void PasswordManager::DidNavigateAnyFrame( 146 void PasswordManager::DidNavigateAnyFrame(
163 const content::LoadCommittedDetails& details, 147 const content::LoadCommittedDetails& details,
164 const content::FrameNavigateParams& params) { 148 const content::FrameNavigateParams& params) {
165 if (params.password_form.origin.is_valid()) 149 if (params.password_form.origin.is_valid())
166 ProvisionallySavePassword(params.password_form); 150 ProvisionallySavePassword(params.password_form);
151
152 // Other than possibly holding on to provisionally saved password data,
153 // we're ready to reset and move on.
154 pending_login_managers_.reset();
tim (not reviewing) 2012/03/01 17:57:52 So, two things. One, yeah, DidNavigate (then in W
Mike Mammarella 2012/03/01 19:02:04 That sounds both plausible and eminently testable.
Ilya Sherman 2012/03/02 01:07:15 Ah, that's a really good catch -- I hadn't really
167 } 155 }
168 156
169 bool PasswordManager::OnMessageReceived(const IPC::Message& message) { 157 bool PasswordManager::OnMessageReceived(const IPC::Message& message) {
170 bool handled = true; 158 bool handled = true;
171 IPC_BEGIN_MESSAGE_MAP(PasswordManager, message) 159 IPC_BEGIN_MESSAGE_MAP(PasswordManager, message)
172 IPC_MESSAGE_HANDLER(AutofillHostMsg_PasswordFormsFound, 160 IPC_MESSAGE_HANDLER(AutofillHostMsg_PasswordFormsFound,
173 OnPasswordFormsFound) 161 OnPasswordFormsFound)
174 IPC_MESSAGE_HANDLER(AutofillHostMsg_PasswordFormsVisible, 162 IPC_MESSAGE_HANDLER(AutofillHostMsg_PasswordFormsVisible,
175 OnPasswordFormsVisible) 163 OnPasswordFormsVisible)
176 IPC_MESSAGE_UNHANDLED(handled = false) 164 IPC_MESSAGE_UNHANDLED(handled = false)
177 IPC_END_MESSAGE_MAP() 165 IPC_END_MESSAGE_MAP()
178 return handled; 166 return handled;
179 } 167 }
180 168
181 void PasswordManager::OnPasswordFormsFound( 169 void PasswordManager::OnPasswordFormsFound(
182 const std::vector<PasswordForm>& forms) { 170 const std::vector<PasswordForm>& forms) {
183 if (!delegate_->GetProfileForPasswordManager()) 171 if (!IsEnabled())
184 return;
185 if (!*password_manager_enabled_)
186 return; 172 return;
187 173
188 // Ask the SSLManager for current security. 174 // Ask the SSLManager for current security.
189 bool had_ssl_error = delegate_->DidLastPageLoadEncounterSSLErrors(); 175 bool had_ssl_error = delegate_->DidLastPageLoadEncounterSSLErrors();
190 176
191 std::vector<PasswordForm>::const_iterator iter; 177 for (std::vector<PasswordForm>::const_iterator iter = forms.begin();
192 for (iter = forms.begin(); iter != forms.end(); iter++) { 178 iter != forms.end(); ++iter) {
193 bool ssl_valid = iter->origin.SchemeIsSecure() && !had_ssl_error; 179 bool ssl_valid = iter->origin.SchemeIsSecure() && !had_ssl_error;
194 PasswordFormManager* manager = 180 PasswordFormManager* manager =
195 new PasswordFormManager(delegate_->GetProfileForPasswordManager(), 181 new PasswordFormManager(delegate_->GetProfileForPasswordManager(),
196 this, *iter, ssl_valid); 182 this, *iter, ssl_valid);
197 pending_login_managers_.push_back(manager); 183 pending_login_managers_.push_back(manager);
198 manager->FetchMatchingLoginsFromPasswordStore(); 184 manager->FetchMatchingLoginsFromPasswordStore();
199 } 185 }
200 } 186 }
201 187
202 void PasswordManager::OnPasswordFormsVisible( 188 void PasswordManager::OnPasswordFormsVisible(
203 const std::vector<PasswordForm>& visible_forms) { 189 const std::vector<PasswordForm>& visible_forms) {
204 if (!provisional_save_manager_.get()) 190 if (!provisional_save_manager_.get())
205 return; 191 return;
206 std::vector<PasswordForm>::const_iterator iter; 192
207 for (iter = visible_forms.begin(); iter != visible_forms.end(); iter++) { 193 for (std::vector<PasswordForm>::const_iterator iter = visible_forms.begin();
194 iter != visible_forms.end(); ++iter) {
208 if (provisional_save_manager_->DoesManage(*iter)) { 195 if (provisional_save_manager_->DoesManage(*iter)) {
209 // The form trying to be saved has immediately re-appeared. Assume login 196 // The form trying to be saved has immediately re-appeared. Assume login
210 // failure and abort this save, by clearing provisional_save_manager_. 197 // failure and abort this save, by clearing provisional_save_manager_.
211 // Don't delete the login managers since the user may try again 198 // Don't delete the login managers since the user may try again
212 // and we want to be able to save in that case. 199 // and we want to be able to save in that case.
213 provisional_save_manager_->SubmitFailed(); 200 provisional_save_manager_->SubmitFailed();
214 ClearProvisionalSave(); 201 provisional_save_manager_.reset();
215 break; 202 break;
216 } 203 }
217 } 204 }
218 } 205 }
219 206
220 void PasswordManager::Autofill( 207 void PasswordManager::Autofill(
221 const PasswordForm& form_for_autofill, 208 const PasswordForm& form_for_autofill,
222 const PasswordFormMap& best_matches, 209 const PasswordFormMap& best_matches,
223 const PasswordForm* const preferred_match, 210 const PasswordForm& preferred_match,
224 bool wait_for_username) const { 211 bool wait_for_username) const {
225 DCHECK(preferred_match);
226 switch (form_for_autofill.scheme) { 212 switch (form_for_autofill.scheme) {
227 case PasswordForm::SCHEME_HTML: { 213 case PasswordForm::SCHEME_HTML: {
228 // Note the check above is required because the observer_ for a non-HTML 214 // Note the check above is required because the observer_ for a non-HTML
229 // schemed password form may have been freed, so we need to distinguish. 215 // schemed password form may have been freed, so we need to distinguish.
230 webkit::forms::PasswordFormFillData fill_data; 216 webkit::forms::PasswordFormFillData fill_data;
231 webkit::forms::PasswordFormDomManager::InitFillData(form_for_autofill, 217 webkit::forms::PasswordFormDomManager::InitFillData(form_for_autofill,
232 best_matches, 218 best_matches,
233 preferred_match, 219 &preferred_match,
234 wait_for_username, 220 wait_for_username,
235 &fill_data); 221 &fill_data);
236 delegate_->FillPasswordForm(fill_data); 222 delegate_->FillPasswordForm(fill_data);
237 return; 223 return;
238 } 224 }
239 default: 225 default:
240 if (observer_) { 226 if (observer_) {
241 observer_->OnAutofillDataAvailable(preferred_match->username_value, 227 observer_->OnAutofillDataAvailable(preferred_match.username_value,
242 preferred_match->password_value); 228 preferred_match.password_value);
243 } 229 }
244 } 230 }
245 } 231 }
232
233 bool PasswordManager::IsEnabled() const {
234 const Profile* profile = delegate_->GetProfileForPasswordManager();
235 return profile && !profile->IsOffTheRecord() && *password_manager_enabled_;
236 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_manager.h ('k') | chrome/browser/password_manager/password_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698