Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/login/user_manager_impl.h" | 5 #include "chrome/browser/chromeos/login/user_manager_impl.h" |
| 6 | 6 |
| 7 #include <cstddef> | 7 #include <cstddef> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 void OnRemoveUserComplete(const std::string& user_email, | 119 void OnRemoveUserComplete(const std::string& user_email, |
| 120 bool success, | 120 bool success, |
| 121 cryptohome::MountError return_code) { | 121 cryptohome::MountError return_code) { |
| 122 // Log the error, but there's not much we can do. | 122 // Log the error, but there's not much we can do. |
| 123 if (!success) { | 123 if (!success) { |
| 124 LOG(ERROR) << "Removal of cryptohome for " << user_email | 124 LOG(ERROR) << "Removal of cryptohome for " << user_email |
| 125 << " failed, return code: " << return_code; | 125 << " failed, return code: " << return_code; |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 | 128 |
| 129 // This method is used to implement UserManager::RemoveUser. | |
| 130 void RemoveUserInternal(const std::string& user_email, | |
| 131 chromeos::RemoveUserDelegate* delegate) { | |
| 132 CrosSettings* cros_settings = CrosSettings::Get(); | |
| 133 | |
| 134 // Ensure the value of owner email has been fetched. | |
| 135 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues( | |
| 136 base::Bind(&RemoveUserInternal, user_email, delegate))) { | |
| 137 // Value of owner email is not fetched yet. RemoveUserInternal will be | |
| 138 // called again after fetch completion. | |
| 139 return; | |
| 140 } | |
| 141 std::string owner; | |
| 142 cros_settings->GetString(kDeviceOwner, &owner); | |
| 143 if (user_email == owner) { | |
| 144 // Owner is not allowed to be removed from the device. | |
| 145 return; | |
| 146 } | |
| 147 | |
| 148 if (delegate) | |
| 149 delegate->OnBeforeUserRemoved(user_email); | |
| 150 | |
| 151 chromeos::UserManager::Get()->RemoveUserFromList(user_email); | |
| 152 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | |
| 153 user_email, base::Bind(&OnRemoveUserComplete, user_email)); | |
| 154 | |
| 155 if (delegate) | |
| 156 delegate->OnUserRemoved(user_email); | |
| 157 } | |
| 158 | |
| 159 // Helper function that copies users from |users_list| to |users_vector| and | 129 // Helper function that copies users from |users_list| to |users_vector| and |
| 160 // |users_set|. Duplicates and users already present in |existing_users| are | 130 // |users_set|. Duplicates and users already present in |existing_users| are |
| 161 // skipped. | 131 // skipped. |
| 162 void ParseUserList(const ListValue& users_list, | 132 void ParseUserList(const ListValue& users_list, |
| 163 const std::set<std::string>& existing_users, | 133 const std::set<std::string>& existing_users, |
| 164 std::vector<std::string>* users_vector, | 134 std::vector<std::string>* users_vector, |
| 165 std::set<std::string>* users_set) { | 135 std::set<std::string>* users_set) { |
| 166 users_vector->clear(); | 136 users_vector->clear(); |
| 167 users_set->clear(); | 137 users_set->clear(); |
| 168 for (size_t i = 0; i < users_list.GetSize(); ++i) { | 138 for (size_t i = 0; i < users_list.GetSize(); ++i) { |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 504 // Sanity check: do not allow any of the the logged in users to be removed. | 474 // Sanity check: do not allow any of the the logged in users to be removed. |
| 505 for (UserList::const_iterator it = logged_in_users_.begin(); | 475 for (UserList::const_iterator it = logged_in_users_.begin(); |
| 506 it != logged_in_users_.end(); ++it) { | 476 it != logged_in_users_.end(); ++it) { |
| 507 if ((*it)->email() == user_id) | 477 if ((*it)->email() == user_id) |
| 508 return; | 478 return; |
| 509 } | 479 } |
| 510 | 480 |
| 511 RemoveUserInternal(user_id, delegate); | 481 RemoveUserInternal(user_id, delegate); |
| 512 } | 482 } |
| 513 | 483 |
| 484 // This method is used to implement UserManager::RemoveUser. | |
|
Nikita (slow)
2013/11/13 01:37:19
nit: drop comment.
| |
| 485 void UserManagerImpl::RemoveUserInternal(const std::string& user_email, | |
| 486 RemoveUserDelegate* delegate) { | |
| 487 CrosSettings* cros_settings = CrosSettings::Get(); | |
| 488 | |
| 489 // Ensure the value of owner email has been fetched. | |
| 490 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues( | |
| 491 base::Bind(&UserManagerImpl::RemoveUserInternal, | |
| 492 base::Unretained(this), | |
| 493 user_email, delegate))) { | |
| 494 // Value of owner email is not fetched yet. RemoveUserInternal will be | |
| 495 // called again after fetch completion. | |
| 496 return; | |
| 497 } | |
| 498 std::string owner; | |
| 499 cros_settings->GetString(kDeviceOwner, &owner); | |
| 500 if (user_email == owner) { | |
| 501 // Owner is not allowed to be removed from the device. | |
| 502 return; | |
| 503 } | |
| 504 RemoveNonOwnerUserInternal(user_email, delegate); | |
| 505 } | |
| 506 | |
| 507 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email, | |
| 508 RemoveUserDelegate* delegate) { | |
| 509 if (delegate) | |
| 510 delegate->OnBeforeUserRemoved(user_email); | |
| 511 RemoveUserFromList(user_email); | |
| 512 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | |
| 513 user_email, base::Bind(&OnRemoveUserComplete, user_email)); | |
| 514 | |
| 515 if (delegate) | |
| 516 delegate->OnUserRemoved(user_email); | |
| 517 } | |
| 518 | |
| 514 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) { | 519 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) { |
| 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 516 EnsureUsersLoaded(); | |
|
Nikita (slow)
2013/11/13 01:37:19
Do you think whether removing this call might have
| |
| 517 RemoveNonCryptohomeData(user_id); | 521 RemoveNonCryptohomeData(user_id); |
| 518 User* user = RemoveRegularOrLocallyManagedUserFromList(user_id); | 522 if (users_loaded_) { |
| 519 delete user; | 523 User* user = RemoveRegularOrLocallyManagedUserFromList(user_id); |
| 524 delete user; | |
| 525 } else { | |
| 526 DCHECK(gaia::ExtractDomainName(user_id) == | |
| 527 UserManager::kLocallyManagedUserDomain); | |
| 528 // Special case, removing partially-constructed supervised user during user | |
| 529 // list loading. | |
| 530 ListPrefUpdate users_update(g_browser_process->local_state(), | |
| 531 kRegularUsers); | |
| 532 users_update->Remove(base::StringValue(user_id), NULL); | |
| 533 } | |
| 520 // Make sure that new data is persisted to Local State. | 534 // Make sure that new data is persisted to Local State. |
| 521 g_browser_process->local_state()->CommitPendingWrite(); | 535 g_browser_process->local_state()->CommitPendingWrite(); |
| 522 } | 536 } |
| 523 | 537 |
| 524 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const { | 538 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const { |
| 525 return FindUser(user_id) != NULL; | 539 return FindUser(user_id) != NULL; |
| 526 } | 540 } |
| 527 | 541 |
| 528 const User* UserManagerImpl::FindUser(const std::string& user_id) const { | 542 const User* UserManagerImpl::FindUser(const std::string& user_id) const { |
| 529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 950 // Data belonging to the guest, retail mode and stub users is always | 964 // Data belonging to the guest, retail mode and stub users is always |
| 951 // ephemeral. | 965 // ephemeral. |
| 952 if (user_id == UserManager::kGuestUserName || | 966 if (user_id == UserManager::kGuestUserName || |
| 953 user_id == UserManager::kRetailModeUserName || | 967 user_id == UserManager::kRetailModeUserName || |
| 954 user_id == kStubUser) { | 968 user_id == kStubUser) { |
| 955 return true; | 969 return true; |
| 956 } | 970 } |
| 957 | 971 |
| 958 // Data belonging to the owner, anyone found on the user list and obsolete | 972 // Data belonging to the owner, anyone found on the user list and obsolete |
| 959 // public accounts whose data has not been removed yet is not ephemeral. | 973 // public accounts whose data has not been removed yet is not ephemeral. |
| 960 if (user_id == owner_email_ || FindUserInList(user_id) || | 974 if (user_id == owner_email_ || UserExistsInList(user_id) || |
| 961 user_id == g_browser_process->local_state()-> | 975 user_id == g_browser_process->local_state()-> |
| 962 GetString(kPublicAccountPendingDataRemoval)) { | 976 GetString(kPublicAccountPendingDataRemoval)) { |
| 963 return false; | 977 return false; |
| 964 } | 978 } |
| 965 | 979 |
| 966 // Data belonging to the currently logged-in user is ephemeral when: | 980 // Data belonging to the currently logged-in user is ephemeral when: |
| 967 // a) The user logged into a regular account while the ephemeral users policy | 981 // a) The user logged into a regular account while the ephemeral users policy |
| 968 // was enabled. | 982 // was enabled. |
| 969 // - or - | 983 // - or - |
| 970 // b) The user logged into any other account type. | 984 // b) The user logged into any other account type. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1026 RestorePendingUserSessions(); | 1040 RestorePendingUserSessions(); |
| 1027 } | 1041 } |
| 1028 | 1042 |
| 1029 void UserManagerImpl::EnsureUsersLoaded() { | 1043 void UserManagerImpl::EnsureUsersLoaded() { |
| 1030 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1044 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1031 if (!g_browser_process || !g_browser_process->local_state()) | 1045 if (!g_browser_process || !g_browser_process->local_state()) |
| 1032 return; | 1046 return; |
| 1033 | 1047 |
| 1034 if (users_loaded_) | 1048 if (users_loaded_) |
| 1035 return; | 1049 return; |
| 1036 users_loaded_ = true; | 1050 // Clean up user list first. All code down the path should be synchronous, |
| 1037 | 1051 // so that local state after transaction rollback is in consistent state. |
| 1038 // Clean up user list first. | 1052 // This process also should not trigger EnsureUsersLoaded again. |
| 1039 if (supervised_user_manager_->HasFailedUserCreationTransaction()) | 1053 if (supervised_user_manager_->HasFailedUserCreationTransaction()) |
| 1040 supervised_user_manager_->RollbackUserCreationTransaction(); | 1054 supervised_user_manager_->RollbackUserCreationTransaction(); |
| 1041 | 1055 |
| 1042 PrefService* local_state = g_browser_process->local_state(); | 1056 PrefService* local_state = g_browser_process->local_state(); |
| 1043 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers); | 1057 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers); |
| 1044 const ListValue* prefs_public_accounts = | 1058 const ListValue* prefs_public_accounts = |
| 1045 local_state->GetList(kPublicAccounts); | 1059 local_state->GetList(kPublicAccounts); |
| 1046 const DictionaryValue* prefs_display_names = | 1060 const DictionaryValue* prefs_display_names = |
| 1047 local_state->GetDictionary(kUserDisplayName); | 1061 local_state->GetDictionary(kUserDisplayName); |
| 1048 const DictionaryValue* prefs_display_emails = | 1062 const DictionaryValue* prefs_display_emails = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1080 // Load public accounts. | 1094 // Load public accounts. |
| 1081 std::vector<std::string> public_accounts; | 1095 std::vector<std::string> public_accounts; |
| 1082 std::set<std::string> public_accounts_set; | 1096 std::set<std::string> public_accounts_set; |
| 1083 ParseUserList(*prefs_public_accounts, regular_users_set, | 1097 ParseUserList(*prefs_public_accounts, regular_users_set, |
| 1084 &public_accounts, &public_accounts_set); | 1098 &public_accounts, &public_accounts_set); |
| 1085 for (std::vector<std::string>::const_iterator it = public_accounts.begin(); | 1099 for (std::vector<std::string>::const_iterator it = public_accounts.begin(); |
| 1086 it != public_accounts.end(); ++it) { | 1100 it != public_accounts.end(); ++it) { |
| 1087 users_.push_back(User::CreatePublicAccountUser(*it)); | 1101 users_.push_back(User::CreatePublicAccountUser(*it)); |
| 1088 UpdatePublicAccountDisplayName(*it); | 1102 UpdatePublicAccountDisplayName(*it); |
| 1089 } | 1103 } |
| 1104 users_loaded_ = true; | |
| 1090 | 1105 |
| 1091 user_image_manager_->LoadUserImages(users_); | 1106 user_image_manager_->LoadUserImages(users_); |
| 1092 } | 1107 } |
| 1093 | 1108 |
| 1094 void UserManagerImpl::RetrieveTrustedDevicePolicies() { | 1109 void UserManagerImpl::RetrieveTrustedDevicePolicies() { |
| 1095 ephemeral_users_enabled_ = false; | 1110 ephemeral_users_enabled_ = false; |
| 1096 owner_email_ = ""; | 1111 owner_email_ = ""; |
| 1097 | 1112 |
| 1098 // Schedule a callback if device policy has not yet been verified. | 1113 // Schedule a callback if device policy has not yet been verified. |
| 1099 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues( | 1114 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1157 | 1172 |
| 1158 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const { | 1173 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const { |
| 1159 const UserList& users = GetUsers(); | 1174 const UserList& users = GetUsers(); |
| 1160 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { | 1175 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { |
| 1161 if ((*it)->email() == user_id) | 1176 if ((*it)->email() == user_id) |
| 1162 return *it; | 1177 return *it; |
| 1163 } | 1178 } |
| 1164 return NULL; | 1179 return NULL; |
| 1165 } | 1180 } |
| 1166 | 1181 |
| 1182 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const { | |
| 1183 PrefService* local_state = g_browser_process->local_state(); | |
| 1184 const ListValue* user_list = local_state->GetList(kRegularUsers); | |
| 1185 for (size_t i = 0; i < user_list->GetSize(); ++i) { | |
| 1186 std::string email; | |
| 1187 if (user_list->GetString(i, &email) && (user_id == email)) | |
| 1188 return true; | |
| 1189 } | |
| 1190 return false; | |
| 1191 } | |
| 1192 | |
| 1167 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) { | 1193 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) { |
| 1168 UserList& users = GetUsersAndModify(); | 1194 UserList& users = GetUsersAndModify(); |
| 1169 for (UserList::iterator it = users.begin(); it != users.end(); ++it) { | 1195 for (UserList::iterator it = users.begin(); it != users.end(); ++it) { |
| 1170 if ((*it)->email() == user_id) | 1196 if ((*it)->email() == user_id) |
| 1171 return *it; | 1197 return *it; |
| 1172 } | 1198 } |
| 1173 return NULL; | 1199 return NULL; |
| 1174 } | 1200 } |
| 1175 | 1201 |
| 1176 void UserManagerImpl::GuestUserLoggedIn() { | 1202 void UserManagerImpl::GuestUserLoggedIn() { |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1804 } | 1830 } |
| 1805 } | 1831 } |
| 1806 | 1832 |
| 1807 void UserManagerImpl::OnUserNotAllowed() { | 1833 void UserManagerImpl::OnUserNotAllowed() { |
| 1808 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the " | 1834 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the " |
| 1809 "current session"; | 1835 "current session"; |
| 1810 chrome::AttemptUserExit(); | 1836 chrome::AttemptUserExit(); |
| 1811 } | 1837 } |
| 1812 | 1838 |
| 1813 } // namespace chromeos | 1839 } // namespace chromeos |
| OLD | NEW |