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

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: fix problem revealed through git-cl-try Created 5 years, 6 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" 8 #include "base/command_line.h"
9 #include "base/files/file_path.h"
10 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
10 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
12 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h" 15 #include "base/values.h"
14 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/password_manager/sync_metrics.h"
15 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/sync/profile_sync_service.h" 19 #include "chrome/browser/sync/profile_sync_service.h"
17 #include "chrome/browser/sync/profile_sync_service_factory.h" 20 #include "chrome/browser/sync/profile_sync_service_factory.h"
18 #if defined(OS_WIN) && defined(USE_ASH) 21 #if defined(OS_WIN) && defined(USE_ASH)
19 #include "chrome/browser/ui/ash/ash_util.h" 22 #include "chrome/browser/ui/ash/ash_util.h"
20 #endif 23 #endif
24 #include "chrome/browser/ui/chrome_select_file_policy.h"
21 #include "chrome/common/pref_names.h" 25 #include "chrome/common/pref_names.h"
22 #include "chrome/common/url_constants.h" 26 #include "chrome/common/url_constants.h"
23 #include "chrome/grit/generated_resources.h" 27 #include "chrome/grit/generated_resources.h"
24 #include "components/autofill/core/common/password_form.h" 28 #include "components/autofill/core/common/password_form.h"
25 #include "components/password_manager/core/browser/affiliation_utils.h" 29 #include "components/password_manager/core/browser/affiliation_utils.h"
30 #include "components/password_manager/core/browser/export/password_exporter.h"
26 #include "components/password_manager/core/browser/password_bubble_experiment.h" 31 #include "components/password_manager/core/browser/password_bubble_experiment.h"
27 #include "components/password_manager/core/common/experiments.h" 32 #include "components/password_manager/core/common/experiments.h"
33 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/notification_details.h" 34 #include "content/public/browser/notification_details.h"
29 #include "content/public/browser/notification_source.h" 35 #include "content/public/browser/notification_source.h"
30 #include "content/public/browser/user_metrics.h" 36 #include "content/public/browser/user_metrics.h"
31 #include "content/public/browser/web_contents.h" 37 #include "content/public/browser/web_contents.h"
32 #include "content/public/browser/web_ui.h" 38 #include "content/public/browser/web_ui.h"
33 #include "content/public/common/content_switches.h" 39 #include "content/public/common/content_switches.h"
34 #include "net/base/net_util.h" 40 #include "net/base/net_util.h"
35 #include "ui/base/l10n/l10n_util.h" 41 #include "ui/base/l10n/l10n_util.h"
36 42
37 namespace options { 43 namespace options {
38 44
39 PasswordManagerHandler::PasswordManagerHandler() 45 namespace {
40 : password_manager_presenter_(this) {} 46
47 // Enumeration of different callers of SelectFile. Starting count at 1 so
48 // accidental call of SelectFile with params=NULL will error out.
49 enum {
50 IMPORT_FILE_SELECTED = 1,
51 EXPORT_FILE_SELECTED,
52 };
53
54 } // namespace
55
56 PasswordManagerHandler::PasswordManagerHandler() {
57 password_manager_presenter_.reset(new PasswordManagerPresenter(this));
58 }
59
60 PasswordManagerHandler::PasswordManagerHandler(
61 PasswordManagerPresenter* presenter) {
62 password_manager_presenter_.reset(presenter);
63 }
41 64
42 PasswordManagerHandler::~PasswordManagerHandler() {} 65 PasswordManagerHandler::~PasswordManagerHandler() {}
43 66
44 Profile* PasswordManagerHandler::GetProfile() { 67 Profile* PasswordManagerHandler::GetProfile() {
45 return Profile::FromWebUI(web_ui()); 68 return Profile::FromWebUI(web_ui());
46 } 69 }
47 70
48 #if !defined(OS_ANDROID) 71 #if !defined(OS_ANDROID)
49 gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() const { 72 gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() const {
50 return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); 73 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
51 } 74 }
52 #endif 75 #endif
53 76
54 void PasswordManagerHandler::GetLocalizedValues( 77 void PasswordManagerHandler::GetLocalizedValues(
55 base::DictionaryValue* localized_strings) { 78 base::DictionaryValue* localized_strings) {
56 DCHECK(localized_strings); 79 DCHECK(localized_strings);
57 80
58 static const OptionsStringResource resources[] = { 81 static const OptionsStringResource resources[] = {
59 { "autoSigninTitle", 82 {"autoSigninTitle", IDS_PASSWORDS_AUTO_SIGNIN_TITLE},
60 IDS_PASSWORDS_AUTO_SIGNIN_TITLE }, 83 {"autoSigninDescription", IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION},
61 { "autoSigninDescription", 84 {"savedPasswordsTitle", IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE},
62 IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION }, 85 {"passwordExceptionsTitle", IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE},
63 { "savedPasswordsTitle", 86 {"passwordSearchPlaceholder", IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS},
64 IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE }, 87 {"passwordShowButton", IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON},
65 { "passwordExceptionsTitle", 88 {"passwordHideButton", IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON},
66 IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE }, 89 {"passwordsNoPasswordsDescription",
67 { "passwordSearchPlaceholder", 90 IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION},
68 IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS }, 91 {"passwordsNoExceptionsDescription",
69 { "passwordShowButton", 92 IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION},
70 IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON }, 93 {"passwordManagerImportPasswordButtonText",
71 { "passwordHideButton", 94 IDS_PASSWORD_MANAGER_IMPORT_BUTTON},
72 IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON }, 95 {"passwordManagerExportPasswordButtonText",
73 { "passwordsNoPasswordsDescription", 96 IDS_PASSWORD_MANAGER_EXPORT_BUTTON},
74 IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION }, 97 {"importPasswordCompletedMessage",
75 { "passwordsNoExceptionsDescription", 98 IDS_PASSWORD_MANAGER_IMPORT_COMPLETED_MESSAGE},
76 IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION },
77 }; 99 };
78 100
79 RegisterStrings(localized_strings, resources, arraysize(resources)); 101 RegisterStrings(localized_strings, resources, arraysize(resources));
80 102
81 const ProfileSyncService* sync_service = 103 const ProfileSyncService* sync_service =
82 ProfileSyncServiceFactory::GetForProfile(GetProfile()); 104 ProfileSyncServiceFactory::GetForProfile(GetProfile());
83 int title_id = 105 int title_id =
84 password_bubble_experiment::IsSmartLockBrandingEnabled(sync_service) ? 106 password_bubble_experiment::IsSmartLockBrandingEnabled(sync_service) ?
85 IDS_PASSWORDS_EXCEPTIONS_SMART_LOCK_WINDOW_TITLE : 107 IDS_PASSWORDS_EXCEPTIONS_SMART_LOCK_WINDOW_TITLE :
86 IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE; 108 IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 base::Bind(&PasswordManagerHandler::HandleRemoveSavedPassword, 156 base::Bind(&PasswordManagerHandler::HandleRemoveSavedPassword,
135 base::Unretained(this))); 157 base::Unretained(this)));
136 web_ui()->RegisterMessageCallback( 158 web_ui()->RegisterMessageCallback(
137 "removePasswordException", 159 "removePasswordException",
138 base::Bind(&PasswordManagerHandler::HandleRemovePasswordException, 160 base::Bind(&PasswordManagerHandler::HandleRemovePasswordException,
139 base::Unretained(this))); 161 base::Unretained(this)));
140 web_ui()->RegisterMessageCallback( 162 web_ui()->RegisterMessageCallback(
141 "requestShowPassword", 163 "requestShowPassword",
142 base::Bind(&PasswordManagerHandler::HandleRequestShowPassword, 164 base::Bind(&PasswordManagerHandler::HandleRequestShowPassword,
143 base::Unretained(this))); 165 base::Unretained(this)));
166 web_ui()->RegisterMessageCallback(
167 "importPassword",
168 base::Bind(&PasswordManagerHandler::HandlePasswordImport,
169 base::Unretained(this)));
170 web_ui()->RegisterMessageCallback(
171 "exportPassword",
172 base::Bind(&PasswordManagerHandler::HandlePasswordExport,
173 base::Unretained(this)));
144 } 174 }
145 175
146 void PasswordManagerHandler::InitializeHandler() { 176 void PasswordManagerHandler::InitializeHandler() {
147 password_manager_presenter_.Initialize(); 177 password_manager_presenter_->Initialize();
148 } 178 }
149 179
150 void PasswordManagerHandler::InitializePage() { 180 void PasswordManagerHandler::InitializePage() {
151 base::FundamentalValue visible( 181 base::FundamentalValue visible(
152 password_manager::ManageAccountLinkExperimentEnabled()); 182 password_manager::ManageAccountLinkExperimentEnabled());
153 web_ui()->CallJavascriptFunction( 183 web_ui()->CallJavascriptFunction(
154 "PasswordManager.setManageAccountLinkVisibility", visible); 184 "PasswordManager.setManageAccountLinkVisibility", visible);
155 } 185 }
156 186
157 void PasswordManagerHandler::HandleRemoveSavedPassword( 187 void PasswordManagerHandler::HandleRemoveSavedPassword(
158 const base::ListValue* args) { 188 const base::ListValue* args) {
159 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); 189 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args));
160 int index; 190 int index;
161 if (base::StringToInt(string_value, &index) && index >= 0) { 191 if (base::StringToInt(string_value, &index) && index >= 0) {
162 password_manager_presenter_.RemoveSavedPassword(static_cast<size_t>(index)); 192 password_manager_presenter_->RemoveSavedPassword(
193 static_cast<size_t>(index));
163 } 194 }
164 } 195 }
165 196
166 void PasswordManagerHandler::HandleRemovePasswordException( 197 void PasswordManagerHandler::HandleRemovePasswordException(
167 const base::ListValue* args) { 198 const base::ListValue* args) {
168 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args)); 199 std::string string_value = base::UTF16ToUTF8(ExtractStringValue(args));
169 int index; 200 int index;
170 if (base::StringToInt(string_value, &index) && index >= 0) { 201 if (base::StringToInt(string_value, &index) && index >= 0) {
171 password_manager_presenter_.RemovePasswordException( 202 password_manager_presenter_->RemovePasswordException(
172 static_cast<size_t>(index)); 203 static_cast<size_t>(index));
173 } 204 }
174 } 205 }
175 206
176 void PasswordManagerHandler::HandleRequestShowPassword( 207 void PasswordManagerHandler::HandleRequestShowPassword(
177 const base::ListValue* args) { 208 const base::ListValue* args) {
178 int index; 209 int index;
179 if (!ExtractIntegerValue(args, &index)) 210 if (!ExtractIntegerValue(args, &index))
180 NOTREACHED(); 211 NOTREACHED();
181 212
182 password_manager_presenter_.RequestShowPassword(static_cast<size_t>(index)); 213 password_manager_presenter_->RequestShowPassword(static_cast<size_t>(index));
183 } 214 }
184 215
185 void PasswordManagerHandler::ShowPassword( 216 void PasswordManagerHandler::ShowPassword(
186 size_t index, 217 size_t index,
187 const std::string& origin_url, 218 const std::string& origin_url,
188 const std::string& username, 219 const std::string& username,
189 const base::string16& password_value) { 220 const base::string16& password_value) {
190 // Call back the front end to reveal the password. 221 // Call back the front end to reveal the password.
191 web_ui()->CallJavascriptFunction( 222 web_ui()->CallJavascriptFunction(
192 "PasswordManager.showPassword", 223 "PasswordManager.showPassword",
193 base::FundamentalValue(static_cast<int>(index)), 224 base::FundamentalValue(static_cast<int>(index)),
194 base::StringValue(password_value)); 225 base::StringValue(password_value));
195 } 226 }
196 227
197 void PasswordManagerHandler::HandleUpdatePasswordLists( 228 void PasswordManagerHandler::HandleUpdatePasswordLists(
198 const base::ListValue* args) { 229 const base::ListValue* args) {
199 password_manager_presenter_.UpdatePasswordLists(); 230 password_manager_presenter_->UpdatePasswordLists();
200 } 231 }
201 232
202 void PasswordManagerHandler::SetPasswordList( 233 void PasswordManagerHandler::SetPasswordList(
203 const ScopedVector<autofill::PasswordForm>& password_list, 234 const ScopedVector<autofill::PasswordForm>& password_list,
204 bool show_passwords) { 235 bool show_passwords) {
205 base::ListValue entries; 236 base::ListValue entries;
206 languages_ = GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages); 237 languages_ = GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
207 base::string16 placeholder(base::ASCIIToUTF16(" ")); 238 base::string16 placeholder(base::ASCIIToUTF16(" "));
208 for (size_t i = 0; i < password_list.size(); ++i) { 239 for (size_t i = 0; i < password_list.size(); ++i) {
209 base::ListValue* entry = new base::ListValue(); 240 base::ListValue* entry = new base::ListValue();
(...skipping 25 matching lines...) Expand all
235 base::ListValue entries; 266 base::ListValue entries;
236 for (size_t i = 0; i < password_exception_list.size(); ++i) { 267 for (size_t i = 0; i < password_exception_list.size(); ++i) {
237 entries.AppendString(password_manager::GetHumanReadableOrigin( 268 entries.AppendString(password_manager::GetHumanReadableOrigin(
238 *password_exception_list[i], languages_)); 269 *password_exception_list[i], languages_));
239 } 270 }
240 271
241 web_ui()->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList", 272 web_ui()->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList",
242 entries); 273 entries);
243 } 274 }
244 275
276 void PasswordManagerHandler::FileSelected(const base::FilePath& path,
277 int index,
278 void* params) {
279 switch (reinterpret_cast<intptr_t>(params)) {
280 case IMPORT_FILE_SELECTED:
281 ImportPasswordFileSelected(path);
282 break;
283 case EXPORT_FILE_SELECTED:
284 ExportPasswordFileSelected(path);
285 break;
286 default:
287 NOTREACHED();
288 }
289 }
290
291 void PasswordManagerHandler::HandlePasswordImport(const base::ListValue* args) {
292 #if !defined(OS_ANDROID) // This is never called on Android.
293 ui::SelectFileDialog::FileTypeInfo file_type_info;
294 file_type_info.extensions =
295 password_manager::PasswordImporter::GetSupportedFileExtensions();
296 DCHECK(!file_type_info.extensions.empty() &&
297 !file_type_info.extensions[0].empty());
298 file_type_info.include_all_files = true;
299 selected_file_dialog_ = ui::SelectFileDialog::Create(
300 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
301 selected_file_dialog_->SelectFile(
302 ui::SelectFileDialog::SELECT_OPEN_FILE,
303 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_IMPORT_DIALOG_TITLE),
304 base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0],
305 web_ui()->GetWebContents()->GetTopLevelNativeWindow(),
306 reinterpret_cast<void*>(IMPORT_FILE_SELECTED));
307 #endif
308 }
309
310 void PasswordManagerHandler::ImportPasswordFileSelected(
311 const base::FilePath& path) {
312 password_manager::PasswordImporter::Import(
313 path, content::BrowserThread::GetMessageLoopProxyForThread(
314 content::BrowserThread::FILE).get(),
315 base::Bind(&PasswordManagerHandler::ImportPasswordFileRead,
316 base::Unretained(this)));
317 }
318
319 void PasswordManagerHandler::ImportPasswordFileRead(
320 password_manager::PasswordImporter::Result result,
321 const std::vector<autofill::PasswordForm>& forms) {
322 UMA_HISTOGRAM_ENUMERATION("PasswordManager.ImportPasswordFromCSVResult",
323 result,
324 password_manager::PasswordImporter::SEMANTIC_ERROR);
325 if (result != password_manager::PasswordImporter::SUCCESS) {
326 return;
327 }
328
329 UMA_HISTOGRAM_COUNTS("PasswordManager.ImportedPasswordsPerUserInCSV",
330 forms.size());
331
332 if (password_manager_presenter_->AddPasswordsToStore(forms)) {
333 // Display Feedback UI
334 base::FundamentalValue visible(true);
335 web_ui()->CallJavascriptFunction(
336 "PasswordManager.setImportCompleteUIVisibility", visible);
337 } else {
338 UMA_HISTOGRAM_COUNTS("PasswordManager.FailToStorePasswordImportedFromCSV",
339 1);
340 }
341 }
342
343 void PasswordManagerHandler::HandlePasswordExport(const base::ListValue* args) {
344 #if !defined(OS_ANDROID) // This is never called on Android.
345 if (password_manager_presenter_->RequestToExportPassword()) {
346 ui::SelectFileDialog::FileTypeInfo file_type_info;
347 file_type_info.extensions =
348 password_manager::PasswordExporter::GetSupportedFileExtensions();
349 DCHECK(!file_type_info.extensions.empty() &&
350 !file_type_info.extensions[0].empty());
351 file_type_info.include_all_files = true;
352 selected_file_dialog_ = ui::SelectFileDialog::Create(
353 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
354 selected_file_dialog_->SelectFile(
355 ui::SelectFileDialog::SELECT_SAVEAS_FILE,
356 l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EXPORT_DIALOG_TITLE),
357 base::FilePath(), &file_type_info, 1, file_type_info.extensions[0][0],
358 GetNativeWindow(), reinterpret_cast<void*>(EXPORT_FILE_SELECTED));
359 }
360 #endif
361 }
362
363 void PasswordManagerHandler::ExportPasswordFileSelected(
364 const base::FilePath& path) {
365 ScopedVector<autofill::PasswordForm> password_list =
366 password_manager_presenter_->GetAllPasswords().Pass();
367 UMA_HISTOGRAM_COUNTS("PasswordManager.ExportedPasswordsPerUserInCSV",
368 password_list.size());
369 password_manager::PasswordExporter::Export(
370 path.ReplaceExtension(FILE_PATH_LITERAL("csv")), password_list.Pass(),
Garrett Casto 2015/06/26 21:13:48 For encapsulation purposes, I don't think that I w
xunlu 2015/06/30 23:06:09 Done.
371 content::BrowserThread::GetMessageLoopProxyForThread(
372 content::BrowserThread::FILE).get(),
373 base::Bind(&PasswordManagerHandler::ExportPasswordFileWritten,
374 base::Unretained(this)));
375 }
376
377 void PasswordManagerHandler::ExportPasswordFileWritten() {
378 // We do not plan to give any UI feedback for export
379 // at this moment as it will almost always succeed. If the plan changes, this
380 // is the place to put the feedback logic.
381 }
382
245 } // namespace options 383 } // namespace options
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698