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

Side by Side Diff: chrome/browser/password_manager/password_store_proxy_mac.cc

Issue 1213043003: Start the migration of passwords from the Keychain. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move the enum Created 5 years, 5 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/password_manager/password_store_proxy_mac.h" 5 #include "chrome/browser/password_manager/password_store_proxy_mac.h"
6 6
7 #include "base/metrics/histogram_macros.h"
7 #include "chrome/browser/password_manager/password_store_mac.h" 8 #include "chrome/browser/password_manager/password_store_mac.h"
8 #include "chrome/browser/password_manager/simple_password_store_mac.h" 9 #include "chrome/browser/password_manager/simple_password_store_mac.h"
9 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
10 #include "crypto/apple_keychain.h" 11 #include "crypto/apple_keychain.h"
11 12
13 using password_manager::MigrationStatus;
12 using password_manager::PasswordStoreChangeList; 14 using password_manager::PasswordStoreChangeList;
13 15
14 PasswordStoreProxyMac::PasswordStoreProxyMac( 16 PasswordStoreProxyMac::PasswordStoreProxyMac(
15 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, 17 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
16 scoped_ptr<crypto::AppleKeychain> keychain, 18 scoped_ptr<crypto::AppleKeychain> keychain,
17 scoped_ptr<password_manager::LoginDatabase> login_db) 19 scoped_ptr<password_manager::LoginDatabase> login_db,
20 PrefService* prefs)
18 : PasswordStore(main_thread_runner, nullptr), 21 : PasswordStore(main_thread_runner, nullptr),
19 login_metadata_db_(login_db.Pass()) { 22 login_metadata_db_(login_db.Pass()) {
20 DCHECK(login_metadata_db_); 23 DCHECK(login_metadata_db_);
21 // TODO(vasilii): for now the class is just a wrapper around PasswordStoreMac. 24 migration_status_.Init(password_manager::prefs::kKeychainMigrationStatus,
22 password_store_mac_ = 25 prefs);
23 new PasswordStoreMac(main_thread_runner, nullptr, keychain.Pass()); 26 if (migration_status_.GetValue() ==
27 static_cast<int>(MigrationStatus::MIGRATED)) {
28 // The login database will be set later after initialization.
29 password_store_simple_ =
30 new SimplePasswordStoreMac(main_thread_runner, nullptr, nullptr);
31 } else {
32 password_store_mac_ =
33 new PasswordStoreMac(main_thread_runner, nullptr, keychain.Pass());
34 }
24 } 35 }
25 36
26 PasswordStoreProxyMac::~PasswordStoreProxyMac() { 37 PasswordStoreProxyMac::~PasswordStoreProxyMac() {
27 } 38 }
28 39
29 bool PasswordStoreProxyMac::Init( 40 bool PasswordStoreProxyMac::Init(
30 const syncer::SyncableService::StartSyncFlare& flare) { 41 const syncer::SyncableService::StartSyncFlare& flare) {
31 // Set up a background thread. 42 // Set up a background thread.
32 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 43 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
33 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread")); 44 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
34 45
35 if (!thread_->Start()) { 46 if (!thread_->Start()) {
36 thread_.reset(); 47 thread_.reset();
37 return false; 48 return false;
38 } 49 }
39 50
40 ScheduleTask( 51 if (!password_manager::PasswordStore::Init(flare))
41 base::Bind(&PasswordStoreProxyMac::InitOnBackgroundThread, this)); 52 return false;
42 password_store_mac_->InitWithTaskRunner(GetBackgroundTaskRunner()); 53
43 return password_manager::PasswordStore::Init(flare); 54 return ScheduleTask(
55 base::Bind(&PasswordStoreProxyMac::InitOnBackgroundThread, this,
56 static_cast<MigrationStatus>(migration_status_.GetValue())));
44 } 57 }
45 58
46 void PasswordStoreProxyMac::Shutdown() { 59 void PasswordStoreProxyMac::Shutdown() {
47 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 60 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
48 PasswordStore::Shutdown(); 61 PasswordStore::Shutdown();
62 thread_->Stop();
63
64 // Execute the task which are still pending.
65 FlushPendingTasks();
66
67 // Unsubscribe the observer, otherwise it's too late in the destructor.
68 migration_status_.Destroy();
69
70 // After the thread has stopped it's impossible to switch from one backend to
71 // another. GetBackend() returns the correct result.
49 GetBackend()->Shutdown(); 72 GetBackend()->Shutdown();
50 thread_->Stop();
51 } 73 }
52 74
53 scoped_refptr<base::SingleThreadTaskRunner> 75 scoped_refptr<base::SingleThreadTaskRunner>
54 PasswordStoreProxyMac::GetBackgroundTaskRunner() { 76 PasswordStoreProxyMac::GetBackgroundTaskRunner() {
55 return thread_ ? thread_->task_runner() : nullptr; 77 return thread_ ? thread_->task_runner() : nullptr;
56 } 78 }
57 79
58 password_manager::PasswordStore* PasswordStoreProxyMac::GetBackend() const { 80 password_manager::PasswordStore* PasswordStoreProxyMac::GetBackend() const {
59 if (password_store_mac_) 81 if (password_store_mac_)
60 return password_store_mac_.get(); 82 return password_store_mac_.get();
61 return password_store_simple_.get(); 83 return password_store_simple_.get();
62 } 84 }
63 85
64 void PasswordStoreProxyMac::InitOnBackgroundThread() { 86 void PasswordStoreProxyMac::InitOnBackgroundThread(MigrationStatus status) {
65 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); 87 DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
66 if (!login_metadata_db_->Init()) { 88 if (!login_metadata_db_->Init()) {
67 login_metadata_db_.reset(); 89 login_metadata_db_.reset();
68 LOG(ERROR) << "Could not create/open login database."; 90 LOG(ERROR) << "Could not create/open login database.";
69 return;
70 } 91 }
71 if (password_store_mac_) 92
93 if (status == MigrationStatus::MIGRATED) {
94 password_store_simple_->InitWithTaskRunner(GetBackgroundTaskRunner(),
95 login_metadata_db_.Pass());
96 } else {
72 password_store_mac_->set_login_metadata_db(login_metadata_db_.get()); 97 password_store_mac_->set_login_metadata_db(login_metadata_db_.get());
98 password_store_mac_->InitWithTaskRunner(GetBackgroundTaskRunner());
99 if (login_metadata_db_ && (status == MigrationStatus::NOT_STARTED ||
100 status == MigrationStatus::FAILED_ONCE)) {
101 // Let's try to migrate the passwords.
102 if (password_store_mac_->ImportFromKeychain() ==
103 PasswordStoreMac::MIGRATION_OK) {
104 status = MigrationStatus::MIGRATED;
105 // Switch from |password_store_mac_| to |password_store_simple_|.
106 password_store_mac_->set_login_metadata_db(nullptr);
107 pending_ui_tasks_.push_back(
108 base::Bind(&PasswordStoreMac::Shutdown, password_store_mac_));
109 password_store_mac_ = nullptr;
110 password_store_simple_ = new SimplePasswordStoreMac(
stuartmorgan 2015/07/07 17:40:25 Just to be safe (since the logic that creates this
vasilii 2015/07/08 09:56:58 Done.
111 main_thread_runner_, GetBackgroundTaskRunner(),
112 login_metadata_db_.Pass());
113 } else {
114 status = (status == MigrationStatus::FAILED_ONCE
115 ? MigrationStatus::FAILED_TWICE
116 : MigrationStatus::FAILED_ONCE);
117 }
118 pending_ui_tasks_.push_back(
119 base::Bind(&PasswordStoreProxyMac::UpdateStatusPref, this, status));
stuartmorgan 2015/07/07 17:40:25 Given that there's a race where the login DB could
vasilii 2015/07/08 09:56:58 There is no race. The preference is written in Pas
stuartmorgan 2015/07/08 14:18:40 I meant in case of a crash; there's a window of ti
vasilii 2015/07/08 15:45:54 I think it's rare and on the next run the password
120 }
121 }
122 if (!pending_ui_tasks_.empty()) {
123 main_thread_runner_->PostTask(
124 FROM_HERE, base::Bind(&PasswordStoreProxyMac::FlushPendingTasks, this));
125 }
126 UMA_HISTOGRAM_ENUMERATION(
127 "PasswordManager.KeychainMigration.Status", static_cast<int>(status),
128 static_cast<int>(MigrationStatus::MIGRATION_STATUS_COUNT));
129 DCHECK(GetBackend());
130 }
131
132 void PasswordStoreProxyMac::UpdateStatusPref(MigrationStatus status) {
133 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
134 migration_status_.SetValue(static_cast<int>(status));
135 }
136
137 void PasswordStoreProxyMac::FlushPendingTasks() {
138 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
139 for (auto& task : pending_ui_tasks_)
140 task.Run();
141 pending_ui_tasks_.clear();
73 } 142 }
74 143
75 void PasswordStoreProxyMac::ReportMetricsImpl( 144 void PasswordStoreProxyMac::ReportMetricsImpl(
76 const std::string& sync_username, 145 const std::string& sync_username,
77 bool custom_passphrase_sync_enabled) { 146 bool custom_passphrase_sync_enabled) {
78 GetBackend()->ReportMetricsImpl(sync_username, 147 GetBackend()->ReportMetricsImpl(sync_username,
79 custom_passphrase_sync_enabled); 148 custom_passphrase_sync_enabled);
80 } 149 }
81 150
82 PasswordStoreChangeList PasswordStoreProxyMac::AddLoginImpl( 151 PasswordStoreChangeList PasswordStoreProxyMac::AddLoginImpl(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 197 }
129 198
130 void PasswordStoreProxyMac::RemoveSiteStatsImpl(const GURL& origin_domain) { 199 void PasswordStoreProxyMac::RemoveSiteStatsImpl(const GURL& origin_domain) {
131 GetBackend()->RemoveSiteStatsImpl(origin_domain); 200 GetBackend()->RemoveSiteStatsImpl(origin_domain);
132 } 201 }
133 202
134 scoped_ptr<password_manager::InteractionsStats> 203 scoped_ptr<password_manager::InteractionsStats>
135 PasswordStoreProxyMac::GetSiteStatsImpl(const GURL& origin_domain) { 204 PasswordStoreProxyMac::GetSiteStatsImpl(const GURL& origin_domain) {
136 return GetBackend()->GetSiteStatsImpl(origin_domain); 205 return GetBackend()->GetSiteStatsImpl(origin_domain);
137 } 206 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698