OLD | NEW |
---|---|
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/chromeos/app_mode/kiosk_app_manager.h" | 5 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
(...skipping 17 matching lines...) Expand all Loading... | |
28 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 28 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
29 #include "chrome/browser/chromeos/policy/device_local_account.h" | 29 #include "chrome/browser/chromeos/policy/device_local_account.h" |
30 #include "chrome/browser/chromeos/settings/cros_settings.h" | 30 #include "chrome/browser/chromeos/settings/cros_settings.h" |
31 #include "chrome/browser/extensions/external_loader.h" | 31 #include "chrome/browser/extensions/external_loader.h" |
32 #include "chrome/browser/extensions/external_provider_impl.h" | 32 #include "chrome/browser/extensions/external_provider_impl.h" |
33 #include "chrome/browser/lifetime/application_lifetime.h" | 33 #include "chrome/browser/lifetime/application_lifetime.h" |
34 #include "chrome/common/chrome_paths.h" | 34 #include "chrome/common/chrome_paths.h" |
35 #include "chrome/common/extensions/extension_constants.h" | 35 #include "chrome/common/extensions/extension_constants.h" |
36 #include "chromeos/chromeos_paths.h" | 36 #include "chromeos/chromeos_paths.h" |
37 #include "chromeos/cryptohome/async_method_caller.h" | 37 #include "chromeos/cryptohome/async_method_caller.h" |
38 #include "chromeos/cryptohome/cryptohome_parameters.h" | |
38 #include "chromeos/dbus/dbus_thread_manager.h" | 39 #include "chromeos/dbus/dbus_thread_manager.h" |
39 #include "chromeos/settings/cros_settings_names.h" | 40 #include "chromeos/settings/cros_settings_names.h" |
40 #include "components/ownership/owner_key_util.h" | 41 #include "components/ownership/owner_key_util.h" |
41 #include "components/prefs/pref_registry_simple.h" | 42 #include "components/prefs/pref_registry_simple.h" |
42 #include "components/prefs/pref_service.h" | 43 #include "components/prefs/pref_service.h" |
43 #include "components/prefs/scoped_user_pref_update.h" | 44 #include "components/prefs/scoped_user_pref_update.h" |
44 #include "components/signin/core/account_id/account_id.h" | 45 #include "components/signin/core/account_id/account_id.h" |
46 #include "components/user_manager/known_user.h" | |
45 #include "components/user_manager/user_manager.h" | 47 #include "components/user_manager/user_manager.h" |
46 #include "content/public/browser/browser_thread.h" | 48 #include "content/public/browser/browser_thread.h" |
47 #include "extensions/common/extension_urls.h" | 49 #include "extensions/common/extension_urls.h" |
48 | 50 |
49 namespace chromeos { | 51 namespace chromeos { |
50 | 52 |
51 namespace { | 53 namespace { |
52 | 54 |
53 // Domain that is used for kiosk-app account IDs. | 55 // Domain that is used for kiosk-app account IDs. |
54 const char kKioskAppAccountDomain[] = "kiosk-apps"; | 56 const char kKioskAppAccountDomain[] = "kiosk-apps"; |
55 | 57 |
56 // Preference for the dictionary of user ids for which cryptohomes have to be | 58 // Preference for the dictionary of user ids for which cryptohomes have to be |
57 // removed upon browser restart. | 59 // removed upon browser restart. |
58 const char kKioskUsersToRemove[] = "kiosk-users-to-remove"; | 60 const char kKioskUsersToRemove[] = "kiosk-users-to-remove"; |
59 | 61 |
60 std::string GenerateKioskAppAccountId(const std::string& app_id) { | 62 std::string GenerateKioskAppAccountId(const std::string& app_id) { |
61 return app_id + '@' + kKioskAppAccountDomain; | 63 return app_id + '@' + kKioskAppAccountDomain; |
62 } | 64 } |
63 | 65 |
64 void ScheduleDelayedCryptohomeRemoval(const std::string& user_id, | 66 void ScheduleDelayedCryptohomeRemoval(const AccountId& account_id, |
65 const std::string& app_id) { | 67 const std::string& app_id) { |
66 PrefService* local_state = g_browser_process->local_state(); | 68 PrefService* local_state = g_browser_process->local_state(); |
67 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); | 69 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); |
68 dict_update->SetStringWithoutPathExpansion(user_id, app_id); | 70 dict_update->SetStringWithoutPathExpansion(account_id.Serialize(), app_id); |
xiyuan
2016/02/17 23:14:25
The comment for Serialize() in account_id.h says:
Alexander Alekseev
2016/02/18 13:45:14
You're right. We should not use it here. I've repl
| |
69 local_state->CommitPendingWrite(); | 71 local_state->CommitPendingWrite(); |
70 } | 72 } |
71 | 73 |
72 void CancelDelayedCryptohomeRemoval(const std::string& user_id) { | 74 void CancelDelayedCryptohomeRemoval(const AccountId& account_id) { |
73 PrefService* local_state = g_browser_process->local_state(); | 75 PrefService* local_state = g_browser_process->local_state(); |
74 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); | 76 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); |
75 dict_update->RemoveWithoutPathExpansion(user_id, NULL); | 77 dict_update->RemoveWithoutPathExpansion(account_id.Serialize(), NULL); |
78 const std::string& old_user_id = account_id.GetUserEmail(); // Migrated | |
79 dict_update->RemoveWithoutPathExpansion(old_user_id, NULL); | |
76 local_state->CommitPendingWrite(); | 80 local_state->CommitPendingWrite(); |
77 } | 81 } |
78 | 82 |
79 void OnRemoveAppCryptohomeComplete(const std::string& user_id, | 83 void OnRemoveAppCryptohomeComplete(const AccountId& account_id, |
80 const std::string& app, | 84 const std::string& app, |
81 const base::Closure& callback, | 85 const base::Closure& callback, |
82 bool success, | 86 bool success, |
83 cryptohome::MountError return_code) { | 87 cryptohome::MountError return_code) { |
84 if (success) { | 88 if (success) { |
85 CancelDelayedCryptohomeRemoval(user_id); | 89 CancelDelayedCryptohomeRemoval(account_id); |
86 } else { | 90 } else { |
87 ScheduleDelayedCryptohomeRemoval(user_id, app); | 91 ScheduleDelayedCryptohomeRemoval(account_id, app); |
88 LOG(ERROR) << "Remove cryptohome for " << app | 92 LOG(ERROR) << "Remove cryptohome for " << app |
89 << " failed, return code: " << return_code; | 93 << " failed, return code: " << return_code; |
90 } | 94 } |
91 if (!callback.is_null()) | 95 if (!callback.is_null()) |
92 callback.Run(); | 96 callback.Run(); |
93 } | 97 } |
94 | 98 |
95 void PerformDelayedCryptohomeRemovals(bool service_is_available) { | 99 void PerformDelayedCryptohomeRemovals(bool service_is_available) { |
96 if (!service_is_available) { | 100 if (!service_is_available) { |
97 LOG(ERROR) << "Crypthomed is not available."; | 101 LOG(ERROR) << "Crypthomed is not available."; |
98 return; | 102 return; |
99 } | 103 } |
100 | 104 |
101 PrefService* local_state = g_browser_process->local_state(); | 105 PrefService* local_state = g_browser_process->local_state(); |
102 const base::DictionaryValue* dict = | 106 const base::DictionaryValue* dict = |
103 local_state->GetDictionary(kKioskUsersToRemove); | 107 local_state->GetDictionary(kKioskUsersToRemove); |
104 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { | 108 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { |
105 std::string user_id = it.key(); | 109 std::string user_id = it.key(); |
110 const AccountId account_id( | |
111 user_manager::known_user::MayBeDeserializeAccountId(user_id)); | |
106 std::string app_id; | 112 std::string app_id; |
107 it.value().GetAsString(&app_id); | 113 it.value().GetAsString(&app_id); |
108 VLOG(1) << "Removing obsolete crypthome for " << app_id; | 114 VLOG(1) << "Removing obsolete crypthome for " << app_id; |
109 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 115 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
110 user_id, | 116 cryptohome::Identification(account_id), |
111 base::Bind(&OnRemoveAppCryptohomeComplete, | 117 base::Bind(&OnRemoveAppCryptohomeComplete, account_id, app_id, |
112 user_id, | |
113 app_id, | |
114 base::Closure())); | 118 base::Closure())); |
115 } | 119 } |
116 } | 120 } |
117 | 121 |
118 // Check for presence of machine owner public key file. | 122 // Check for presence of machine owner public key file. |
119 void CheckOwnerFilePresence(bool *present) { | 123 void CheckOwnerFilePresence(bool *present) { |
120 scoped_refptr<ownership::OwnerKeyUtil> util = | 124 scoped_refptr<ownership::OwnerKeyUtil> util = |
121 OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil(); | 125 OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil(); |
122 *present = util.get() && util->IsPublicKeyPresent(); | 126 *present = util.get() && util->IsPublicKeyPresent(); |
123 } | 127 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 } | 164 } |
161 | 165 |
162 // static | 166 // static |
163 void KioskAppManager::RemoveObsoleteCryptohomes() { | 167 void KioskAppManager::RemoveObsoleteCryptohomes() { |
164 chromeos::CryptohomeClient* client = | 168 chromeos::CryptohomeClient* client = |
165 chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); | 169 chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); |
166 client->WaitForServiceToBeAvailable( | 170 client->WaitForServiceToBeAvailable( |
167 base::Bind(&PerformDelayedCryptohomeRemovals)); | 171 base::Bind(&PerformDelayedCryptohomeRemovals)); |
168 } | 172 } |
169 | 173 |
170 KioskAppManager::App::App( | 174 KioskAppManager::App::App(const KioskAppData& data, |
171 const KioskAppData& data, | 175 bool is_extension_pending, |
172 bool is_extension_pending, | 176 bool auto_launched_with_zero_delay) |
173 bool auto_launched_with_zero_delay) | |
174 : app_id(data.app_id()), | 177 : app_id(data.app_id()), |
175 user_id(data.user_id()), | 178 account_id(data.account_id()), |
176 name(data.name()), | 179 name(data.name()), |
177 icon(data.icon()), | 180 icon(data.icon()), |
178 is_loading(data.IsLoading() || is_extension_pending), | 181 is_loading(data.IsLoading() || is_extension_pending), |
179 was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) { | 182 was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) {} |
180 } | |
181 | 183 |
182 KioskAppManager::App::App() : is_loading(false), | 184 KioskAppManager::App::App() |
183 was_auto_launched_with_zero_delay(false) {} | 185 : account_id(EmptyAccountId()), |
186 is_loading(false), | |
187 was_auto_launched_with_zero_delay(false) {} | |
184 | 188 |
185 KioskAppManager::App::~App() {} | 189 KioskAppManager::App::~App() {} |
186 | 190 |
187 std::string KioskAppManager::GetAutoLaunchApp() const { | 191 std::string KioskAppManager::GetAutoLaunchApp() const { |
188 return auto_launch_app_id_; | 192 return auto_launch_app_id_; |
189 } | 193 } |
190 | 194 |
191 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id, | 195 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id, |
192 OwnerSettingsServiceChromeOS* service) { | 196 OwnerSettingsServiceChromeOS* service) { |
193 SetAutoLoginState(AUTOLOGIN_REQUESTED); | 197 SetAutoLoginState(AUTOLOGIN_REQUESTED); |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 policy::GetDeviceLocalAccounts(CrosSettings::Get()); | 631 policy::GetDeviceLocalAccounts(CrosSettings::Get()); |
628 for (std::vector<policy::DeviceLocalAccount>::const_iterator | 632 for (std::vector<policy::DeviceLocalAccount>::const_iterator |
629 it = device_local_accounts.begin(); | 633 it = device_local_accounts.begin(); |
630 it != device_local_accounts.end(); ++it) { | 634 it != device_local_accounts.end(); ++it) { |
631 if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) | 635 if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) |
632 continue; | 636 continue; |
633 | 637 |
634 if (it->account_id == auto_login_account_id) | 638 if (it->account_id == auto_login_account_id) |
635 auto_launch_app_id_ = it->kiosk_app_id; | 639 auto_launch_app_id_ = it->kiosk_app_id; |
636 | 640 |
641 const AccountId account_id(AccountId::FromUserEmail(it->user_id)); | |
xiyuan
2016/02/17 23:14:25
Note it->user_id could be an arbitrary string set
Alexander Alekseev
2016/02/18 13:45:14
It cannot be completely arbitrary, because we use
xiyuan
2016/02/18 17:22:33
I am not objecting to the change. Just want to poi
Alexander Alekseev
2016/02/19 00:17:03
You're right. But it still looks like email. It ca
| |
637 std::map<std::string, KioskAppData*>::iterator old_it = | 642 std::map<std::string, KioskAppData*>::iterator old_it = |
638 old_apps.find(it->kiosk_app_id); | 643 old_apps.find(it->kiosk_app_id); |
639 if (old_it != old_apps.end()) { | 644 if (old_it != old_apps.end()) { |
640 apps_.push_back(old_it->second); | 645 apps_.push_back(old_it->second); |
641 old_apps.erase(old_it); | 646 old_apps.erase(old_it); |
642 } else { | 647 } else { |
643 KioskAppData* new_app = new KioskAppData( | 648 KioskAppData* new_app = new KioskAppData( |
644 this, it->kiosk_app_id, it->user_id, GURL(it->kiosk_app_update_url)); | 649 this, it->kiosk_app_id, account_id, GURL(it->kiosk_app_update_url)); |
645 apps_.push_back(new_app); // Takes ownership of |new_app|. | 650 apps_.push_back(new_app); // Takes ownership of |new_app|. |
646 new_app->Load(); | 651 new_app->Load(); |
647 } | 652 } |
648 CancelDelayedCryptohomeRemoval(it->user_id); | 653 CancelDelayedCryptohomeRemoval(account_id); |
649 } | 654 } |
650 | 655 |
651 base::Closure cryptohomes_barrier_closure; | 656 base::Closure cryptohomes_barrier_closure; |
652 | 657 |
653 const user_manager::User* active_user = | 658 const user_manager::User* active_user = |
654 user_manager::UserManager::Get()->GetActiveUser(); | 659 user_manager::UserManager::Get()->GetActiveUser(); |
655 if (active_user) { | 660 if (active_user) { |
656 const AccountId active_account_id = active_user->GetAccountId(); | 661 const AccountId active_account_id = active_user->GetAccountId(); |
657 for (const auto& it : old_apps) { | 662 for (const auto& it : old_apps) { |
658 if (it.second->user_id() == active_account_id.GetUserEmail()) { | 663 if (it.second->account_id() == active_account_id) { |
659 VLOG(1) << "Currently running kiosk app removed from policy, exiting"; | 664 VLOG(1) << "Currently running kiosk app removed from policy, exiting"; |
660 cryptohomes_barrier_closure = BarrierClosure( | 665 cryptohomes_barrier_closure = BarrierClosure( |
661 old_apps.size(), base::Bind(&chrome::AttemptUserExit)); | 666 old_apps.size(), base::Bind(&chrome::AttemptUserExit)); |
662 break; | 667 break; |
663 } | 668 } |
664 } | 669 } |
665 } | 670 } |
666 | 671 |
667 // Clears cache and deletes the remaining old data. | 672 // Clears cache and deletes the remaining old data. |
668 std::vector<std::string> apps_to_remove; | 673 std::vector<std::string> apps_to_remove; |
669 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); | 674 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); |
670 it != old_apps.end(); ++it) { | 675 it != old_apps.end(); ++it) { |
671 it->second->ClearCache(); | 676 it->second->ClearCache(); |
672 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 677 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
673 it->second->user_id(), | 678 cryptohome::Identification(it->second->account_id()), |
674 base::Bind(&OnRemoveAppCryptohomeComplete, | 679 base::Bind(&OnRemoveAppCryptohomeComplete, it->second->account_id(), |
675 it->second->user_id(), | 680 it->first, cryptohomes_barrier_closure)); |
676 it->first, | |
677 cryptohomes_barrier_closure)); | |
678 apps_to_remove.push_back(it->second->app_id()); | 681 apps_to_remove.push_back(it->second->app_id()); |
679 } | 682 } |
680 STLDeleteValues(&old_apps); | 683 STLDeleteValues(&old_apps); |
681 external_cache_->RemoveExtensions(apps_to_remove); | 684 external_cache_->RemoveExtensions(apps_to_remove); |
682 | 685 |
683 // Request external_cache_ to download new apps and update the existing | 686 // Request external_cache_ to download new apps and update the existing |
684 // apps. | 687 // apps. |
685 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); | 688 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); |
686 for (size_t i = 0; i < apps_.size(); ++i) { | 689 for (size_t i = 0; i < apps_.size(); ++i) { |
687 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); | 690 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
778 *cache_dir = user_data_dir.AppendASCII(kCrxCacheDir); | 781 *cache_dir = user_data_dir.AppendASCII(kCrxCacheDir); |
779 } | 782 } |
780 | 783 |
781 void KioskAppManager::GetCrxUnpackDir(base::FilePath* unpack_dir) { | 784 void KioskAppManager::GetCrxUnpackDir(base::FilePath* unpack_dir) { |
782 base::FilePath temp_dir; | 785 base::FilePath temp_dir; |
783 base::GetTempDir(&temp_dir); | 786 base::GetTempDir(&temp_dir); |
784 *unpack_dir = temp_dir.AppendASCII(kCrxUnpackDir); | 787 *unpack_dir = temp_dir.AppendASCII(kCrxUnpackDir); |
785 } | 788 } |
786 | 789 |
787 } // namespace chromeos | 790 } // namespace chromeos |
OLD | NEW |