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

Side by Side Diff: chrome/browser/chromeos/login/user_manager_impl.cc

Issue 63173012: SupervisedUsers : Fix transaction cleanup (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/chromeos/login/user_manager_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
485 RemoveUserDelegate* delegate) {
486 CrosSettings* cros_settings = CrosSettings::Get();
487
488 // Ensure the value of owner email has been fetched.
489 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
490 base::Bind(&UserManagerImpl::RemoveUserInternal,
491 base::Unretained(this),
492 user_email, delegate))) {
493 // Value of owner email is not fetched yet. RemoveUserInternal will be
494 // called again after fetch completion.
495 return;
496 }
497 std::string owner;
498 cros_settings->GetString(kDeviceOwner, &owner);
499 if (user_email == owner) {
500 // Owner is not allowed to be removed from the device.
501 return;
502 }
503 RemoveNonOwnerUserInternal(user_email, delegate);
504 }
505
506 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
507 RemoveUserDelegate* delegate) {
508 if (delegate)
509 delegate->OnBeforeUserRemoved(user_email);
510 RemoveUserFromList(user_email);
511 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
512 user_email, base::Bind(&OnRemoveUserComplete, user_email));
513
514 if (delegate)
515 delegate->OnUserRemoved(user_email);
516 }
517
514 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) { 518 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 519 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
516 EnsureUsersLoaded();
517 RemoveNonCryptohomeData(user_id); 520 RemoveNonCryptohomeData(user_id);
518 User* user = RemoveRegularOrLocallyManagedUserFromList(user_id); 521 if (users_loaded_) {
519 delete user; 522 User* user = RemoveRegularOrLocallyManagedUserFromList(user_id);
523 delete user;
524 } else {
525 DCHECK(gaia::ExtractDomainName(user_id) ==
526 UserManager::kLocallyManagedUserDomain);
527 // Special case, removing partially-constructed supervised user during user
528 // list loading.
529 ListPrefUpdate users_update(g_browser_process->local_state(),
530 kRegularUsers);
531 users_update->Remove(base::StringValue(user_id), NULL);
532 }
520 // Make sure that new data is persisted to Local State. 533 // Make sure that new data is persisted to Local State.
521 g_browser_process->local_state()->CommitPendingWrite(); 534 g_browser_process->local_state()->CommitPendingWrite();
522 } 535 }
523 536
524 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const { 537 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
525 return FindUser(user_id) != NULL; 538 return FindUser(user_id) != NULL;
526 } 539 }
527 540
528 const User* UserManagerImpl::FindUser(const std::string& user_id) const { 541 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 // Data belonging to the guest, retail mode and stub users is always 963 // Data belonging to the guest, retail mode and stub users is always
951 // ephemeral. 964 // ephemeral.
952 if (user_id == UserManager::kGuestUserName || 965 if (user_id == UserManager::kGuestUserName ||
953 user_id == UserManager::kRetailModeUserName || 966 user_id == UserManager::kRetailModeUserName ||
954 user_id == kStubUser) { 967 user_id == kStubUser) {
955 return true; 968 return true;
956 } 969 }
957 970
958 // Data belonging to the owner, anyone found on the user list and obsolete 971 // 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. 972 // public accounts whose data has not been removed yet is not ephemeral.
960 if (user_id == owner_email_ || FindUserInList(user_id) || 973 if (user_id == owner_email_ || UserExistsInList(user_id) ||
961 user_id == g_browser_process->local_state()-> 974 user_id == g_browser_process->local_state()->
962 GetString(kPublicAccountPendingDataRemoval)) { 975 GetString(kPublicAccountPendingDataRemoval)) {
963 return false; 976 return false;
964 } 977 }
965 978
966 // Data belonging to the currently logged-in user is ephemeral when: 979 // 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 980 // a) The user logged into a regular account while the ephemeral users policy
968 // was enabled. 981 // was enabled.
969 // - or - 982 // - or -
970 // b) The user logged into any other account type. 983 // b) The user logged into any other account type.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 RestorePendingUserSessions(); 1039 RestorePendingUserSessions();
1027 } 1040 }
1028 1041
1029 void UserManagerImpl::EnsureUsersLoaded() { 1042 void UserManagerImpl::EnsureUsersLoaded() {
1030 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1043 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1031 if (!g_browser_process || !g_browser_process->local_state()) 1044 if (!g_browser_process || !g_browser_process->local_state())
1032 return; 1045 return;
1033 1046
1034 if (users_loaded_) 1047 if (users_loaded_)
1035 return; 1048 return;
1036 users_loaded_ = true; 1049 // Clean up user list first. All code down the path should be synchronous,
1037 1050 // so that local state after transaction rollback is in consistent state.
1038 // Clean up user list first. 1051 // This process also should not trigger EnsureUsersLoaded again.
1039 if (supervised_user_manager_->HasFailedUserCreationTransaction()) 1052 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1040 supervised_user_manager_->RollbackUserCreationTransaction(); 1053 supervised_user_manager_->RollbackUserCreationTransaction();
1041 1054
1042 PrefService* local_state = g_browser_process->local_state(); 1055 PrefService* local_state = g_browser_process->local_state();
1043 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers); 1056 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers);
1044 const ListValue* prefs_public_accounts = 1057 const ListValue* prefs_public_accounts =
1045 local_state->GetList(kPublicAccounts); 1058 local_state->GetList(kPublicAccounts);
1046 const DictionaryValue* prefs_display_names = 1059 const DictionaryValue* prefs_display_names =
1047 local_state->GetDictionary(kUserDisplayName); 1060 local_state->GetDictionary(kUserDisplayName);
1048 const DictionaryValue* prefs_display_emails = 1061 const DictionaryValue* prefs_display_emails =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 // Load public accounts. 1093 // Load public accounts.
1081 std::vector<std::string> public_accounts; 1094 std::vector<std::string> public_accounts;
1082 std::set<std::string> public_accounts_set; 1095 std::set<std::string> public_accounts_set;
1083 ParseUserList(*prefs_public_accounts, regular_users_set, 1096 ParseUserList(*prefs_public_accounts, regular_users_set,
1084 &public_accounts, &public_accounts_set); 1097 &public_accounts, &public_accounts_set);
1085 for (std::vector<std::string>::const_iterator it = public_accounts.begin(); 1098 for (std::vector<std::string>::const_iterator it = public_accounts.begin();
1086 it != public_accounts.end(); ++it) { 1099 it != public_accounts.end(); ++it) {
1087 users_.push_back(User::CreatePublicAccountUser(*it)); 1100 users_.push_back(User::CreatePublicAccountUser(*it));
1088 UpdatePublicAccountDisplayName(*it); 1101 UpdatePublicAccountDisplayName(*it);
1089 } 1102 }
1103 users_loaded_ = true;
1090 1104
1091 user_image_manager_->LoadUserImages(users_); 1105 user_image_manager_->LoadUserImages(users_);
1092 } 1106 }
1093 1107
1094 void UserManagerImpl::RetrieveTrustedDevicePolicies() { 1108 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1095 ephemeral_users_enabled_ = false; 1109 ephemeral_users_enabled_ = false;
1096 owner_email_ = ""; 1110 owner_email_ = "";
1097 1111
1098 // Schedule a callback if device policy has not yet been verified. 1112 // Schedule a callback if device policy has not yet been verified.
1099 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues( 1113 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 1171
1158 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const { 1172 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1159 const UserList& users = GetUsers(); 1173 const UserList& users = GetUsers();
1160 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { 1174 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1161 if ((*it)->email() == user_id) 1175 if ((*it)->email() == user_id)
1162 return *it; 1176 return *it;
1163 } 1177 }
1164 return NULL; 1178 return NULL;
1165 } 1179 }
1166 1180
1181 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1182 PrefService* local_state = g_browser_process->local_state();
1183 const ListValue* user_list = local_state->GetList(kRegularUsers);
1184 for (size_t i = 0; i < user_list->GetSize(); ++i) {
1185 std::string email;
1186 if (user_list->GetString(i, &email) && (user_id == email))
1187 return true;
1188 }
1189 return false;
1190 }
1191
1167 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) { 1192 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1168 UserList& users = GetUsersAndModify(); 1193 UserList& users = GetUsersAndModify();
1169 for (UserList::iterator it = users.begin(); it != users.end(); ++it) { 1194 for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1170 if ((*it)->email() == user_id) 1195 if ((*it)->email() == user_id)
1171 return *it; 1196 return *it;
1172 } 1197 }
1173 return NULL; 1198 return NULL;
1174 } 1199 }
1175 1200
1176 void UserManagerImpl::GuestUserLoggedIn() { 1201 void UserManagerImpl::GuestUserLoggedIn() {
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 } 1829 }
1805 } 1830 }
1806 1831
1807 void UserManagerImpl::OnUserNotAllowed() { 1832 void UserManagerImpl::OnUserNotAllowed() {
1808 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the " 1833 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
1809 "current session"; 1834 "current session";
1810 chrome::AttemptUserExit(); 1835 chrome::AttemptUserExit();
1811 } 1836 }
1812 1837
1813 } // namespace chromeos 1838 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/user_manager_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698