Chromium Code Reviews| 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 |