forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add PasswordManagerPorter class for password import/export
This class provides functionality to import and export passwords from and to the Password Manager as part of a change to enable password importing/exporting from the new Material Design Password Manager settings. Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation Change-Id: Idbf3cad46b9ef62c2bd4ff923d208833ef3b03ac Reviewed-on: https://chromium-review.googlesource.com/668448 Commit-Queue: Nathanael Alcock <varkor@google.com> Reviewed-by: Vasilii Sukhanov <vasilii@chromium.org> Reviewed-by: Ilya Sherman <isherman@chromium.org> Cr-Commit-Position: refs/heads/master@{#503223}
- Loading branch information
Nathanael Alcock
authored and
Commit Bot
committed
Sep 20, 2017
1 parent
108e612
commit 226d0ee
Showing
11 changed files
with
441 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
chrome/browser/ui/passwords/credential_provider_interface.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright 2017 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_UI_PASSWORDS_CREDENTIAL_PROVIDER_INTERFACE_H_ | ||
#define CHROME_BROWSER_UI_PASSWORDS_CREDENTIAL_PROVIDER_INTERFACE_H_ | ||
|
||
namespace autofill { | ||
struct PasswordForm; | ||
} | ||
|
||
// Provides an interface for getting credentials, such as passwords, from some | ||
// form of provider. | ||
class CredentialProviderInterface { | ||
public: | ||
// Gets all password entries. | ||
virtual std::vector<std::unique_ptr<autofill::PasswordForm>> | ||
GetAllPasswords() = 0; | ||
|
||
protected: | ||
virtual ~CredentialProviderInterface() {} | ||
}; | ||
|
||
#endif // CHROME_BROWSER_UI_PASSWORDS_CREDENTIAL_PROVIDER_INTERFACE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
// Copyright 2017 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/ui/passwords/password_manager_porter.h" | ||
|
||
#include "base/metrics/histogram_macros.h" | ||
#include "base/path_service.h" | ||
#include "build/build_config.h" | ||
#include "chrome/browser/password_manager/password_store_factory.h" | ||
#include "chrome/browser/profiles/profile.h" | ||
#include "chrome/browser/ui/chrome_select_file_policy.h" | ||
#include "chrome/browser/ui/passwords/credential_provider_interface.h" | ||
#include "chrome/common/chrome_paths.h" | ||
#include "chrome/grit/generated_resources.h" | ||
#include "components/password_manager/core/browser/export/password_exporter.h" | ||
#include "components/password_manager/core/browser/password_store.h" | ||
#include "content/public/browser/web_contents.h" | ||
#include "net/base/filename_util.h" | ||
#include "ui/base/l10n/l10n_util.h" | ||
#include "url/gurl.h" | ||
|
||
namespace { | ||
// The following are not used on Android due to the |SelectFileDialog| being | ||
// unused. | ||
#if !defined(OS_ANDROID) | ||
// The default name of the password file when exporting. | ||
constexpr base::FilePath::CharType kDefaultFileName[] = | ||
FILE_PATH_LITERAL("chrome_passwords"); | ||
|
||
// The default directory and filename when importing and exporting passwords. | ||
base::FilePath GetDefaultFilepathForPasswordFile( | ||
const base::FilePath::StringType& default_extension) { | ||
base::FilePath default_path; | ||
PathService::Get(chrome::DIR_USER_DOCUMENTS, &default_path); | ||
return default_path.Append(kDefaultFileName).AddExtension(default_extension); | ||
} | ||
#endif | ||
|
||
// A helper class for reading the passwords that have been imported. | ||
class PasswordImportConsumer { | ||
public: | ||
explicit PasswordImportConsumer(Profile* profile); | ||
|
||
void ConsumePassword(password_manager::PasswordImporter::Result result, | ||
const std::vector<autofill::PasswordForm>& forms); | ||
|
||
private: | ||
Profile* profile_; | ||
SEQUENCE_CHECKER(sequence_checker_); | ||
|
||
DISALLOW_COPY_AND_ASSIGN(PasswordImportConsumer); | ||
}; | ||
|
||
PasswordImportConsumer::PasswordImportConsumer(Profile* profile) | ||
: profile_(profile) {} | ||
|
||
void PasswordImportConsumer::ConsumePassword( | ||
password_manager::PasswordImporter::Result result, | ||
const std::vector<autofill::PasswordForm>& forms) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
|
||
UMA_HISTOGRAM_ENUMERATION( | ||
"PasswordManager.ImportPasswordFromCSVResult", result, | ||
password_manager::PasswordImporter::NUM_IMPORT_RESULTS); | ||
|
||
if (result != password_manager::PasswordImporter::SUCCESS) | ||
return; | ||
|
||
UMA_HISTOGRAM_COUNTS("PasswordManager.ImportedPasswordsPerUserInCSV", | ||
forms.size()); | ||
scoped_refptr<password_manager::PasswordStore> store( | ||
PasswordStoreFactory::GetForProfile(profile_, | ||
ServiceAccessType::EXPLICIT_ACCESS)); | ||
if (store) { | ||
for (const autofill::PasswordForm& form : forms) | ||
store->AddLogin(form); | ||
} | ||
} | ||
} // namespace | ||
|
||
PasswordManagerPorter::PasswordManagerPorter( | ||
CredentialProviderInterface* credential_provider_interface) | ||
: credential_provider_interface_(credential_provider_interface) {} | ||
|
||
PasswordManagerPorter::~PasswordManagerPorter() {} | ||
|
||
void PasswordManagerPorter::PresentFileSelector( | ||
content::WebContents* web_contents, | ||
Type type) { | ||
// This method should never be called on Android (as there is no file selector), | ||
// and the relevant IDS constants are not present for Android. | ||
#if !defined(OS_ANDROID) | ||
DCHECK(web_contents); | ||
profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); | ||
|
||
// Get the default file extension for password files. | ||
ui::SelectFileDialog::FileTypeInfo file_type_info; | ||
file_type_info.extensions = | ||
password_manager::PasswordExporter::GetSupportedFileExtensions(); | ||
DCHECK(!file_type_info.extensions.empty()); | ||
DCHECK(!file_type_info.extensions[0].empty()); | ||
file_type_info.include_all_files = true; | ||
|
||
// Present the file selector dialogue. | ||
select_file_dialog_ = ui::SelectFileDialog::Create( | ||
this, std::make_unique<ChromeSelectFilePolicy>(web_contents)); | ||
|
||
ui::SelectFileDialog::Type file_selector_mode = | ||
ui::SelectFileDialog::SELECT_NONE; | ||
unsigned title = 0; | ||
switch (type) { | ||
case PASSWORD_IMPORT: | ||
file_selector_mode = ui::SelectFileDialog::SELECT_OPEN_FILE; | ||
title = IDS_PASSWORD_MANAGER_IMPORT_DIALOG_TITLE; | ||
break; | ||
case PASSWORD_EXPORT: | ||
file_selector_mode = ui::SelectFileDialog::SELECT_SAVEAS_FILE; | ||
title = IDS_PASSWORD_MANAGER_EXPORT_DIALOG_TITLE; | ||
break; | ||
} | ||
// Check that a valid action has been chosen. | ||
DCHECK(file_selector_mode); | ||
DCHECK(title); | ||
|
||
select_file_dialog_->SelectFile( | ||
file_selector_mode, l10n_util::GetStringUTF16(title), | ||
GetDefaultFilepathForPasswordFile(file_type_info.extensions[0][0]), | ||
&file_type_info, 1, file_type_info.extensions[0][0], | ||
web_contents->GetTopLevelNativeWindow(), reinterpret_cast<void*>(type)); | ||
#endif | ||
} | ||
|
||
void PasswordManagerPorter::FileSelected(const base::FilePath& path, | ||
int index, | ||
void* params) { | ||
// We are unable to cast directly from void* to Type: reinterpret_cast will | ||
// only convert between pointers and static_cast only from integral types to | ||
// enums (for those types that are relevant to this example), which | ||
// necessitates the use of two casts. | ||
switch (static_cast<Type>(reinterpret_cast<uintptr_t>(params))) { | ||
case PASSWORD_IMPORT: | ||
ImportPasswordsFromPath(path); | ||
break; | ||
case PASSWORD_EXPORT: | ||
ExportPasswordsToPath(path); | ||
break; | ||
} | ||
} | ||
|
||
void PasswordManagerPorter::ImportPasswordsFromPath( | ||
const base::FilePath& path) { | ||
// Set up a |PasswordImportConsumer| to process each password entry. | ||
std::unique_ptr<PasswordImportConsumer> form_consumer( | ||
new PasswordImportConsumer(profile_)); | ||
password_manager::PasswordImporter::Import( | ||
path, base::Bind(&PasswordImportConsumer::ConsumePassword, | ||
std::move(form_consumer))); | ||
} | ||
|
||
void PasswordManagerPorter::ExportPasswordsToPath(const base::FilePath& path) { | ||
std::vector<std::unique_ptr<autofill::PasswordForm>> password_list = | ||
credential_provider_interface_->GetAllPasswords(); | ||
UMA_HISTOGRAM_COUNTS("PasswordManager.ExportedPasswordsPerUserInCSV", | ||
password_list.size()); | ||
password_manager::PasswordExporter::Export(path, std::move(password_list)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Copyright 2017 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_UI_PASSWORDS_PASSWORD_MANAGER_PORTER_H_ | ||
#define CHROME_BROWSER_UI_PASSWORDS_PASSWORD_MANAGER_PORTER_H_ | ||
|
||
#include "components/password_manager/core/browser/import/password_importer.h" | ||
#include "ui/shell_dialogs/select_file_dialog.h" | ||
|
||
namespace content { | ||
class WebContents; | ||
} | ||
|
||
class CredentialProviderInterface; | ||
class Profile; | ||
|
||
// Handles the exporting of passwords to a file, and the importing of such a | ||
// file to the Password Manager. | ||
class PasswordManagerPorter : public ui::SelectFileDialog::Listener { | ||
public: | ||
enum Type { | ||
PASSWORD_IMPORT, | ||
PASSWORD_EXPORT, | ||
}; | ||
|
||
explicit PasswordManagerPorter( | ||
CredentialProviderInterface* credential_provider_interface); | ||
|
||
~PasswordManagerPorter() override; | ||
|
||
// Display the file-picker dialogue for either importing or exporting | ||
// passwords. | ||
void PresentFileSelector(content::WebContents* web_contents, Type type); | ||
|
||
private: | ||
// Callback from the file selector dialogue when a file has been picked (for | ||
// either import or export). | ||
// ui::SelectFileDialog::Listener: | ||
void FileSelected(const base::FilePath& path, | ||
int index, | ||
void* params) override; | ||
|
||
virtual void ImportPasswordsFromPath(const base::FilePath& path); | ||
|
||
virtual void ExportPasswordsToPath(const base::FilePath& path); | ||
|
||
CredentialProviderInterface* credential_provider_interface_; | ||
scoped_refptr<ui::SelectFileDialog> select_file_dialog_; | ||
Profile* profile_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(PasswordManagerPorter); | ||
}; | ||
|
||
#endif // CHROME_BROWSER_UI_PASSWORDS_PASSWORD_MANAGER_PORTER_H_ |
Oops, something went wrong.