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

Side by Side Diff: chrome/browser/ui/webui/options/password_manager_handler.cc

Issue 1193143003: Enable import/export of passwords into/from Password Manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comment Created 4 years, 8 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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/ui/webui/options/password_manager_handler.h" 5 #include "chrome/browser/ui/webui/options/password_manager_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/debug/leak_annotations.h"
8 #include "base/feature_list.h" 10 #include "base/feature_list.h"
11 #include "base/files/file_path.h"
9 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/metrics/field_trial.h"
14 #include "base/metrics/histogram.h"
10 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h" 16 #include "base/strings/string_split.h"
12 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h" 18 #include "base/values.h"
14 #include "build/build_config.h" 19 #include "build/build_config.h"
15 #include "chrome/browser/chrome_notification_types.h" 20 #include "chrome/browser/chrome_notification_types.h"
21 #include "chrome/browser/password_manager/password_store_factory.h"
16 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/sync/profile_sync_service_factory.h" 23 #include "chrome/browser/sync/profile_sync_service_factory.h"
24 #include "chrome/browser/ui/chrome_select_file_policy.h"
18 #include "chrome/common/pref_names.h" 25 #include "chrome/common/pref_names.h"
19 #include "chrome/common/url_constants.h" 26 #include "chrome/common/url_constants.h"
20 #include "chrome/grit/generated_resources.h" 27 #include "chrome/grit/generated_resources.h"
21 #include "components/autofill/core/common/password_form.h" 28 #include "components/autofill/core/common/password_form.h"
22 #include "components/browser_sync/browser/profile_sync_service.h" 29 #include "components/browser_sync/browser/profile_sync_service.h"
30 #include "components/password_manager/core/browser/export/password_exporter.h"
23 #include "components/password_manager/core/browser/password_bubble_experiment.h" 31 #include "components/password_manager/core/browser/password_bubble_experiment.h"
24 #include "components/password_manager/core/browser/password_manager_constants.h" 32 #include "components/password_manager/core/browser/password_manager_constants.h"
33 #include "components/password_manager/core/browser/password_store.h"
25 #include "components/password_manager/core/browser/password_ui_utils.h" 34 #include "components/password_manager/core/browser/password_ui_utils.h"
26 #include "components/password_manager/core/common/experiments.h" 35 #include "components/password_manager/core/common/experiments.h"
36 #include "components/password_manager/core/common/password_manager_features.h"
27 #include "components/prefs/pref_service.h" 37 #include "components/prefs/pref_service.h"
28 #include "components/strings/grit/components_strings.h" 38 #include "components/strings/grit/components_strings.h"
29 #include "components/url_formatter/url_formatter.h" 39 #include "components/url_formatter/url_formatter.h"
40 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/notification_details.h" 41 #include "content/public/browser/notification_details.h"
31 #include "content/public/browser/notification_source.h" 42 #include "content/public/browser/notification_source.h"
32 #include "content/public/browser/user_metrics.h" 43 #include "content/public/browser/user_metrics.h"
33 #include "content/public/browser/web_contents.h" 44 #include "content/public/browser/web_contents.h"
34 #include "content/public/browser/web_ui.h" 45 #include "content/public/browser/web_ui.h"
35 #include "content/public/common/content_features.h" 46 #include "content/public/common/content_features.h"
36 #include "content/public/common/origin_util.h" 47 #include "content/public/common/origin_util.h"
37 #include "ui/base/l10n/l10n_util.h" 48 #include "ui/base/l10n/l10n_util.h"
38 49
39 #if defined(OS_WIN) && defined(USE_ASH) 50 #if defined(OS_WIN) && defined(USE_ASH)
(...skipping 30 matching lines...) Expand all
70 kUrlField, url_formatter::FormatUrl( 81 kUrlField, url_formatter::FormatUrl(
71 link_url, url_formatter::kFormatUrlOmitNothing, 82 link_url, url_formatter::kFormatUrlOmitNothing,
72 net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); 83 net::UnescapeRule::SPACES, nullptr, nullptr, nullptr));
73 entry->SetBoolean(kIsAndroidUriField, is_android_uri); 84 entry->SetBoolean(kIsAndroidUriField, is_android_uri);
74 entry->SetBoolean(kIsClickable, origin_is_clickable); 85 entry->SetBoolean(kIsClickable, origin_is_clickable);
75 entry->SetBoolean(kIsSecureField, content::IsOriginSecure(link_url)); 86 entry->SetBoolean(kIsSecureField, content::IsOriginSecure(link_url));
76 } 87 }
77 88
78 } // namespace 89 } // namespace
79 90
80 PasswordManagerHandler::PasswordManagerHandler() 91 PasswordManagerHandler::PasswordManagerHandler() {
81 : password_manager_presenter_(this) {} 92 password_manager_presenter_.reset(new PasswordManagerPresenter(this));
93 }
94
95 PasswordManagerHandler::PasswordManagerHandler(
96 scoped_ptr<PasswordManagerPresenter> presenter)
97 : password_manager_presenter_(std::move(presenter)) {}
82 98
83 PasswordManagerHandler::~PasswordManagerHandler() {} 99 PasswordManagerHandler::~PasswordManagerHandler() {}
84 100
85 Profile* PasswordManagerHandler::GetProfile() { 101 Profile* PasswordManagerHandler::GetProfile() {
86 return Profile::FromWebUI(web_ui()); 102 return Profile::FromWebUI(web_ui());
87 } 103 }
88 104
89 #if !defined(OS_ANDROID) 105 #if !defined(OS_ANDROID)
90 gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() const { 106 gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() const {
91 return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); 107 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
(...skipping 10 matching lines...) Expand all
102 {"autoSigninDescription", IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION}, 118 {"autoSigninDescription", IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION},
103 {"savedPasswordsTitle", IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE}, 119 {"savedPasswordsTitle", IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE},
104 {"passwordExceptionsTitle", IDS_PASSWORD_MANAGER_EXCEPTIONS_TAB_TITLE}, 120 {"passwordExceptionsTitle", IDS_PASSWORD_MANAGER_EXCEPTIONS_TAB_TITLE},
105 {"passwordSearchPlaceholder", IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS}, 121 {"passwordSearchPlaceholder", IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS},
106 {"passwordShowButton", IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON}, 122 {"passwordShowButton", IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON},
107 {"passwordHideButton", IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON}, 123 {"passwordHideButton", IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON},
108 {"passwordsNoPasswordsDescription", 124 {"passwordsNoPasswordsDescription",
109 IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION}, 125 IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION},
110 {"passwordsNoExceptionsDescription", 126 {"passwordsNoExceptionsDescription",
111 IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION}, 127 IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION},
128 {"passwordManagerImportPasswordButtonText",
129 IDS_PASSWORD_MANAGER_IMPORT_BUTTON},
130 {"passwordManagerExportPasswordButtonText",
131 IDS_PASSWORD_MANAGER_EXPORT_BUTTON},
112 }; 132 };
113 133
114 RegisterStrings(localized_strings, resources, arraysize(resources)); 134 RegisterStrings(localized_strings, resources, arraysize(resources));
115 135
116 const ProfileSyncService* sync_service = 136 const ProfileSyncService* sync_service =
117 ProfileSyncServiceFactory::GetForProfile(GetProfile()); 137 ProfileSyncServiceFactory::GetForProfile(GetProfile());
118 int title_id = 138 int title_id =
119 password_bubble_experiment::IsSmartLockBrandingEnabled(sync_service) 139 password_bubble_experiment::IsSmartLockBrandingEnabled(sync_service)
120 ? IDS_PASSWORD_MANAGER_SMART_LOCK_FOR_PASSWORDS 140 ? IDS_PASSWORD_MANAGER_SMART_LOCK_FOR_PASSWORDS
121 : IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE; 141 : IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 base::Bind(&PasswordManagerHandler::HandleRemoveSavedPassword, 188 base::Bind(&PasswordManagerHandler::HandleRemoveSavedPassword,
169 base::Unretained(this))); 189 base::Unretained(this)));
170 web_ui()->RegisterMessageCallback( 190 web_ui()->RegisterMessageCallback(
171 "removePasswordException", 191 "removePasswordException",
172 base::Bind(&PasswordManagerHandler::HandleRemovePasswordException, 192 base::Bind(&PasswordManagerHandler::HandleRemovePasswordException,
173 base::Unretained(this))); 193 base::Unretained(this)));
174 web_ui()->RegisterMessageCallback( 194 web_ui()->RegisterMessageCallback(
175 "requestShowPassword", 195 "requestShowPassword",
176 base::Bind(&PasswordManagerHandler::HandleRequestShowPassword, 196 base::Bind(&PasswordManagerHandler::HandleRequestShowPassword,
177 base::Unretained(this))); 197 base::Unretained(this)));
198 web_ui()->RegisterMessageCallback(
199 "importPassword",
200 base::Bind(&PasswordManagerHandler::HandlePasswordImport,
201 base::Unretained(this)));
202 web_ui()->RegisterMessageCallback(
203 "exportPassword",
204 base::Bind(&PasswordManagerHandler::HandlePasswordExport,
205 base::Unretained(this)));
178 } 206 }
179 207
180 void PasswordManagerHandler::InitializeHandler() { 208 void PasswordManagerHandler::InitializeHandler() {
181 password_manager_presenter_.Initialize(); 209 password_manager_presenter_->Initialize();
210 }
211
212 void PasswordManagerHandler::InitializePage() {
213 if (base::FeatureList::IsEnabled(
214 password_manager::features::kPasswordImportExport)) {
215 web_ui()->CallJavascriptFunction("PasswordManager.showImportExportButton");
216 }
182 } 217 }
183 218
184 void PasswordManagerHandler::HandleRemoveSavedPassword( 219 void PasswordManagerHandler::HandleRemoveSavedPassword(
185 const base::ListValue* args) { 220 const base::ListValue* args) {
186 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); 221 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args));
187 int index; 222 int index;
188 if (base::StringToInt(string_value, &index) && index >= 0) { 223 if (base::StringToInt(string_value, &index) && index >= 0) {
189 password_manager_presenter_.RemoveSavedPassword(static_cast<size_t>(index)); 224 password_manager_presenter_->RemoveSavedPassword(
225 static_cast<size_t>(index));
190 } 226 }
191 } 227 }
192 228
193 void PasswordManagerHandler::HandleRemovePasswordException( 229 void PasswordManagerHandler::HandleRemovePasswordException(
194 const base::ListValue* args) { 230 const base::ListValue* args) {
195 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); 231 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args));
196 int index; 232 int index;
197 if (base::StringToInt(string_value, &index) && index >= 0) { 233 if (base::StringToInt(string_value, &index) && index >= 0) {
198 password_manager_presenter_.RemovePasswordException( 234 password_manager_presenter_->RemovePasswordException(
199 static_cast<size_t>(index)); 235 static_cast<size_t>(index));
200 } 236 }
201 } 237 }
202 238
203 void PasswordManagerHandler::HandleRequestShowPassword( 239 void PasswordManagerHandler::HandleRequestShowPassword(
204 const base::ListValue* args) { 240 const base::ListValue* args) {
205 int index; 241 int index;
206 if (!ExtractIntegerValue(args, &index)) 242 if (!ExtractIntegerValue(args, &index))
207 NOTREACHED(); 243 NOTREACHED();
208 244
209 password_manager_presenter_.RequestShowPassword(static_cast<size_t>(index)); 245 password_manager_presenter_->RequestShowPassword(static_cast<size_t>(index));
210 } 246 }
211 247
212 void PasswordManagerHandler::ShowPassword( 248 void PasswordManagerHandler::ShowPassword(
213 size_t index, 249 size_t index,
214 const std::string& origin_url, 250 const std::string& origin_url,
215 const std::string& username, 251 const std::string& username,
216 const base::string16& password_value) { 252 const base::string16& password_value) {
217 // Call back the front end to reveal the password. 253 // Call back the front end to reveal the password.
218 web_ui()->CallJavascriptFunction( 254 web_ui()->CallJavascriptFunction(
219 "PasswordManager.showPassword", 255 "PasswordManager.showPassword",
220 base::FundamentalValue(static_cast<int>(index)), 256 base::FundamentalValue(static_cast<int>(index)),
221 base::StringValue(password_value)); 257 base::StringValue(password_value));
222 } 258 }
223 259
224 void PasswordManagerHandler::HandleUpdatePasswordLists( 260 void PasswordManagerHandler::HandleUpdatePasswordLists(
225 const base::ListValue* args) { 261 const base::ListValue* args) {
226 password_manager_presenter_.UpdatePasswordLists(); 262 password_manager_presenter_->UpdatePasswordLists();
227 } 263 }
228 264
229 void PasswordManagerHandler::SetPasswordList( 265 void PasswordManagerHandler::SetPasswordList(
230 const std::vector<std::unique_ptr<autofill::PasswordForm>>& password_list) { 266 const std::vector<std::unique_ptr<autofill::PasswordForm>>& password_list) {
231 base::ListValue entries; 267 base::ListValue entries;
232 base::string16 placeholder(base::ASCIIToUTF16(" ")); 268 base::string16 placeholder(base::ASCIIToUTF16(" "));
233 for (const auto& saved_password : password_list) { 269 for (const auto& saved_password : password_list) {
234 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue); 270 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
235 CopyOriginInfoOfPasswordForm(*saved_password, entry.get()); 271 CopyOriginInfoOfPasswordForm(*saved_password, entry.get());
236 272
(...skipping 24 matching lines...) Expand all
261 for (const auto& exception : password_exception_list) { 297 for (const auto& exception : password_exception_list) {
262 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue); 298 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
263 CopyOriginInfoOfPasswordForm(*exception, entry.get()); 299 CopyOriginInfoOfPasswordForm(*exception, entry.get());
264 entries.Append(entry.release()); 300 entries.Append(entry.release());
265 } 301 }
266 302
267 web_ui()->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList", 303 web_ui()->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList",
268 entries); 304 entries);
269 } 305 }
270 306
307 void PasswordManagerHandler::FileSelected(const base::FilePath& path,
308 int index,
309 void* params) {
310 switch (static_cast<FileSelectorCaller>(reinterpret_cast<intptr_t>(params))) {
311 case IMPORT_FILE_SELECTED:
312 ImportPasswordFileSelected(path);
313 break;
314 case EXPORT_FILE_SELECTED:
315 ExportPasswordFileSelected(path);
316 break;
317 }
318 }
319
320 void PasswordManagerHandler::HandlePasswordImport(const base::ListValue* args) {
321 #if !defined(OS_ANDROID) // This is never called on Android.
322 ui::SelectFileDialog::FileTypeInfo file_type_info;
323
324 file_type_info.extensions =
325 password_manager::PasswordImporter::GetSupportedFileExtensions();
326 DCHECK(!file_type_info.extensions.empty() &&
327 !file_type_info.extensions[0].empty());
328 file_type_info.include_all_files = true;
329 ChromeSelectFilePolicy* select_file_policy =
330 new ChromeSelectFilePolicy(web_ui()->GetWebContents());
331 ANNOTATE_LEAKING_OBJECT_PTR(select_file_policy);
Jeffrey Yasskin 2016/04/19 00:57:04 Please have the test's SelectFileDialogFactory tak
vabr (Chromium) 2016/04/19 12:43:10 Fix at https://codereview.chromium.org/1898143002.
332 select_file_dialog_ = ui::SelectFileDialog::Create(this, select_file_policy);
333 select_file_dialog_->SelectFile(
334 ui::SelectFileDialog::SELECT_OPEN_FILE,
335 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_IMPORT_DIALOG_TITLE),
336 base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0],
337 web_ui()->GetWebContents()->GetTopLevelNativeWindow(),
338 reinterpret_cast<void*>(IMPORT_FILE_SELECTED));
339 #endif
340 }
341
342 void PasswordManagerHandler::ImportPasswordFileSelected(
343 const base::FilePath& path) {
344 scoped_refptr<ImportPasswordResultConsumer> form_consumer(
345 new ImportPasswordResultConsumer(GetProfile()));
346
347 password_manager::PasswordImporter::Import(
348 path, content::BrowserThread::GetMessageLoopProxyForThread(
349 content::BrowserThread::FILE)
350 .get(),
351 base::Bind(&ImportPasswordResultConsumer::ConsumePassword,
352 form_consumer));
353 }
354
355 PasswordManagerHandler::ImportPasswordResultConsumer::
356 ImportPasswordResultConsumer(Profile* profile)
357 : profile_(profile) {}
358
359 void PasswordManagerHandler::ImportPasswordResultConsumer::ConsumePassword(
360 password_manager::PasswordImporter::Result result,
361 const std::vector<autofill::PasswordForm>& forms) {
362 UMA_HISTOGRAM_ENUMERATION(
363 "PasswordManager.ImportPasswordFromCSVResult", result,
364 password_manager::PasswordImporter::NUM_IMPORT_RESULTS);
365 if (result != password_manager::PasswordImporter::SUCCESS)
366 return;
367
368 UMA_HISTOGRAM_COUNTS("PasswordManager.ImportedPasswordsPerUserInCSV",
369 forms.size());
370
371 scoped_refptr<password_manager::PasswordStore> store(
372 PasswordStoreFactory::GetForProfile(profile_,
373 ServiceAccessType::EXPLICIT_ACCESS));
374 if (store) {
375 for (const autofill::PasswordForm& form : forms) {
376 store->AddLogin(form);
377 }
378 }
379 UMA_HISTOGRAM_BOOLEAN("PasswordManager.StorePasswordImportedFromCSVResult",
380 store);
381 }
382
383 void PasswordManagerHandler::HandlePasswordExport(const base::ListValue* args) {
384 #if !defined(OS_ANDROID) // This is never called on Android.
385 if (!password_manager_presenter_->IsUserAuthenticated())
386 return;
387
388 ui::SelectFileDialog::FileTypeInfo file_type_info;
389 file_type_info.extensions =
390 password_manager::PasswordExporter::GetSupportedFileExtensions();
391 DCHECK(!file_type_info.extensions.empty() &&
392 !file_type_info.extensions[0].empty());
393 file_type_info.include_all_files = true;
394 ChromeSelectFilePolicy* select_file_policy =
395 new ChromeSelectFilePolicy(web_ui()->GetWebContents());
396 ANNOTATE_LEAKING_OBJECT_PTR(select_file_policy);
397 select_file_dialog_ = ui::SelectFileDialog::Create(this, select_file_policy);
398 select_file_dialog_->SelectFile(
399 ui::SelectFileDialog::SELECT_SAVEAS_FILE,
400 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EXPORT_DIALOG_TITLE),
401 base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0],
402 GetNativeWindow(), reinterpret_cast<void*>(EXPORT_FILE_SELECTED));
403 #endif
404 }
405
406 void PasswordManagerHandler::ExportPasswordFileSelected(
407 const base::FilePath& path) {
408 std::vector<scoped_ptr<autofill::PasswordForm>> password_list =
409 password_manager_presenter_->GetAllPasswords();
410 UMA_HISTOGRAM_COUNTS("PasswordManager.ExportedPasswordsPerUserInCSV",
411 password_list.size());
412 password_manager::PasswordExporter::Export(
413 path, std::move(password_list),
414 content::BrowserThread::GetMessageLoopProxyForThread(
415 content::BrowserThread::FILE)
416 .get());
417 }
418
271 } // namespace options 419 } // namespace options
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698