Import history, bookmarks, cookies, and passwords from Brave

This commit is contained in:
Garrett Robinson
2018-07-05 16:20:30 -07:00
parent 96ef43f327
commit f2cac13bcf
32 changed files with 988 additions and 46 deletions
+7
View File
@@ -100,6 +100,13 @@
By installing this extension, you are agreeing to the Google Widevine Terms of Use. You agree that Brave is not responsible for any damages or losses in connection with your use of Google Widevine.
</message>
<!-- Brave Importer -->
<message name="IDS_IMPORT_FROM_BRAVE" desc="browser combo box: Brave">
Brave
</message>
<message name="IDS_BOOKMARK_GROUP_FROM_BRAVE" desc="The group name of bookmarks from Brave">
Imported From Brave
</message>
</messages>
<includes>
<include name="IDR_BRAVE_TAG_SERVICES_POLYFILL" file="resources/js/tag_services_polyfill.js" type="BINDATA" />
+5
View File
@@ -10,6 +10,8 @@ source_set("common") {
"extensions/extension_constants.h",
"extensions/manifest_handlers/pdfjs_manifest_override.cc",
"extensions/manifest_handlers/pdfjs_manifest_override.h",
"importer/brave_importer_utils.cc",
"importer/brave_importer_utils.h",
"importer/chrome_importer_utils.cc",
"importer/chrome_importer_utils.h",
"network_constants.cc",
@@ -33,6 +35,7 @@ source_set("common") {
if (is_mac) {
sources += [
"importer/brave_importer_utils_mac.mm",
"importer/chrome_importer_utils_mac.mm",
]
}
@@ -41,6 +44,7 @@ source_set("common") {
sources += [
"brave_channel_info_posix.cc",
"brave_channel_info_posix.h",
"importer/brave_importer_utils_linux.cc",
"importer/chrome_importer_utils_linux.cc",
]
@@ -51,6 +55,7 @@ source_set("common") {
if (is_win) {
sources += [
"importer/brave_importer_utils_win.cc",
"importer/chrome_importer_utils_win.cc",
]
}
+39
View File
@@ -0,0 +1,39 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/common/importer/brave_importer_utils.h"
#include <memory>
#include <string>
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/values.h"
#include "chrome/common/importer/importer_data_types.h"
bool BraveImporterCanImport(const base::FilePath& profile,
uint16_t* services_supported) {
DCHECK(services_supported);
*services_supported = importer::NONE;
base::FilePath history =
profile.Append(base::FilePath::StringType(FILE_PATH_LITERAL("History")));
base::FilePath session_store =
profile.Append(base::FilePath::StringType(FILE_PATH_LITERAL("session-store-1")));
base::FilePath passwords =
profile.Append(base::FilePath::StringType(FILE_PATH_LITERAL("Login Data")));
base::FilePath cookies =
profile.Append(base::FilePath::StringType(FILE_PATH_LITERAL("Cookies")));
if (base::PathExists(history))
*services_supported |= importer::HISTORY;
if (base::PathExists(session_store))
*services_supported |= importer::FAVORITES;
if (base::PathExists(passwords))
*services_supported |= importer::PASSWORDS;
if (base::PathExists(cookies))
*services_supported |= importer::COOKIES;
return *services_supported != importer::NONE;
}
+26
View File
@@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_COMMON_IMPORTER_BRAVE_IMPORTER_UTILS_H_
#define BRAVE_COMMON_IMPORTER_BRAVE_IMPORTER_UTILS_H_
#include <stdint.h>
#include <vector>
namespace base {
class DictionaryValue;
class FilePath;
class ListValue;
}
base::FilePath GetBraveUserDataFolder();
base::ListValue* GetBraveSourceProfiles(
const base::FilePath& user_data_folder);
bool BraveImporterCanImport(const base::FilePath& profile,
uint16_t* services_supported);
#endif // BRAVE_COMMON_IMPORTER_BRAVE_IMPORTER_UTILS_H_
@@ -0,0 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/common/importer/brave_importer_utils.h"
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
base::FilePath GetBraveUserDataFolder() {
base::FilePath home;
if (!PathService::Get(base::DIR_HOME, &home))
return base::FilePath();
base::FilePath result = home;
// If Brave is installed via Snap, use the sandboxed home directory.
if (base::PathExists(base::FilePath("/snap/bin/brave"))) {
result = result.Append("snap").Append("brave").Append("current");
}
return result.Append(".config").Append("brave");
}
@@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <Cocoa/Cocoa.h>
#include <sys/param.h>
#include "brave/common/importer/brave_importer_utils.h"
#include "base/files/file_util.h"
#include "base/mac/foundation_util.h"
base::FilePath GetBraveUserDataFolder() {
base::FilePath result = base::mac::GetUserLibraryPath();
return result.Append("Application Support").Append("brave");
}
@@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/common/importer/brave_importer_utils.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string16.h"
base::FilePath GetBraveUserDataFolder() {
base::FilePath result;
if (!PathService::Get(base::DIR_APP_DATA, &result))
return base::FilePath();
result = result.AppendASCII("brave");
return result;
}
@@ -0,0 +1,22 @@
diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc
index 429c16dc6a56fcd0ea1d674508c1927a387e1905..0f29ba75ffce20b1104e36b4ba1aa78fd28fc50a 100644
--- a/chrome/browser/importer/external_process_importer_client.cc
+++ b/chrome/browser/importer/external_process_importer_client.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
+#include "brave/grit/generated_resources.h"
#include "build/build_config.h"
#include "chrome/browser/importer/external_process_importer_host.h"
#include "chrome/browser/importer/in_process_importer_bridge.h"
@@ -71,6 +72,9 @@ void ExternalProcessImporterClient::Start() {
localized_strings.SetKey(
base::IntToString(IDS_BOOKMARK_BAR_FOLDER_NAME),
base::Value(l10n_util::GetStringUTF8(IDS_BOOKMARK_BAR_FOLDER_NAME)));
+ localized_strings.SetKey(
+ base::IntToString(IDS_IMPORT_FROM_BRAVE),
+ base::Value(l10n_util::GetStringUTF8(IDS_IMPORT_FROM_BRAVE)));
// If the utility process hasn't started yet the message will queue until it
// does.
@@ -1,8 +1,8 @@
diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc
index 3bf47fa746e2a417f89201f3e3800d8639f2e323..122e9daf552834db4d41c77a320332305320696b 100644
index 3bf47fa746e2a417f89201f3e3800d8639f2e323..80d681f20de36650d2d2b3fb000c71687656140e 100644
--- a/chrome/browser/importer/importer_list.cc
+++ b/chrome/browser/importer/importer_list.cc
@@ -7,9 +7,12 @@
@@ -7,9 +7,14 @@
#include <stdint.h>
#include "base/bind.h"
@@ -11,11 +11,13 @@ index 3bf47fa746e2a417f89201f3e3800d8639f2e323..122e9daf552834db4d41c77a32033230
#include "base/task_scheduler/task_traits.h"
#include "base/threading/thread_restrictions.h"
+#include "base/values.h"
+#include "brave/common/importer/brave_importer_utils.h"
+#include "brave/common/importer/chrome_importer_utils.h"
+#include "brave/grit/generated_resources.h"
#include "build/build_config.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/importer/firefox_importer_utils.h"
@@ -124,6 +127,61 @@ void DetectFirefoxProfiles(const std::string locale,
@@ -124,6 +129,79 @@ void DetectFirefoxProfiles(const std::string locale,
profiles->push_back(firefox);
}
@@ -73,27 +75,50 @@ index 3bf47fa746e2a417f89201f3e3800d8639f2e323..122e9daf552834db4d41c77a32033230
+ AddChromeToProfiles(profiles, chromium_profiles, chromium_user_data_folder,
+ brandChromium);
+}
+
+void DetectBraveProfiles(std::vector<importer::SourceProfile>* profiles) {
+ base::AssertBlockingAllowed();
+
+ base::FilePath brave_user_data_folder = GetBraveUserDataFolder();
+
+ uint16_t items = importer::NONE;
+ if (!BraveImporterCanImport(brave_user_data_folder, &items))
+ return;
+
+ importer::SourceProfile brave;
+ brave.importer_name =
+ l10n_util::GetStringUTF16(IDS_IMPORT_FROM_BRAVE);
+ brave.importer_type = importer::TYPE_BRAVE;
+ brave.services_supported = items;
+ brave.source_path = brave_user_data_folder;
+ profiles->push_back(brave);
+}
+
std::vector<importer::SourceProfile> DetectSourceProfilesWorker(
const std::string& locale,
bool include_interactive_profiles) {
@@ -137,20 +195,30 @@ std::vector<importer::SourceProfile> DetectSourceProfilesWorker(
@@ -136,21 +214,37 @@ std::vector<importer::SourceProfile> DetectSourceProfilesWorker(
#if defined(OS_WIN)
if (shell_integration::IsFirefoxDefaultBrowser()) {
DetectFirefoxProfiles(locale, &profiles);
+ DetectBraveProfiles(&profiles);
DetectBuiltinWindowsProfiles(&profiles);
+ DetectChromeProfiles(&profiles);
} else {
DetectBuiltinWindowsProfiles(&profiles);
+ DetectBraveProfiles(&profiles);
DetectFirefoxProfiles(locale, &profiles);
+ DetectChromeProfiles(&profiles);
}
#elif defined(OS_MACOSX)
if (shell_integration::IsFirefoxDefaultBrowser()) {
DetectFirefoxProfiles(locale, &profiles);
+ DetectBraveProfiles(&profiles);
DetectSafariProfiles(&profiles);
+ DetectChromeProfiles(&profiles);
} else {
DetectSafariProfiles(&profiles);
+ DetectBraveProfiles(&profiles);
DetectFirefoxProfiles(locale, &profiles);
+ DetectChromeProfiles(&profiles);
}
@@ -101,8 +126,10 @@ index 3bf47fa746e2a417f89201f3e3800d8639f2e323..122e9daf552834db4d41c77a32033230
- DetectFirefoxProfiles(locale, &profiles);
+ if (shell_integration::IsFirefoxDefaultBrowser()) {
+ DetectFirefoxProfiles(locale, &profiles);
+ DetectBraveProfiles(&profiles);
+ DetectChromeProfiles(&profiles);
+ } else {
+ DetectBraveProfiles(&profiles);
+ DetectChromeProfiles(&profiles);
+ DetectFirefoxProfiles(locale, &profiles);
+ }
@@ -1,13 +1,16 @@
diff --git a/chrome/browser/importer/importer_uma.cc b/chrome/browser/importer/importer_uma.cc
index da87e84ffe7c2193ea16d24f1ee1174c51c9503f..261dd432b1759b4e62c5ee2b2b0a6e27a688700d 100644
index da87e84ffe7c2193ea16d24f1ee1174c51c9503f..fb80acdfd3997df06189334a8575f39431bf9bd9 100644
--- a/chrome/browser/importer/importer_uma.cc
+++ b/chrome/browser/importer/importer_uma.cc
@@ -59,6 +59,9 @@ void LogImporterUseToMetrics(const std::string& metric_postfix,
@@ -59,6 +59,12 @@ void LogImporterUseToMetrics(const std::string& metric_postfix,
case TYPE_BOOKMARKS_FILE:
metrics_type = IMPORTER_METRICS_BOOKMARKS_FILE;
break;
+ case TYPE_CHROME:
+ // TODO: Wire this up if we want to record metrics on users who import from Chrome
+ break;
+ case TYPE_BRAVE:
+ // TODO: Wire this up if we want to record metrics on users who import from Brave
+ break;
}
@@ -1,13 +1,15 @@
diff --git a/chrome/browser/importer/in_process_importer_bridge.cc b/chrome/browser/importer/in_process_importer_bridge.cc
index 5832fa66c715fe82a3e865c7bde490ef6f6b14b6..5e345a533beef357ee9e0e5509074ec997daa9fa 100644
index 5832fa66c715fe82a3e865c7bde490ef6f6b14b6..acebdad31c6c1b53b8d51b37daa1a9373f4a9158 100644
--- a/chrome/browser/importer/in_process_importer_bridge.cc
+++ b/chrome/browser/importer/in_process_importer_bridge.cc
@@ -59,6 +59,8 @@ history::VisitSource ConvertImporterVisitSourceToHistoryVisitSource(
@@ -59,6 +59,10 @@ history::VisitSource ConvertImporterVisitSourceToHistoryVisitSource(
return history::SOURCE_IE_IMPORTED;
case importer::VISIT_SOURCE_SAFARI_IMPORTED:
return history::SOURCE_SAFARI_IMPORTED;
+ case importer::VISIT_SOURCE_CHROME_IMPORTED:
+ return history::SOURCE_CHROME_IMPORTED;
+ case importer::VISIT_SOURCE_BRAVE_IMPORTED:
+ return history::SOURCE_BRAVE_IMPORTED;
}
NOTREACHED();
return history::SOURCE_SYNCED;
@@ -1,12 +1,13 @@
diff --git a/chrome/common/importer/importer_data_types.h b/chrome/common/importer/importer_data_types.h
index 0fc90c62398a93eb89568ce78c8ded2bc9b232b6..50a7d3c0079b7e9c5bc38a4ae3b25eef6d024169 100644
index 0fc90c62398a93eb89568ce78c8ded2bc9b232b6..cd3301cdbab878231050dbdf66d4572852d0a331 100644
--- a/chrome/common/importer/importer_data_types.h
+++ b/chrome/common/importer/importer_data_types.h
@@ -83,6 +83,7 @@ enum VisitSource {
@@ -83,6 +83,8 @@ enum VisitSource {
VISIT_SOURCE_FIREFOX_IMPORTED = 1,
VISIT_SOURCE_IE_IMPORTED = 2,
VISIT_SOURCE_SAFARI_IMPORTED = 3,
+ VISIT_SOURCE_CHROME_IMPORTED = 4,
+ VISIT_SOURCE_BRAVE_IMPORTED = 5,
};
} // namespace importer
@@ -1,8 +1,8 @@
diff --git a/chrome/common/importer/importer_type.h b/chrome/common/importer/importer_type.h
index c172f8a5bc534465ff4d063a52f9bb510b7e36af..f1252eb63f413e2135202236ca40d05f129a6c7a 100644
index c172f8a5bc534465ff4d063a52f9bb510b7e36af..88d54c3bcc91f6d2975a3c3e040cb14d20bfbfeb 100644
--- a/chrome/common/importer/importer_type.h
+++ b/chrome/common/importer/importer_type.h
@@ -19,6 +19,8 @@ enum ImporterType {
@@ -19,11 +19,15 @@ enum ImporterType {
TYPE_IE = 0,
#endif
// Value 1 was the (now deleted) Firefox 2 profile importer.
@@ -11,3 +11,10 @@ index c172f8a5bc534465ff4d063a52f9bb510b7e36af..f1252eb63f413e2135202236ca40d05f
TYPE_FIREFOX = 2,
#if defined(OS_MACOSX)
TYPE_SAFARI = 3,
#endif
// Value 4 was the (now deleted) Google Toolbar importer.
+ // We use it for the Brave profile importer now.
+ TYPE_BRAVE = 4,
TYPE_BOOKMARKS_FILE = 5, // Identifies a 'bookmarks.html' file.
#if defined(OS_WIN)
TYPE_EDGE = 6,
@@ -1,21 +1,24 @@
diff --git a/chrome/utility/importer/importer_creator.cc b/chrome/utility/importer/importer_creator.cc
index 2bef627aa890484a3fb75fa9bd04b2994f997305..90214ae7659f57971f66119bede4bd7dd34a30f3 100644
index 2bef627aa890484a3fb75fa9bd04b2994f997305..48b0ce819af1ad86b5ae19ba778dcae79560bae9 100644
--- a/chrome/utility/importer/importer_creator.cc
+++ b/chrome/utility/importer/importer_creator.cc
@@ -5,6 +5,7 @@
@@ -5,6 +5,8 @@
#include "chrome/utility/importer/importer_creator.h"
#include "base/logging.h"
+#include "brave/utility/importer/brave_importer.h"
+#include "brave/utility/importer/chrome_importer.h"
#include "build/build_config.h"
#include "chrome/utility/importer/bookmarks_file_importer.h"
#include "chrome/utility/importer/firefox_importer.h"
@@ -43,6 +44,8 @@ scoped_refptr<Importer> CreateImporterByType(ImporterType type) {
@@ -43,6 +45,10 @@ scoped_refptr<Importer> CreateImporterByType(ImporterType type) {
case TYPE_SAFARI:
return new SafariImporter(base::mac::GetUserLibraryPath());
#endif
+ case TYPE_CHROME:
+ return new ChromeImporter();
+ case TYPE_BRAVE:
+ return new BraveImporter();
default:
NOTREACHED();
return nullptr;
@@ -1,5 +1,5 @@
diff --git a/chrome/utility/importer/profile_import_impl.cc b/chrome/utility/importer/profile_import_impl.cc
index 1cbcc2fcb663c43daad9e6ad86f97e74b964aa11..2910707b7f569cb87947c81d8522f1d9fad82014 100644
index 1cbcc2fcb663c43daad9e6ad86f97e74b964aa11..ec1c8c3d159c84e8e757dcb84a2766dc7f54851a 100644
--- a/chrome/utility/importer/profile_import_impl.cc
+++ b/chrome/utility/importer/profile_import_impl.cc
@@ -2,12 +2,16 @@
@@ -19,7 +19,7 @@ index 1cbcc2fcb663c43daad9e6ad86f97e74b964aa11..2910707b7f569cb87947c81d8522f1d9
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
@@ -39,6 +43,16 @@ void ProfileImportImpl::StartImport(
@@ -39,6 +43,19 @@ void ProfileImportImpl::StartImport(
items_to_import_ = items;
@@ -31,12 +31,15 @@ index 1cbcc2fcb663c43daad9e6ad86f97e74b964aa11..2910707b7f569cb87947c81d8522f1d9
+ } else if (base::StartsWith(base::UTF16ToUTF8(source_profile.importer_name),
+ "Chromium", base::CompareCase::SENSITIVE)) {
+ command_line->AppendSwitch("import-chromium");
+ } else if (base::StartsWith(base::UTF16ToUTF8(source_profile.importer_name),
+ "Brave", base::CompareCase::SENSITIVE)) {
+ command_line->AppendSwitch("import-brave");
+ }
+
// Create worker thread in which importer runs.
import_thread_.reset(new base::Thread("import_thread"));
#if defined(OS_WIN)
@@ -48,7 +62,7 @@ void ProfileImportImpl::StartImport(
@@ -48,7 +65,7 @@ void ProfileImportImpl::StartImport(
NOTREACHED();
ImporterCleanup();
}
@@ -1,12 +1,13 @@
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h
index ff27b0d74068df5f661bdb6ceb25cff6f61f1ed6..49738a07a4ae0faa11ee73b6004e8869322bdff5 100644
index ff27b0d74068df5f661bdb6ceb25cff6f61f1ed6..356614a0949e13c0864ea9a8ee96adcc542d9421 100644
--- a/components/history/core/browser/history_types.h
+++ b/components/history/core/browser/history_types.h
@@ -55,6 +55,7 @@ enum VisitSource {
@@ -55,6 +55,8 @@ enum VisitSource {
SOURCE_FIREFOX_IMPORTED = 3,
SOURCE_IE_IMPORTED = 4,
SOURCE_SAFARI_IMPORTED = 5,
+ SOURCE_CHROME_IMPORTED = 6,
+ SOURCE_BRAVE_IMPORTED = 7,
};
typedef int64_t VisitID;
@@ -1,5 +1,5 @@
diff --git a/components/os_crypt/key_storage_keyring.cc b/components/os_crypt/key_storage_keyring.cc
index af2f64b34ddb8e49d72dd0dd22ffd2418a422efb..9db6e47b35e6cac14168908a4385120fe44cb8d0 100644
index af2f64b34ddb8e49d72dd0dd22ffd2418a422efb..ba7380e307740690ea2f3b626d24715e2c707fc0 100644
--- a/components/os_crypt/key_storage_keyring.cc
+++ b/components/os_crypt/key_storage_keyring.cc
@@ -6,6 +6,7 @@
@@ -19,7 +19,7 @@ index af2f64b34ddb8e49d72dd0dd22ffd2418a422efb..9db6e47b35e6cac14168908a4385120f
#endif
const GnomeKeyringPasswordSchema kSchema = {
@@ -45,9 +46,18 @@ std::string KeyStorageKeyring::GetKeyImpl() {
@@ -45,9 +46,19 @@ std::string KeyStorageKeyring::GetKeyImpl() {
std::string password;
gchar* password_c = nullptr;
@@ -27,7 +27,8 @@ index af2f64b34ddb8e49d72dd0dd22ffd2418a422efb..9db6e47b35e6cac14168908a4385120f
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch("import-chrome")) {
+ application_name = "chrome";
+ } else if (command_line->HasSwitch("import-chromium")) {
+ } else if (command_line->HasSwitch("import-chromium") ||
+ command_line->HasSwitch("import-brave")) {
+ application_name = "chromium";
+ } else {
+ application_name = kApplicationName;
@@ -1,5 +1,5 @@
diff --git a/components/os_crypt/key_storage_kwallet.cc b/components/os_crypt/key_storage_kwallet.cc
index aa4b3d4a6b5c7b1f725d6446ea5e573094ec935b..4c4c7191a57afc7a42dfa87701578bd99d417d94 100644
index aa4b3d4a6b5c7b1f725d6446ea5e573094ec935b..8e1ac53bccaf2213466af3daf685ee88f3253f11 100644
--- a/components/os_crypt/key_storage_kwallet.cc
+++ b/components/os_crypt/key_storage_kwallet.cc
@@ -7,6 +7,7 @@
@@ -10,7 +10,7 @@ index aa4b3d4a6b5c7b1f725d6446ea5e573094ec935b..4c4c7191a57afc7a42dfa87701578bd9
#include "base/rand_util.h"
#include "components/os_crypt/kwallet_dbus.h"
#include "dbus/bus.h"
@@ -90,11 +91,24 @@ std::string KeyStorageKWallet::GetKeyImpl() {
@@ -90,11 +91,25 @@ std::string KeyStorageKWallet::GetKeyImpl() {
if (!InitFolder())
return std::string();
@@ -19,7 +19,8 @@ index aa4b3d4a6b5c7b1f725d6446ea5e573094ec935b..4c4c7191a57afc7a42dfa87701578bd9
+ if (command_line->HasSwitch("import-chrome")) {
+ folder_name = "Chrome Keys";
+ key = "Chrome Safe Storage";
+ } else if (command_line->HasSwitch("import-chromium")) {
+ } else if (command_line->HasSwitch("import-chromium") ||
+ command_line->HasSwitch("import-brave")) {
+ folder_name = "Chromium Keys";
+ key = "Chromium Safe Storage";
+ } else {
@@ -37,7 +38,7 @@ index aa4b3d4a6b5c7b1f725d6446ea5e573094ec935b..4c4c7191a57afc7a42dfa87701578bd9
if (error)
return std::string();
@@ -114,8 +128,17 @@ std::string KeyStorageKWallet::GetKeyImpl() {
@@ -114,8 +129,18 @@ std::string KeyStorageKWallet::GetKeyImpl() {
bool KeyStorageKWallet::InitFolder() {
bool has_folder = false;
@@ -45,7 +46,8 @@ index aa4b3d4a6b5c7b1f725d6446ea5e573094ec935b..4c4c7191a57afc7a42dfa87701578bd9
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch("import-chrome")) {
+ folder_name = "Chrome Keys";
+ } else if (command_line->HasSwitch("import-chromium")) {
+ } else if (command_line->HasSwitch("import-chromium") ||
+ command_line->HasSwitch("import-brave")) {
+ folder_name = "Chromium Keys";
+ } else {
+ folder_name = KeyStorageLinux::kFolderName;
@@ -1,5 +1,5 @@
diff --git a/components/os_crypt/key_storage_libsecret.cc b/components/os_crypt/key_storage_libsecret.cc
index a1b5b975bc89c4891643adab17ce0b00ba2a8032..9d4be365463d2555101a96006ca4c68a61b7e886 100644
index a1b5b975bc89c4891643adab17ce0b00ba2a8032..7d5b3200f1b6ac3f99b536767281f761b9ad8193 100644
--- a/components/os_crypt/key_storage_libsecret.cc
+++ b/components/os_crypt/key_storage_libsecret.cc
@@ -5,6 +5,7 @@
@@ -19,7 +19,7 @@ index a1b5b975bc89c4891643adab17ce0b00ba2a8032..9d4be365463d2555101a96006ca4c68a
#endif
// Deprecated in M55 (crbug.com/639298)
@@ -73,7 +74,16 @@ std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() {
@@ -73,7 +74,17 @@ std::string KeyStorageLibsecret::AddRandomPasswordInLibsecret() {
std::string KeyStorageLibsecret::GetKeyImpl() {
LibsecretAttributesBuilder attrs;
@@ -28,7 +28,8 @@ index a1b5b975bc89c4891643adab17ce0b00ba2a8032..9d4be365463d2555101a96006ca4c68a
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch("import-chrome")) {
+ application_name = "chrome";
+ } else if (command_line->HasSwitch("import-chromium")) {
+ } else if (command_line->HasSwitch("import-chromium") ||
+ command_line->HasSwitch("import-brave")) {
+ application_name = "chromium";
+ } else {
+ application_name = kApplicationName;
@@ -1,5 +1,5 @@
diff --git a/components/os_crypt/keychain_password_mac.mm b/components/os_crypt/keychain_password_mac.mm
index 2b38db266f9aa1f4141c8649c021042ede4e5589..4b14f15e5091b251be53eff29139beaa59a93dbc 100644
index 2b38db266f9aa1f4141c8649c021042ede4e5589..442defb6f2d9ee129ca5c01ccd360d626934a9d3 100644
--- a/components/os_crypt/keychain_password_mac.mm
+++ b/components/os_crypt/keychain_password_mac.mm
@@ -7,6 +7,7 @@
@@ -10,7 +10,7 @@ index 2b38db266f9aa1f4141c8649c021042ede4e5589..4b14f15e5091b251be53eff29139beaa
#include "base/mac/mac_logging.h"
#include "base/rand_util.h"
#include "crypto/apple_keychain.h"
@@ -54,11 +55,23 @@ std::string AddRandomPasswordToKeychain(const AppleKeychain& keychain,
@@ -54,11 +55,24 @@
const char KeychainPassword::service_name[] = "Chrome Safe Storage";
const char KeychainPassword::account_name[] = "Chrome";
#else
@@ -26,7 +26,8 @@ index 2b38db266f9aa1f4141c8649c021042ede4e5589..4b14f15e5091b251be53eff29139beaa
+ if (command_line->HasSwitch("import-chrome")) {
+ service_name = "Chrome Safe Storage";
+ account_name = "Chrome";
+ } else if (command_line->HasSwitch("import-chromium")) {
+ } else if (command_line->HasSwitch("import-chromium") ||
+ command_line->HasSwitch("import-brave")) {
+ service_name = "Chromium Safe Storage";
+ account_name = "Chromium";
+ } else {
+1
View File
@@ -41,6 +41,7 @@ test("brave_unit_tests") {
"//chrome/common/importer/mock_importer_bridge.h",
"../browser/importer/chrome_profile_lock_unittest.cc",
"../utility/importer/chrome_importer_unittest.cc",
"../utility/importer/brave_importer_unittest.cc",
]
# On Windows, brave_install_static_unittests covers channel test.
@@ -0,0 +1,9 @@
Since Brave browser-laptop is based on Chromium (via Muon/Electron), most of the notes from the ChromeImporter test data README (`../chrome/README`) are also applicable here.
# Generating test data
Unlike Chrome/Chromium, Brave browser-laptop does not support multiple profiles, so if you use Brave as your regular web browser, it may not be immediately obvious how you can create a separate profile for the purpose of generating test data. I found the least obtrusive method to be setting the CHROME_USER_DATA_DIR environment variable, e.g. on macOS:
TEST_UDD=/path/to/test/user/data/dir
mkdir -p $TEST_UDD
CHROME_USER_DATA_DIR=$TEST_UDD /Applications/Brave.app/Contents/MacOS/Brave
File diff suppressed because one or more lines are too long
+12 -2
View File
@@ -3,7 +3,17 @@ const port = 8080
const requestHandler = (request, response) => {
console.log(request.url)
response.setHeader('Set-Cookie', ['test=test'])
// Cookie needs Expires or Max-Age attribute to be a persistent
// cookie; otherwise, the browser will treat it as an ephemeral
// session cookie and may delete it when the browser is closed.
//
// The maximum allowable Expires date is used to avoid any potential
// issues with the test browser clearing the cookie upon load if the
// tests are run after the cookie's expiration date. The choice of
// date and the decision to use an absolute date with Expires rather
// than a relative one with Max-Age are based on this Stack Overflow
// answer: https://stackoverflow.com/a/22479460.
response.setHeader('Set-Cookie', ['test=test; Expires=Tue, 19 Jan 2038 03:14:07 GMT'])
response.end('Cookie set')
}
@@ -15,4 +25,4 @@ server.listen(port, (err) => {
}
console.log(`server is listening on ${port}`)
})
})
+2
View File
@@ -7,6 +7,8 @@ source_set("utility") {
"brave_content_utility_client.h",
"importer/brave_external_process_importer_bridge.cc",
"importer/brave_external_process_importer_bridge.h",
"importer/brave_importer.cc",
"importer/brave_importer.h",
"importer/chrome_importer.cc",
"importer/chrome_importer.h",
]
+440
View File
@@ -0,0 +1,440 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/utility/importer/brave_importer.h"
#include <memory>
#include <vector>
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "brave/grit/generated_resources.h"
#include "chrome/common/importer/importer_bridge.h"
#include "components/autofill/core/common/password_form.h"
#include "components/cookie_config/cookie_store_util.h"
#include "components/os_crypt/os_crypt.h"
#include "components/password_manager/core/browser/login_database.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_filter.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/extras/sqlite/cookie_crypto_delegate.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
#include "sql/connection.h"
#include "sql/statement.h"
#include "url/gurl.h"
#if defined(OS_LINUX)
#include "components/os_crypt/key_storage_config_linux.h"
#endif
#if defined(USE_X11)
#if defined(USE_LIBSECRET)
#include "chrome/browser/password_manager/native_backend_libsecret.h"
#endif
#include "chrome/browser/password_manager/native_backend_kwallet_x.h"
#include "chrome/browser/password_manager/password_store_x.h"
#include "components/os_crypt/key_storage_util_linux.h"
base::nix::DesktopEnvironment BraveImporter::GetDesktopEnvironment() {
std::unique_ptr<base::Environment> env(base::Environment::Create());
return base::nix::GetDesktopEnvironment(env.get());
}
#endif
using base::Time;
BraveImporter::BraveImporter() {
}
BraveImporter::~BraveImporter() {
}
void BraveImporter::StartImport(const importer::SourceProfile& source_profile,
uint16_t items,
ImporterBridge* bridge) {
bridge_ = bridge;
source_path_ = source_profile.source_path;
// The order here is important!
bridge_->NotifyStarted();
if ((items & importer::HISTORY) && !cancelled()) {
bridge_->NotifyItemStarted(importer::HISTORY);
ImportHistory();
bridge_->NotifyItemEnded(importer::HISTORY);
}
if ((items & importer::FAVORITES) && !cancelled()) {
bridge_->NotifyItemStarted(importer::FAVORITES);
ImportBookmarks();
bridge_->NotifyItemEnded(importer::FAVORITES);
}
if ((items & importer::PASSWORDS) && !cancelled()) {
bridge_->NotifyItemStarted(importer::PASSWORDS);
ImportPasswords();
bridge_->NotifyItemEnded(importer::PASSWORDS);
}
if ((items & importer::COOKIES) && !cancelled()) {
bridge_->NotifyItemStarted(importer::COOKIES);
ImportCookies();
bridge_->NotifyItemEnded(importer::COOKIES);
}
bridge_->NotifyEnded();
}
// Returns true if |url| has a valid scheme that we allow to import. We
// filter out the URL with a unsupported scheme.
bool CanImportURL(const GURL& url) {
// The URL is not valid.
if (!url.is_valid())
return false;
// Filter out the URLs with unsupported schemes.
const char* const kInvalidSchemes[] = {"chrome-extension"};
for (size_t i = 0; i < arraysize(kInvalidSchemes); ++i) {
if (url.SchemeIs(kInvalidSchemes[i]))
return false;
}
return true;
}
void BraveImporter::ImportHistory() {
base::FilePath history_path =
source_path_.Append(
base::FilePath::StringType(FILE_PATH_LITERAL("History")));
if (!base::PathExists(history_path))
return;
sql::Connection db;
if (!db.Open(history_path))
return;
const char query[] =
"SELECT url, title, last_visit_time, typed_count, visit_count "
"FROM urls WHERE hidden = 0";
sql::Statement s(db.GetUniqueStatement(query));
std::vector<ImporterURLRow> rows;
while (s.Step() && !cancelled()) {
GURL url(s.ColumnString(0));
// Filter out unwanted URLs.
if (!CanImportURL(url))
continue;
ImporterURLRow row(url);
row.title = s.ColumnString16(1);
row.last_visit =
base::Time::FromDoubleT(chromeTimeToDouble((s.ColumnInt64(2))));
row.hidden = false;
row.typed_count = s.ColumnInt(3);
row.visit_count = s.ColumnInt(4);
rows.push_back(row);
}
if (!rows.empty() && !cancelled())
bridge_->SetHistoryItems(rows, importer::VISIT_SOURCE_BRAVE_IMPORTED);
}
void BraveImporter::ParseBookmarks(
std::vector<ImportedBookmarkEntry>* bookmarks) {
base::FilePath session_store_path =
source_path_.Append(
base::FilePath::StringType(FILE_PATH_LITERAL("session-store-1")));
std::string session_store_content;
if (!ReadFileToString(session_store_path, &session_store_content)) {
LOG(ERROR) << "Reading Brave session store file failed";
return;
}
std::unique_ptr<base::Value> session_store_json =
base::JSONReader::Read(session_store_content);
if (!session_store_json) {
LOG(ERROR) << "Parsing Brave session store JSON failed";
return;
}
base::Value* bookmark_folders_dict =
session_store_json->FindKeyOfType("bookmarkFolders",
base::Value::Type::DICTIONARY);
base::Value* bookmarks_dict =
session_store_json->FindKeyOfType("bookmarks",
base::Value::Type::DICTIONARY);
base::Value* bookmark_order_dict =
session_store_json->FindPathOfType({"cache", "bookmarkOrder"},
base::Value::Type::DICTIONARY);
if (!(bookmark_folders_dict && bookmarks_dict && bookmark_order_dict))
return;
// Recursively load bookmarks from each of the top-level bookmarks
// folders: "Bookmarks Toolbar" and "Other Bookmarks"
std::vector<base::string16> path;
RecursiveReadBookmarksFolder(base::UTF8ToUTF16("Bookmarks Toolbar"),
"0",
path,
true,
bookmark_folders_dict,
bookmarks_dict,
bookmark_order_dict,
bookmarks);
RecursiveReadBookmarksFolder(base::UTF8ToUTF16("Other Bookmarks"),
"-1",
path,
false,
bookmark_folders_dict,
bookmarks_dict,
bookmark_order_dict,
bookmarks);
}
void BraveImporter::RecursiveReadBookmarksFolder(
const base::string16 name,
const std::string key,
std::vector<base::string16> path,
const bool in_toolbar,
base::Value* bookmark_folders_dict,
base::Value* bookmarks_dict,
base::Value* bookmark_order_dict,
std::vector<ImportedBookmarkEntry>* bookmarks) {
// Add the name of the current folder to the path
path.push_back(name);
base::Value* bookmark_order =
bookmark_order_dict->FindKeyOfType(key, base::Value::Type::LIST);
if (!bookmark_order)
return;
for (const auto& entry : bookmark_order->GetList()) {
auto& type = entry.FindKeyOfType("type", base::Value::Type::STRING)->GetString();
auto& key = entry.FindKeyOfType("key", base::Value::Type::STRING)->GetString();
if (type == "bookmark-folder") {
base::Value* bookmark_folder =
bookmark_folders_dict->FindKeyOfType(key, base::Value::Type::DICTIONARY);
auto& title =
bookmark_folder->FindKeyOfType("title", base::Value::Type::STRING)->GetString();
// Empty folders don't have a corresponding entry in bookmark_order_dict,
// which provides an easy way to test whether a folder is empty.
base::Value* bookmark_order_entry =
bookmark_order_dict->FindKeyOfType(key, base::Value::Type::LIST);
if (bookmark_order_entry) {
// Recurse into non-empty folder.
RecursiveReadBookmarksFolder(base::UTF8ToUTF16(title),
key,
path,
in_toolbar,
bookmark_folders_dict,
bookmarks_dict,
bookmark_order_dict,
bookmarks);
} else {
// Add ImportedBookmarkEntry for empty folder.
ImportedBookmarkEntry imported_bookmark_folder;
imported_bookmark_folder.is_folder = true;
imported_bookmark_folder.in_toolbar = in_toolbar;
imported_bookmark_folder.url = GURL();
imported_bookmark_folder.path = path;
imported_bookmark_folder.title = base::UTF8ToUTF16(title);
// Brave doesn't specify a creation time for the folder.
imported_bookmark_folder.creation_time = base::Time::Now();
bookmarks->push_back(imported_bookmark_folder);
}
} else if (type == "bookmark") {
base::Value* bookmark =
bookmarks_dict->FindKeyOfType(key, base::Value::Type::DICTIONARY);
auto& title =
bookmark->FindKeyOfType("title", base::Value::Type::STRING)->GetString();
auto& location =
bookmark->FindKeyOfType("location", base::Value::Type::STRING)->GetString();
ImportedBookmarkEntry imported_bookmark;
imported_bookmark.is_folder = false;
imported_bookmark.in_toolbar = in_toolbar;
imported_bookmark.url = GURL(location);
imported_bookmark.path = path;
imported_bookmark.title = base::UTF8ToUTF16(title);
// Brave doesn't specify a creation time for the bookmark.
imported_bookmark.creation_time = base::Time::Now();
bookmarks->push_back(imported_bookmark);
}
}
}
void BraveImporter::ImportBookmarks() {
std::vector<ImportedBookmarkEntry> bookmarks;
ParseBookmarks(&bookmarks);
if (!bookmarks.empty() && !cancelled()) {
const base::string16& first_folder_name =
bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_BRAVE);
bridge_->AddBookmarks(bookmarks, first_folder_name);
}
}
double BraveImporter::chromeTimeToDouble(int64_t time) {
return ((time * 10 - 0x19DB1DED53E8000) / 10000) / 1000;
}
void BraveImporter::ImportPasswords() {
#if !defined(USE_X11)
base::FilePath passwords_path =
source_path_.Append(
base::FilePath::StringType(FILE_PATH_LITERAL("Login Data")));
password_manager::LoginDatabase database(passwords_path);
if (!database.Init()) {
LOG(ERROR) << "LoginDatabase Init() failed";
return;
}
std::vector<std::unique_ptr<autofill::PasswordForm>> forms;
bool success = database.GetAutofillableLogins(&forms);
if (success) {
for (size_t i = 0; i < forms.size(); ++i) {
bridge_->SetPasswordForm(*forms[i].get());
}
}
std::vector<std::unique_ptr<autofill::PasswordForm>> blacklist;
success = database.GetBlacklistLogins(&blacklist);
if (success) {
for (size_t i = 0; i < blacklist.size(); ++i) {
bridge_->SetPasswordForm(*blacklist[i].get());
}
}
#else
base::FilePath prefs_path =
source_path_.Append(
base::FilePath::StringType(FILE_PATH_LITERAL("UserPrefs")));
const base::Value *value;
scoped_refptr<JsonPrefStore> prefs = new JsonPrefStore(prefs_path);
int local_profile_id;
if (prefs->ReadPrefs() != PersistentPrefStore::PREF_READ_ERROR_NONE) {
return;
}
if (!prefs->GetValue(password_manager::prefs::kLocalProfileId, &value)) {
return;
}
if (!value->GetAsInteger(&local_profile_id)) {
return;
}
std::unique_ptr<PasswordStoreX::NativeBackend> backend;
base::nix::DesktopEnvironment desktop_env = GetDesktopEnvironment();
// WIP proper kEnableEncryptionSelection
os_crypt::SelectedLinuxBackend selected_backend =
os_crypt::SelectBackend(std::string(), true, desktop_env);
if (!backend &&
(selected_backend == os_crypt::SelectedLinuxBackend::KWALLET ||
selected_backend == os_crypt::SelectedLinuxBackend::KWALLET5)) {
base::nix::DesktopEnvironment used_desktop_env =
selected_backend == os_crypt::SelectedLinuxBackend::KWALLET
? base::nix::DESKTOP_ENVIRONMENT_KDE4
: base::nix::DESKTOP_ENVIRONMENT_KDE5;
backend.reset(new NativeBackendKWallet(local_profile_id,
used_desktop_env));
} else if (selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY ||
selected_backend ==
os_crypt::SelectedLinuxBackend::GNOME_KEYRING ||
selected_backend ==
os_crypt::SelectedLinuxBackend::GNOME_LIBSECRET) {
#if defined(USE_LIBSECRET)
if (!backend &&
(selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY ||
selected_backend == os_crypt::SelectedLinuxBackend::GNOME_LIBSECRET)) {
backend.reset(new NativeBackendLibsecret(local_profile_id));
}
#endif
}
if (backend && backend->Init()) {
std::vector<std::unique_ptr<autofill::PasswordForm>> forms;
bool success = backend->GetAutofillableLogins(&forms);
if (success) {
for (size_t i = 0; i < forms.size(); ++i) {
bridge_->SetPasswordForm(*forms[i].get());
}
}
std::vector<std::unique_ptr<autofill::PasswordForm>> blacklist;
success = backend->GetBlacklistLogins(&blacklist);
if (success) {
for (size_t i = 0; i < blacklist.size(); ++i) {
bridge_->SetPasswordForm(*blacklist[i].get());
}
}
}
#endif
}
void BraveImporter::ImportCookies() {
base::FilePath cookies_path =
source_path_.Append(
base::FilePath::StringType(FILE_PATH_LITERAL("Cookies")));
if (!base::PathExists(cookies_path))
return;
sql::Connection db;
if (!db.Open(cookies_path))
return;
const char query[] =
"SELECT creation_utc, host_key, name, value, encrypted_value, path, "
"expires_utc, is_secure, is_httponly, firstpartyonly, last_access_utc, "
"has_expires, is_persistent, priority FROM cookies";
sql::Statement s(db.GetUniqueStatement(query));
net::CookieCryptoDelegate* delegate =
cookie_config::GetCookieCryptoDelegate();
#if defined(OS_LINUX)
OSCrypt::SetConfig(std::make_unique<os_crypt::Config>());
#endif
std::vector<net::CanonicalCookie> cookies;
while (s.Step() && !cancelled()) {
std::string encrypted_value = s.ColumnString(4);
std::string value;
if (!encrypted_value.empty() && delegate) {
if (!delegate->DecryptString(encrypted_value, &value)) {
continue;
}
} else {
value = s.ColumnString(3);
}
auto cookie = net::CanonicalCookie(
s.ColumnString(2), // name
value, // value
s.ColumnString(1), // domain
s.ColumnString(5), // path
Time::FromInternalValue(s.ColumnInt64(0)), // creation_utc
Time::FromInternalValue(s.ColumnInt64(6)), // expires_utc
Time::FromInternalValue(s.ColumnInt64(10)), // last_access_utc
s.ColumnBool(7), // secure
s.ColumnBool(8), // http_only
static_cast<net::CookieSameSite>(s.ColumnInt(9)), // samesite
static_cast<net::CookiePriority>(s.ColumnInt(13))); // priority
if (cookie.IsCanonical()) {
cookies.push_back(cookie);
}
}
if (!cookies.empty() && !cancelled()) {
bridge_->SetCookies(cookies);
}
}
+58
View File
@@ -0,0 +1,58 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_UTILITY_IMPORTER_BRAVE_IMPORTER_H_
#define BRAVE_UTILITY_IMPORTER_BRAVE_IMPORTER_H_
#include <stdint.h>
#include <map>
#include <vector>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/nix/xdg_util.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/common/importer/imported_bookmark_entry.h"
#include "chrome/utility/importer/importer.h"
class BraveImporter : public Importer {
public:
BraveImporter();
// Importer:
void StartImport(const importer::SourceProfile& source_profile,
uint16_t items,
ImporterBridge* bridge) override;
private:
~BraveImporter() override;
static base::nix::DesktopEnvironment GetDesktopEnvironment();
void ImportHistory();
void ImportBookmarks();
void ImportPasswords();
void ImportCookies();
void ParseBookmarks(std::vector<ImportedBookmarkEntry>* bookmarks);
void RecursiveReadBookmarksFolder(
const base::string16 name,
const std::string key,
std::vector<base::string16> path,
const bool in_toolbar,
base::Value* bookmark_folders_dict,
base::Value* bookmarks_dict,
base::Value* bookmark_order_dict,
std::vector<ImportedBookmarkEntry>* bookmarks);
double chromeTimeToDouble(int64_t time);
base::FilePath source_path_;
DISALLOW_COPY_AND_ASSIGN(BraveImporter);
};
#endif // BRAVE_UTILITY_IMPORTER_BRAVE_IMPORTER_H_
+211
View File
@@ -0,0 +1,211 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "brave/utility/importer/brave_importer.h"
#include "brave/common/brave_paths.h"
#include "brave/common/importer/brave_mock_importer_bridge.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/utf_string_conversions.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/importer/imported_bookmark_entry.h"
#include "chrome/common/importer/importer_data_types.h"
#include "chrome/common/importer/importer_url_row.h"
#include "chrome/common/importer/mock_importer_bridge.h"
#include "components/favicon_base/favicon_usage_data.h"
#include "components/os_crypt/os_crypt_mocker.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
using base::UTF16ToASCII;
using ::testing::_;
// In order to test the Brave import functionality effectively, we store a
// simulated Brave profile directory containing dummy data files with the
// same structure as ~/Library/Application Support/brave in the Brave
// test data directory. This function returns the path to that directory.
base::FilePath GetTestBraveProfileDir(const std::string& profile) {
base::FilePath test_dir;
PathService::Get(brave::DIR_TEST_DATA, &test_dir);
return test_dir.AppendASCII("import").AppendASCII("brave-browser-laptop")
.AppendASCII(profile);
}
class BraveImporterTest : public ::testing::Test {
protected:
void SetUpBraveProfile() {
// Creates a new profile in a new subdirectory in the temp directory.
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base::FilePath test_path = temp_dir_.GetPath().AppendASCII("BraveImporterTest");
base::DeleteFile(test_path, true);
base::CreateDirectory(test_path);
profile_dir_ = test_path.AppendASCII("profile");
base::FilePath data_dir = GetTestBraveProfileDir("default");
ASSERT_TRUE(base::DirectoryExists(data_dir));
ASSERT_TRUE(base::CopyDirectory(data_dir, profile_dir_, true));
profile_.source_path = profile_dir_;
}
void SetUp() override {
SetUpBraveProfile();
importer_ = new BraveImporter;
bridge_ = new BraveMockImporterBridge;
}
base::ScopedTempDir temp_dir_;
base::FilePath profile_dir_;
importer::SourceProfile profile_;
scoped_refptr<BraveImporter> importer_;
scoped_refptr<BraveMockImporterBridge> bridge_;
};
TEST_F(BraveImporterTest, ImportHistory) {
std::vector<ImporterURLRow> history;
EXPECT_CALL(*bridge_, NotifyStarted());
EXPECT_CALL(*bridge_, NotifyItemStarted(importer::HISTORY));
EXPECT_CALL(*bridge_, SetHistoryItems(_, _))
.WillOnce(::testing::SaveArg<0>(&history));
EXPECT_CALL(*bridge_, NotifyItemEnded(importer::HISTORY));
EXPECT_CALL(*bridge_, NotifyEnded());
importer_->StartImport(profile_, importer::HISTORY, bridge_.get());
// There are 17 history entries in the test History sqlite db, but 7
// of them are internal URLs with a chrome-extension:// scheme, so
// they should be filtered out by CanImportURL.
ASSERT_EQ(10u, history.size());
// After some initial chrome-extension:// URLs, which should be
// filtered out, the first importable url should be
// https://brave.com.
EXPECT_EQ("https://brave.com/", history[0].url.spec());
}
TEST_F(BraveImporterTest, ImportBookmarks) {
std::vector<ImportedBookmarkEntry> bookmarks;
EXPECT_CALL(*bridge_, NotifyStarted());
EXPECT_CALL(*bridge_, NotifyItemStarted(importer::FAVORITES));
EXPECT_CALL(*bridge_, AddBookmarks(_, _))
.WillOnce(::testing::SaveArg<0>(&bookmarks));
EXPECT_CALL(*bridge_, NotifyItemEnded(importer::FAVORITES));
EXPECT_CALL(*bridge_, NotifyEnded());
importer_->StartImport(profile_, importer::FAVORITES, bridge_.get());
ASSERT_EQ(6u, bookmarks.size());
EXPECT_EQ(ASCIIToUTF16("Nested Folder 2 (Empty)"), bookmarks[0].title);
EXPECT_EQ(2u, bookmarks[0].path.size());
EXPECT_EQ(ASCIIToUTF16("Bookmarks Toolbar"), bookmarks[0].path[0]);
EXPECT_EQ(ASCIIToUTF16("Nested Folder 1"), bookmarks[0].path[1]);
EXPECT_TRUE(bookmarks[0].in_toolbar);
EXPECT_TRUE(bookmarks[0].is_folder);
EXPECT_EQ(ASCIIToUTF16("Features | Brave Browser"), bookmarks[1].title);
EXPECT_EQ("https://brave.com/features/", bookmarks[1].url.spec());
EXPECT_EQ(2u, bookmarks[1].path.size());
EXPECT_EQ(ASCIIToUTF16("Bookmarks Toolbar"), bookmarks[1].path[0]);
EXPECT_EQ(ASCIIToUTF16("Nested Folder 1"), bookmarks[1].path[1]);
EXPECT_TRUE(bookmarks[1].in_toolbar);
EXPECT_FALSE(bookmarks[1].is_folder);
EXPECT_EQ(ASCIIToUTF16(
"Secure, Fast & Private Web Browser with Adblocker | Brave Browser"),
bookmarks[2].title);
EXPECT_EQ("https://brave.com/", bookmarks[2].url.spec());
EXPECT_EQ(1u, bookmarks[2].path.size());
EXPECT_EQ(ASCIIToUTF16("Bookmarks Toolbar"), bookmarks[2].path[0]);
EXPECT_TRUE(bookmarks[2].in_toolbar);
EXPECT_FALSE(bookmarks[2].is_folder);
EXPECT_EQ(ASCIIToUTF16("Nested Folder 2 (Empty)"), bookmarks[3].title);
EXPECT_EQ(2u, bookmarks[3].path.size());
EXPECT_EQ(ASCIIToUTF16("Other Bookmarks"), bookmarks[3].path[0]);
EXPECT_EQ(ASCIIToUTF16("Nested Folder 1"), bookmarks[3].path[1]);
EXPECT_FALSE(bookmarks[3].in_toolbar);
EXPECT_TRUE(bookmarks[3].is_folder);
EXPECT_EQ(ASCIIToUTF16(
"Blog About Privacy, Adblocks & Best Browsers | Brave Browser"),
bookmarks[4].title);
EXPECT_EQ(2u, bookmarks[4].path.size());
EXPECT_EQ(ASCIIToUTF16("Other Bookmarks"), bookmarks[4].path[0]);
EXPECT_EQ(ASCIIToUTF16("Nested Folder 1"), bookmarks[4].path[1]);
EXPECT_FALSE(bookmarks[4].in_toolbar);
EXPECT_FALSE(bookmarks[4].is_folder);
EXPECT_EQ(ASCIIToUTF16(
"Make Money as a Publisher with Brave Payments | Brave Browser"),
bookmarks[5].title);
EXPECT_EQ(1u, bookmarks[5].path.size());
EXPECT_EQ(ASCIIToUTF16("Other Bookmarks"), bookmarks[5].path[0]);
EXPECT_FALSE(bookmarks[5].in_toolbar);
EXPECT_FALSE(bookmarks[5].is_folder);
}
// The mock keychain only works on macOS, so only run this test on macOS (for now)
#if defined(OS_MACOSX)
TEST_F(BraveImporterTest, ImportPasswords) {
// Use mock keychain on mac to prevent blocking permissions dialogs.
OSCryptMocker::SetUp();
autofill::PasswordForm autofillable_login;
autofill::PasswordForm blacklisted_login;
EXPECT_CALL(*bridge_, NotifyStarted());
EXPECT_CALL(*bridge_, NotifyItemStarted(importer::PASSWORDS));
EXPECT_CALL(*bridge_, SetPasswordForm(_))
.WillOnce(::testing::SaveArg<0>(&autofillable_login))
.WillOnce(::testing::SaveArg<0>(&blacklisted_login));
EXPECT_CALL(*bridge_, NotifyItemEnded(importer::PASSWORDS));
EXPECT_CALL(*bridge_, NotifyEnded());
importer_->StartImport(profile_, importer::PASSWORDS, bridge_.get());
EXPECT_FALSE(autofillable_login.blacklisted_by_user);
EXPECT_EQ("http://127.0.0.1:8080/",
autofillable_login.signon_realm);
EXPECT_EQ("test_username",
UTF16ToASCII(autofillable_login.username_value));
EXPECT_EQ("test_password",
UTF16ToASCII(autofillable_login.password_value));
EXPECT_TRUE(blacklisted_login.blacklisted_by_user);
EXPECT_EQ("http://127.0.0.1:8081/",
blacklisted_login.signon_realm);
EXPECT_EQ("", UTF16ToASCII(blacklisted_login.username_value));
EXPECT_EQ("", UTF16ToASCII(blacklisted_login.password_value));
OSCryptMocker::TearDown();
}
TEST_F(BraveImporterTest, ImportCookies) {
OSCryptMocker::SetUp();
std::vector<net::CanonicalCookie> cookies;
EXPECT_CALL(*bridge_, NotifyStarted());
EXPECT_CALL(*bridge_, NotifyItemStarted(importer::COOKIES));
EXPECT_CALL(*bridge_, SetCookies(_))
.WillOnce(::testing::SaveArg<0>(&cookies));
EXPECT_CALL(*bridge_, NotifyItemEnded(importer::COOKIES));
EXPECT_CALL(*bridge_, NotifyEnded());
importer_->StartImport(profile_, importer::COOKIES, bridge_.get());
ASSERT_EQ(1u, cookies.size());
EXPECT_EQ("localhost", cookies[0].Domain());
EXPECT_EQ("test", cookies[0].Name());
EXPECT_EQ("test", cookies[0].Value());
OSCryptMocker::TearDown();
}
#endif
+9 -10
View File
@@ -30,7 +30,7 @@
#include "components/prefs/pref_filter.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.cc"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
#include "sql/connection.h"
#include "sql/statement.h"
#include "url/gurl.h"
@@ -410,16 +410,17 @@ void ChromeImporter::ImportCookies() {
sql::Statement s(db.GetUniqueStatement(query));
net::CookieCryptoDelegate* delegate =
cookie_config::GetCookieCryptoDelegate();
#if defined(OS_LINUX)
OSCrypt::SetConfig(std::make_unique<os_crypt::Config>());
#endif
std::vector<net::CanonicalCookie> cookies;
while (s.Step() && !cancelled()) {
std::string encrypted_value = s.ColumnString(4);
net::CookieCryptoDelegate* delegate =
cookie_config::GetCookieCryptoDelegate();
std::string value;
if (!encrypted_value.empty() && delegate) {
#if defined(OS_LINUX)
OSCrypt::SetConfig(std::make_unique<os_crypt::Config>());
#endif
if (!delegate->DecryptString(encrypted_value, &value)) {
continue;
}
@@ -437,10 +438,8 @@ void ChromeImporter::ImportCookies() {
Time::FromInternalValue(s.ColumnInt64(10)), // last_access_utc
s.ColumnBool(7), // secure
s.ColumnBool(8), // http_only
DBCookieSameSiteToCookieSameSite( // samesite
static_cast<net::DBCookieSameSite>(s.ColumnInt(9))),
DBCookiePriorityToCookiePriority( // priority
static_cast<net::DBCookiePriority>(s.ColumnInt(13))));
static_cast<net::CookieSameSite>(s.ColumnInt(9)), // samesite
static_cast<net::CookiePriority>(s.ColumnInt(13))); // priority
if (cookie.IsCanonical()) {
cookies.push_back(cookie);
}