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

Unified Diff: chrome/browser/chromeos/login/user_manager_impl.cc

Issue 9405035: Implement ephemeral users (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: As discussed, removed initial image selection. Created 8 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/login/user_manager_impl.cc
diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
index f12e0db8f6fe451570c1422cf726c24c9b2ba245..cd491954b8745c139927bde52023f402eab4f599 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/user_manager_impl.cc
@@ -35,6 +35,7 @@
#include "chrome/browser/chromeos/login/ownership_service.h"
#include "chrome/browser/chromeos/login/remove_user_delegate.h"
#include "chrome/browser/chromeos/system/runtime_environment.h"
+#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile_downloader.h"
@@ -290,7 +291,9 @@ UserManagerImpl::UserManagerImpl()
logged_in_user_(NULL),
is_current_user_owner_(false),
is_current_user_new_(false),
+ is_current_user_ephemeral_(false),
is_user_logged_in_(false),
+ ephemeral_users_enabled_(false),
observed_sync_service_(NULL),
last_image_set_async_(false),
downloaded_profile_image_data_url_(chrome::kAboutBlankURL) {
@@ -301,6 +304,7 @@ UserManagerImpl::UserManagerImpl()
content::NotificationService::AllSources());
registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
content::NotificationService::AllSources());
+ RetrieveTrustedDevicePolicies();
}
UserManagerImpl::~UserManagerImpl() {
@@ -317,43 +321,52 @@ void UserManagerImpl::UserLoggedIn(const std::string& email) {
is_user_logged_in_ = true;
if (email == kGuestUser) {
+ is_current_user_ephemeral_ = true;
GuestUserLoggedIn();
return;
}
if (email == kDemoUser) {
+ is_current_user_ephemeral_ = true;
DemoUserLoggedIn();
return;
}
- EnsureUsersLoaded();
-
- // Clear the prefs view of the users.
- PrefService* prefs = g_browser_process->local_state();
- ListPrefUpdate prefs_users_update(prefs, UserManager::kLoggedInUsers);
- prefs_users_update->Clear();
-
- // Make sure this user is first.
- prefs_users_update->Append(Value::CreateStringValue(email));
- UserList::iterator logged_in_user = users_.end();
- for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
- std::string user_email = (*it)->email();
- // Skip the most recent user.
- if (email != user_email)
- prefs_users_update->Append(Value::CreateStringValue(user_email));
- else
- logged_in_user = it;
- }
-
- if (logged_in_user == users_.end()) {
+ if (IsEphemeralUser(email)) {
is_current_user_new_ = true;
+ is_current_user_ephemeral_ = true;
logged_in_user_ = CreateUser(email);
+ SetInitialUserImage(email);
} else {
- logged_in_user_ = *logged_in_user;
- users_.erase(logged_in_user);
+ EnsureUsersLoaded();
+
+ // Clear the prefs view of the users.
+ PrefService* prefs = g_browser_process->local_state();
+ ListPrefUpdate prefs_users_update(prefs, UserManager::kLoggedInUsers);
+ prefs_users_update->Clear();
+
+ // Make sure this user is first.
+ prefs_users_update->Append(Value::CreateStringValue(email));
+ UserList::iterator logged_in_user = users_.end();
+ for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
+ std::string user_email = (*it)->email();
+ // Skip the most recent user.
+ if (email != user_email)
+ prefs_users_update->Append(Value::CreateStringValue(user_email));
+ else
+ logged_in_user = it;
+ }
+
+ if (logged_in_user == users_.end()) {
+ is_current_user_new_ = true;
+ logged_in_user_ = CreateUser(email);
+ } else {
+ logged_in_user_ = *logged_in_user;
+ users_.erase(logged_in_user);
+ }
+ // This user must be in the front of the user list.
+ users_.insert(users_.begin(), logged_in_user_);
}
- // This user must be in the front of the user list.
- users_.insert(users_.begin(), logged_in_user_);
NotifyOnLogin();
@@ -422,54 +435,7 @@ void UserManagerImpl::RemoveUser(const std::string& email,
void UserManagerImpl::RemoveUserFromList(const std::string& email) {
EnsureUsersLoaded();
-
- // Clear the prefs view of the users.
- PrefService* prefs = g_browser_process->local_state();
- ListPrefUpdate prefs_users_update(prefs, UserManager::kLoggedInUsers);
- prefs_users_update->Clear();
-
- UserList::iterator user_to_remove = users_.end();
- for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
- std::string user_email = (*it)->email();
- // Skip user that we would like to delete.
- if (email != user_email)
- prefs_users_update->Append(Value::CreateStringValue(user_email));
- else
- user_to_remove = it;
- }
-
- DictionaryPrefUpdate prefs_images_update(prefs, UserManager::kUserImages);
- std::string image_path_string;
- prefs_images_update->GetStringWithoutPathExpansion(email, &image_path_string);
- prefs_images_update->RemoveWithoutPathExpansion(email, NULL);
-
- DictionaryPrefUpdate prefs_oauth_update(prefs,
- UserManager::kUserOAuthTokenStatus);
- int oauth_status;
- prefs_oauth_update->GetIntegerWithoutPathExpansion(email, &oauth_status);
- prefs_oauth_update->RemoveWithoutPathExpansion(email, NULL);
-
- DictionaryPrefUpdate prefs_display_email_update(
- prefs, UserManager::kUserDisplayEmail);
- prefs_display_email_update->RemoveWithoutPathExpansion(email, NULL);
-
- if (user_to_remove != users_.end()) {
- --display_name_count_[(*user_to_remove)->GetDisplayName()];
- delete *user_to_remove;
- users_.erase(user_to_remove);
- }
-
- int default_image_id = User::kInvalidImageIndex;
- if (!image_path_string.empty() &&
- !IsDefaultImagePath(image_path_string, &default_image_id)) {
- FilePath image_path(image_path_string);
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&UserManagerImpl::DeleteUserImage,
- base::Unretained(this),
- image_path));
- }
+ RemoveUserFromListInternal(email);
}
bool UserManagerImpl::IsKnownUser(const std::string& email) const {
@@ -477,15 +443,9 @@ bool UserManagerImpl::IsKnownUser(const std::string& email) const {
}
const User* UserManagerImpl::FindUser(const std::string& email) const {
- // Speed up search by checking the logged-in user first.
if (logged_in_user_ && logged_in_user_->email() == email)
return logged_in_user_;
- const UserList& users = GetUsers();
- for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
- if ((*it)->email() == email)
- return *it;
- }
- return NULL;
+ return FindUserInList(email);
}
const User& UserManagerImpl::GetLoggedInUser() const {
@@ -505,15 +465,22 @@ void UserManagerImpl::SaveUserOAuthStatus(
const std::string& username,
User::OAuthTokenStatus oauth_token_status) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ DVLOG(1) << "Saving user OAuth token status in Local State";
+ User* user = const_cast<User*>(FindUser(username));
+ if (user)
+ user->set_oauth_token_status(oauth_token_status);
+
+ // Do not update local store if the user is ephemeral.
+ if (IsEphemeralUser(username))
+ return;
+
PrefService* local_state = g_browser_process->local_state();
+
DictionaryPrefUpdate oauth_status_update(local_state,
UserManager::kUserOAuthTokenStatus);
oauth_status_update->SetWithoutPathExpansion(username,
new base::FundamentalValue(static_cast<int>(oauth_token_status)));
- DVLOG(1) << "Saving user OAuth token status in Local State";
- User* user = const_cast<User*>(FindUser(username));
- if (user)
- user->set_oauth_token_status(oauth_token_status);
}
User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
@@ -550,6 +517,10 @@ void UserManagerImpl::SaveUserDisplayEmail(const std::string& username,
user->set_display_email(display_email);
+ // Do not update local store if the user is ephemeral.
+ if (IsEphemeralUser(username))
+ return;
+
PrefService* local_state = g_browser_process->local_state();
DictionaryPrefUpdate display_email_update(local_state,
@@ -604,7 +575,7 @@ void UserManagerImpl::DownloadProfileImage(const std::string& reason) {
return;
}
- if (GetLoggedInUser().email().empty()) {
+ if (IsLoggedInAsGuest()) {
// This is a guest login so there's no profile image to download.
return;
}
@@ -623,6 +594,9 @@ void UserManagerImpl::Observe(int type,
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&UserManagerImpl::CheckOwnership,
base::Unretained(this)));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
+ base::Unretained(this)));
break;
case chrome::NOTIFICATION_PROFILE_ADDED:
if (IsUserLoggedIn() && !IsLoggedInAsGuest()) {
@@ -669,6 +643,10 @@ bool UserManagerImpl::IsCurrentUserNew() const {
return is_current_user_new_;
}
+bool UserManagerImpl::IsCurrentUserEphemeral() const {
+ return is_current_user_ephemeral_;
+}
+
bool UserManagerImpl::IsUserLoggedIn() const {
return is_user_logged_in_;
}
@@ -792,6 +770,80 @@ void UserManagerImpl::EnsureUsersLoaded() {
}
}
+void UserManagerImpl::RetrieveTrustedDevicePolicies() {
+ ephemeral_users_enabled_ = false;
+ owner_email_ = "";
merkulova 2014/04/08 10:34:59 I wonder why we need this string? We can initializ
bartfab (slow) 2014/04/14 11:36:42 Sorry for the late reply. I will summarize here wh
+
+ CrosSettings* cros_settings = CrosSettings::Get();
+ // Schedule a callback if device policy has not yet been verified.
+ if (!cros_settings->GetTrusted(
+ kAccountsPrefEphemeralUsersEnabled,
+ base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
+ base::Unretained(this)))) {
+ return;
+ }
+
+ cros_settings->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
+ &ephemeral_users_enabled_);
+ cros_settings->GetString(kDeviceOwner, &owner_email_);
+
+ // If ephemeral users are enabled, remove all users except the owner.
+ if (ephemeral_users_enabled_) {
+ scoped_ptr<base::ListValue> users(
+ g_browser_process->local_state()->GetList(kLoggedInUsers)->DeepCopy());
+
+ bool changed = false;
+ for (base::ListValue::const_iterator user = users->begin();
+ user != users->end(); ++user) {
+ std::string user_email;
+ (*user)->GetAsString(&user_email);
+ if (user_email != owner_email_) {
+ RemoveUserFromListInternal(user_email);
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ // Trigger a redraw of the login window.
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED,
+ content::Source<UserManagerImpl>(this),
+ content::NotificationService::NoDetails());
+ }
+ }
+}
+
+bool UserManagerImpl::AreEphemeralUsersEnabled() const {
+ return ephemeral_users_enabled_ &&
+ (g_browser_process->browser_policy_connector()->IsEnterpriseManaged() ||
+ !owner_email_.empty());
+}
+
+bool UserManagerImpl::IsEphemeralUser(const std::string& email) const {
+ // The guest user always is ephemeral.
+ if (email == guest_user_.email())
+ return true;
+
+ // The currently logged-in user is ephemeral iff logged in as ephemeral.
+ if (logged_in_user_ && (email == logged_in_user_->email()))
+ return is_current_user_ephemeral_;
+
+ // Any other user is ephemeral iff ephemeral users are enabled, the user is
+ // not the owner and is not in the persistent list.
+ return AreEphemeralUsersEnabled() &&
+ (email != owner_email_) &&
+ !FindUserInList(email);
+}
+
+const User* UserManagerImpl::FindUserInList(const std::string& email) const {
+ const UserList& users = GetUsers();
+ for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
+ if ((*it)->email() == email)
+ return *it;
+ }
+ return NULL;
+}
+
void UserManagerImpl::StubUserLoggedIn() {
logged_in_user_ = &stub_user_;
stub_user_.SetImage(GetDefaultImage(kStubDefaultImageIndex),
@@ -874,6 +926,10 @@ void UserManagerImpl::SaveUserImageInternal(const std::string& username,
SetUserImage(username, image_index, image);
+ // Ignore for ephemeral users.
+ if (IsEphemeralUser(username))
+ return;
+
FilePath image_path = GetImagePathForUser(username);
DVLOG(1) << "Saving user image to " << image_path.value();
@@ -920,6 +976,10 @@ void UserManagerImpl::SaveImageToLocalState(const std::string& username,
bool is_async) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Ignore for ephemeral users.
+ if (IsEphemeralUser(username))
+ return;
+
// TODO(ivankr): use unique filenames for user images each time
// a new image is set so that only the last image update is saved
// to Local State and notified.
@@ -1069,4 +1129,52 @@ User* UserManagerImpl::CreateUser(const std::string& email) const {
return user;
}
+void UserManagerImpl::RemoveUserFromListInternal(const std::string& email) {
+ // Clear the prefs view of the users.
+ PrefService* prefs = g_browser_process->local_state();
+ ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers);
+ prefs_users_update->Clear();
+
+ UserList::iterator user_to_remove = users_.end();
+ for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
+ std::string user_email = (*it)->email();
+ // Skip user that we would like to delete.
+ if (email != user_email)
+ prefs_users_update->Append(Value::CreateStringValue(user_email));
+ else
+ user_to_remove = it;
+ }
+
+ DictionaryPrefUpdate prefs_images_update(prefs, kUserImages);
+ std::string image_path_string;
+ prefs_images_update->GetStringWithoutPathExpansion(email, &image_path_string);
+ prefs_images_update->RemoveWithoutPathExpansion(email, NULL);
+
+ DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
+ int oauth_status;
+ prefs_oauth_update->GetIntegerWithoutPathExpansion(email, &oauth_status);
+ prefs_oauth_update->RemoveWithoutPathExpansion(email, NULL);
+
+ DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
+ prefs_display_email_update->RemoveWithoutPathExpansion(email, NULL);
+
+ if (user_to_remove != users_.end()) {
+ --display_name_count_[(*user_to_remove)->GetDisplayName()];
+ delete *user_to_remove;
+ users_.erase(user_to_remove);
+ }
+
+ int default_image_id = User::kInvalidImageIndex;
+ if (!image_path_string.empty() &&
+ !IsDefaultImagePath(image_path_string, &default_image_id)) {
+ FilePath image_path(image_path_string);
+ BrowserThread::PostTask(
+ BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&UserManagerImpl::DeleteUserImage,
+ base::Unretained(this),
+ image_path));
+ }
+}
+
} // namespace chromeos
« no previous file with comments | « chrome/browser/chromeos/login/user_manager_impl.h ('k') | chrome/browser/chromeos/login/user_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698