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

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 28 matching lines...) Expand all
68 DCHECK(link_url.is_valid()); 79 DCHECK(link_url.is_valid());
69 entry->SetString( 80 entry->SetString(
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
89 // Enumeration of different callers of SelectFile.
90 enum FileSelectorCaller {
91 IMPORT_FILE_SELECTED,
92 EXPORT_FILE_SELECTED,
93 };
94
78 } // namespace 95 } // namespace
79 96
80 PasswordManagerHandler::PasswordManagerHandler() 97 PasswordManagerHandler::PasswordManagerHandler() {
81 : password_manager_presenter_(this) {} 98 password_manager_presenter_.reset(new PasswordManagerPresenter(this));
99 }
100
101 PasswordManagerHandler::PasswordManagerHandler(
102 scoped_ptr<PasswordManagerPresenter> presenter)
103 : password_manager_presenter_(std::move(presenter)) {}
82 104
83 PasswordManagerHandler::~PasswordManagerHandler() {} 105 PasswordManagerHandler::~PasswordManagerHandler() {}
84 106
85 Profile* PasswordManagerHandler::GetProfile() { 107 Profile* PasswordManagerHandler::GetProfile() {
86 return Profile::FromWebUI(web_ui()); 108 return Profile::FromWebUI(web_ui());
87 } 109 }
88 110
89 #if !defined(OS_ANDROID) 111 #if !defined(OS_ANDROID)
90 gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() const { 112 gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() const {
91 return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); 113 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
(...skipping 10 matching lines...) Expand all
102 {"autoSigninDescription", IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION}, 124 {"autoSigninDescription", IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION},
103 {"savedPasswordsTitle", IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE}, 125 {"savedPasswordsTitle", IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE},
104 {"passwordExceptionsTitle", IDS_PASSWORD_MANAGER_EXCEPTIONS_TAB_TITLE}, 126 {"passwordExceptionsTitle", IDS_PASSWORD_MANAGER_EXCEPTIONS_TAB_TITLE},
105 {"passwordSearchPlaceholder", IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS}, 127 {"passwordSearchPlaceholder", IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS},
106 {"passwordShowButton", IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON}, 128 {"passwordShowButton", IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON},
107 {"passwordHideButton", IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON}, 129 {"passwordHideButton", IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON},
108 {"passwordsNoPasswordsDescription", 130 {"passwordsNoPasswordsDescription",
109 IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION}, 131 IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION},
110 {"passwordsNoExceptionsDescription", 132 {"passwordsNoExceptionsDescription",
111 IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION}, 133 IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION},
134 {"passwordManagerImportPasswordButtonText",
135 IDS_PASSWORD_MANAGER_IMPORT_BUTTON},
136 {"passwordManagerExportPasswordButtonText",
137 IDS_PASSWORD_MANAGER_EXPORT_BUTTON},
112 }; 138 };
113 139
114 RegisterStrings(localized_strings, resources, arraysize(resources)); 140 RegisterStrings(localized_strings, resources, arraysize(resources));
115 141
116 const ProfileSyncService* sync_service = 142 const ProfileSyncService* sync_service =
117 ProfileSyncServiceFactory::GetForProfile(GetProfile()); 143 ProfileSyncServiceFactory::GetForProfile(GetProfile());
118 int title_id = 144 int title_id =
119 password_bubble_experiment::IsSmartLockBrandingEnabled(sync_service) 145 password_bubble_experiment::IsSmartLockBrandingEnabled(sync_service)
120 ? IDS_PASSWORD_MANAGER_SMART_LOCK_FOR_PASSWORDS 146 ? IDS_PASSWORD_MANAGER_SMART_LOCK_FOR_PASSWORDS
121 : IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE; 147 : IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 base::Bind(&PasswordManagerHandler::HandleRemoveSavedPassword, 194 base::Bind(&PasswordManagerHandler::HandleRemoveSavedPassword,
169 base::Unretained(this))); 195 base::Unretained(this)));
170 web_ui()->RegisterMessageCallback( 196 web_ui()->RegisterMessageCallback(
171 "removePasswordException", 197 "removePasswordException",
172 base::Bind(&PasswordManagerHandler::HandleRemovePasswordException, 198 base::Bind(&PasswordManagerHandler::HandleRemovePasswordException,
173 base::Unretained(this))); 199 base::Unretained(this)));
174 web_ui()->RegisterMessageCallback( 200 web_ui()->RegisterMessageCallback(
175 "requestShowPassword", 201 "requestShowPassword",
176 base::Bind(&PasswordManagerHandler::HandleRequestShowPassword, 202 base::Bind(&PasswordManagerHandler::HandleRequestShowPassword,
177 base::Unretained(this))); 203 base::Unretained(this)));
204 web_ui()->RegisterMessageCallback(
205 "importPassword",
206 base::Bind(&PasswordManagerHandler::HandlePasswordImport,
207 base::Unretained(this)));
208 web_ui()->RegisterMessageCallback(
209 "exportPassword",
210 base::Bind(&PasswordManagerHandler::HandlePasswordExport,
211 base::Unretained(this)));
178 } 212 }
179 213
180 void PasswordManagerHandler::InitializeHandler() { 214 void PasswordManagerHandler::InitializeHandler() {
181 password_manager_presenter_.Initialize(); 215 password_manager_presenter_->Initialize();
216 }
217
218 void PasswordManagerHandler::InitializePage() {
219 if (base::FeatureList::IsEnabled(
220 password_manager::features::kPasswordImportExport)) {
221 web_ui()->CallJavascriptFunction("PasswordManager.showImportExportButton");
222 }
182 } 223 }
183 224
184 void PasswordManagerHandler::HandleRemoveSavedPassword( 225 void PasswordManagerHandler::HandleRemoveSavedPassword(
185 const base::ListValue* args) { 226 const base::ListValue* args) {
186 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); 227 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args));
187 int index; 228 int index;
188 if (base::StringToInt(string_value, &index) && index >= 0) { 229 if (base::StringToInt(string_value, &index) && index >= 0) {
189 password_manager_presenter_.RemoveSavedPassword(static_cast<size_t>(index)); 230 password_manager_presenter_->RemoveSavedPassword(
231 static_cast<size_t>(index));
190 } 232 }
191 } 233 }
192 234
193 void PasswordManagerHandler::HandleRemovePasswordException( 235 void PasswordManagerHandler::HandleRemovePasswordException(
194 const base::ListValue* args) { 236 const base::ListValue* args) {
195 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); 237 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args));
196 int index; 238 int index;
197 if (base::StringToInt(string_value, &index) && index >= 0) { 239 if (base::StringToInt(string_value, &index) && index >= 0) {
198 password_manager_presenter_.RemovePasswordException( 240 password_manager_presenter_->RemovePasswordException(
199 static_cast<size_t>(index)); 241 static_cast<size_t>(index));
200 } 242 }
201 } 243 }
202 244
203 void PasswordManagerHandler::HandleRequestShowPassword( 245 void PasswordManagerHandler::HandleRequestShowPassword(
204 const base::ListValue* args) { 246 const base::ListValue* args) {
205 int index; 247 int index;
206 if (!ExtractIntegerValue(args, &index)) 248 if (!ExtractIntegerValue(args, &index))
207 NOTREACHED(); 249 NOTREACHED();
208 250
209 password_manager_presenter_.RequestShowPassword(static_cast<size_t>(index)); 251 password_manager_presenter_->RequestShowPassword(static_cast<size_t>(index));
210 } 252 }
211 253
212 void PasswordManagerHandler::ShowPassword( 254 void PasswordManagerHandler::ShowPassword(
213 size_t index, 255 size_t index,
214 const std::string& origin_url, 256 const std::string& origin_url,
215 const std::string& username, 257 const std::string& username,
216 const base::string16& password_value) { 258 const base::string16& password_value) {
217 // Call back the front end to reveal the password. 259 // Call back the front end to reveal the password.
218 web_ui()->CallJavascriptFunction( 260 web_ui()->CallJavascriptFunction(
219 "PasswordManager.showPassword", 261 "PasswordManager.showPassword",
220 base::FundamentalValue(static_cast<int>(index)), 262 base::FundamentalValue(static_cast<int>(index)),
221 base::StringValue(password_value)); 263 base::StringValue(password_value));
222 } 264 }
223 265
224 void PasswordManagerHandler::HandleUpdatePasswordLists( 266 void PasswordManagerHandler::HandleUpdatePasswordLists(
225 const base::ListValue* args) { 267 const base::ListValue* args) {
226 password_manager_presenter_.UpdatePasswordLists(); 268 password_manager_presenter_->UpdatePasswordLists();
227 } 269 }
228 270
229 void PasswordManagerHandler::SetPasswordList( 271 void PasswordManagerHandler::SetPasswordList(
230 const std::vector<std::unique_ptr<autofill::PasswordForm>>& password_list) { 272 const std::vector<std::unique_ptr<autofill::PasswordForm>>& password_list) {
231 base::ListValue entries; 273 base::ListValue entries;
232 base::string16 placeholder(base::ASCIIToUTF16(" ")); 274 base::string16 placeholder(base::ASCIIToUTF16(" "));
233 for (const auto& saved_password : password_list) { 275 for (const auto& saved_password : password_list) {
234 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue); 276 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
235 CopyOriginInfoOfPasswordForm(*saved_password, entry.get()); 277 CopyOriginInfoOfPasswordForm(*saved_password, entry.get());
236 278
(...skipping 24 matching lines...) Expand all
261 for (const auto& exception : password_exception_list) { 303 for (const auto& exception : password_exception_list) {
262 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue); 304 std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
263 CopyOriginInfoOfPasswordForm(*exception, entry.get()); 305 CopyOriginInfoOfPasswordForm(*exception, entry.get());
264 entries.Append(entry.release()); 306 entries.Append(entry.release());
265 } 307 }
266 308
267 web_ui()->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList", 309 web_ui()->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList",
268 entries); 310 entries);
269 } 311 }
270 312
313 void PasswordManagerHandler::FileSelected(const base::FilePath& path,
314 int index,
315 void* params) {
316 switch (static_cast<FileSelectorCaller>(reinterpret_cast<intptr_t>(params))) {
317 case IMPORT_FILE_SELECTED:
318 ImportPasswordFileSelected(path);
319 break;
320 case EXPORT_FILE_SELECTED:
321 ExportPasswordFileSelected(path);
322 break;
323 }
324 }
325
326 void PasswordManagerHandler::HandlePasswordImport(const base::ListValue* args) {
327 #if !defined(OS_ANDROID) // This is never called on Android.
328 ui::SelectFileDialog::FileTypeInfo file_type_info;
329
330 file_type_info.extensions =
331 password_manager::PasswordImporter::GetSupportedFileExtensions();
332 DCHECK(!file_type_info.extensions.empty() &&
333 !file_type_info.extensions[0].empty());
334 file_type_info.include_all_files = true;
335 ChromeSelectFilePolicy* select_file_policy =
336 new ChromeSelectFilePolicy(web_ui()->GetWebContents());
337 ANNOTATE_LEAKING_OBJECT_PTR(select_file_policy);
338 select_file_dialog_ = ui::SelectFileDialog::Create(this, select_file_policy);
339 select_file_dialog_->SelectFile(
340 ui::SelectFileDialog::SELECT_OPEN_FILE,
341 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_IMPORT_DIALOG_TITLE),
342 base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0],
343 web_ui()->GetWebContents()->GetTopLevelNativeWindow(),
344 reinterpret_cast<void*>(IMPORT_FILE_SELECTED));
345 #endif
346 }
347
348 void PasswordManagerHandler::ImportPasswordFileSelected(
349 const base::FilePath& path) {
350 scoped_refptr<ImportPasswordResultConsumer> form_consumer(
351 new ImportPasswordResultConsumer(GetProfile()));
352
353 password_manager::PasswordImporter::Import(
354 path, content::BrowserThread::GetMessageLoopProxyForThread(
355 content::BrowserThread::FILE)
356 .get(),
357 base::Bind(&ImportPasswordResultConsumer::ConsumePassword,
358 form_consumer));
359 }
360
361 PasswordManagerHandler::ImportPasswordResultConsumer::
362 ImportPasswordResultConsumer(Profile* profile)
363 : profile_(profile) {}
364
365 void PasswordManagerHandler::ImportPasswordResultConsumer::ConsumePassword(
366 password_manager::PasswordImporter::Result result,
367 const std::vector<autofill::PasswordForm>& forms) {
368 UMA_HISTOGRAM_ENUMERATION(
369 "PasswordManager.ImportPasswordFromCSVResult", result,
370 password_manager::PasswordImporter::NUM_IMPORT_RESULTS);
371 if (result != password_manager::PasswordImporter::SUCCESS)
372 return;
373
374 UMA_HISTOGRAM_COUNTS("PasswordManager.ImportedPasswordsPerUserInCSV",
375 forms.size());
376
377 scoped_refptr<password_manager::PasswordStore> store(
378 PasswordStoreFactory::GetForProfile(profile_,
379 ServiceAccessType::EXPLICIT_ACCESS));
380 if (store) {
381 for (const autofill::PasswordForm& form : forms) {
382 store->AddLogin(form);
383 }
384 }
385 UMA_HISTOGRAM_BOOLEAN("PasswordManager.StorePasswordImportedFromCSVResult",
386 store);
387 }
388
389 void PasswordManagerHandler::HandlePasswordExport(const base::ListValue* args) {
390 #if !defined(OS_ANDROID) // This is never called on Android.
391 if (!password_manager_presenter_->IsUserAuthenticated())
392 return;
393
394 ui::SelectFileDialog::FileTypeInfo file_type_info;
395 file_type_info.extensions =
396 password_manager::PasswordExporter::GetSupportedFileExtensions();
397 DCHECK(!file_type_info.extensions.empty() &&
398 !file_type_info.extensions[0].empty());
399 file_type_info.include_all_files = true;
400 ChromeSelectFilePolicy* select_file_policy =
401 new ChromeSelectFilePolicy(web_ui()->GetWebContents());
402 ANNOTATE_LEAKING_OBJECT_PTR(select_file_policy);
403 select_file_dialog_ = ui::SelectFileDialog::Create(this, select_file_policy);
404 select_file_dialog_->SelectFile(
405 ui::SelectFileDialog::SELECT_SAVEAS_FILE,
406 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EXPORT_DIALOG_TITLE),
407 base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0],
408 GetNativeWindow(), reinterpret_cast<void*>(EXPORT_FILE_SELECTED));
409 #endif
410 }
411
412 void PasswordManagerHandler::ExportPasswordFileSelected(
413 const base::FilePath& path) {
414 std::vector<scoped_ptr<autofill::PasswordForm>> password_list =
415 password_manager_presenter_->GetAllPasswords();
416 UMA_HISTOGRAM_COUNTS("PasswordManager.ExportedPasswordsPerUserInCSV",
417 password_list.size());
418 password_manager::PasswordExporter::Export(
419 path, std::move(password_list),
420 content::BrowserThread::GetMessageLoopProxyForThread(
421 content::BrowserThread::FILE)
422 .get());
423 }
424
271 } // namespace options 425 } // namespace options
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698