Index: chrome/browser/chromeos/login/user_manager.cc |
diff --git a/chrome/browser/chromeos/login/user_manager.cc b/chrome/browser/chromeos/login/user_manager.cc |
index 3b56995820865b357fa56d6669ff451387731f35..85b39e54fe45dc4cfb54c851e3b296605aa58e17 100644 |
--- a/chrome/browser/chromeos/login/user_manager.cc |
+++ b/chrome/browser/chromeos/login/user_manager.cc |
@@ -36,6 +36,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" |
@@ -322,15 +323,24 @@ void UserManager::UserLoggedIn(const std::string& email) { |
user_is_logged_in_ = true; |
if (email == kGuestUser) { |
+ current_user_is_ephemeral_ = true; |
GuestUserLoggedIn(); |
return; |
} |
if (email == kDemoUser) { |
+ current_user_is_ephemeral_ = true; |
Ivan Korotkov
2012/03/01 20:16:30
What's the point of making guest/demo user ephemer
use bartfab instead
2012/03/05 18:07:32
It is logically consistent. The guest user's recen
|
DemoUserLoggedIn(); |
return; |
} |
+ if (IsEphemeralUser(email)) { |
+ current_user_is_ephemeral_ = true; |
+ logged_in_user_ = CreateUser(email); |
+ NotifyOnLogin(); |
+ return; |
+ } |
+ |
EnsureUsersLoaded(); |
// Clear the prefs view of the users. |
@@ -480,15 +490,9 @@ bool UserManager::IsKnownUser(const std::string& email) const { |
} |
const User* UserManager::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); |
} |
bool UserManager::IsDisplayNameUnique(const std::string& display_name) const { |
@@ -499,14 +503,21 @@ void UserManager::SaveUserOAuthStatus( |
const std::string& username, |
User::OAuthTokenStatus oauth_token_status) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- PrefService* local_state = g_browser_process->local_state(); |
- DictionaryPrefUpdate oauth_status_update(local_state, 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); |
+ |
+ // 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, kUserOAuthTokenStatus); |
+ oauth_status_update->SetWithoutPathExpansion(username, |
+ new base::FundamentalValue(static_cast<int>(oauth_token_status))); |
} |
User::OAuthTokenStatus UserManager::LoadUserOAuthStatus( |
@@ -543,6 +554,10 @@ void UserManager::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, kUserDisplayEmail); |
@@ -614,6 +629,9 @@ void UserManager::Observe(int type, |
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
base::Bind(&UserManager::CheckOwnership, |
base::Unretained(this))); |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ base::Bind(&UserManager::RetrieveTrustedDevicePolicies, |
+ base::Unretained(this))); |
break; |
case chrome::NOTIFICATION_PROFILE_ADDED: |
if (user_is_logged_in() && !IsLoggedInAsGuest()) { |
@@ -688,6 +706,7 @@ UserManager::UserManager() |
logged_in_user_(NULL), |
current_user_is_owner_(false), |
current_user_is_new_(false), |
+ current_user_is_ephemeral_(false), |
user_is_logged_in_(false), |
observed_sync_service_(NULL), |
last_image_set_async_(false), |
@@ -699,6 +718,7 @@ UserManager::UserManager() |
content::NotificationService::AllSources()); |
registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, |
content::NotificationService::AllSources()); |
+ RetrieveTrustedDevicePolicies(); |
} |
UserManager::~UserManager() { |
@@ -794,6 +814,66 @@ void UserManager::EnsureUsersLoaded() { |
} |
} |
+void UserManager::RetrieveTrustedDevicePolicies() { |
+ ephemeral_users_enabled_.reset(); |
+ owner_.reset(); |
+ |
+ CrosSettings* cros_settings = CrosSettings::Get(); |
+ // Schedule a callback if device policy has not yet been verified. |
+ if (!cros_settings->GetTrusted( |
+ kAccountsPrefEphemeralUsersEnabled, |
+ base::Bind(&UserManager::RetrieveTrustedDevicePolicies, |
+ base::Unretained(this)))) { |
+ return; |
+ } |
+ bool* ephemeral_users_enabled = new bool; |
+ cros_settings->GetBoolean(kAccountsPrefEphemeralUsersEnabled, |
+ ephemeral_users_enabled); |
+ ephemeral_users_enabled_.reset(ephemeral_users_enabled); |
+ |
+ if (g_browser_process->browser_policy_connector()->IsEnterpriseManaged()) { |
+ owner_.reset(new std::string); |
+ } else { |
+ std::string* owner = new std::string; |
+ cros_settings->GetString(kDeviceOwner, owner); |
+ owner_.reset(owner); |
+ } |
+ |
+ if (*ephemeral_users_enabled_) |
+ RemoveAllExceptOwnerFromList(); |
Ivan Korotkov
2012/03/02 12:39:38
Discussed this with Nikita:
Please consider delayi
use bartfab instead
2012/03/05 18:07:32
I discussed this with the folks here at the office
|
+} |
+ |
+bool UserManager::AreEphemeralUsersEnabled() const { |
+ return ephemeral_users_enabled_.get() && |
+ *ephemeral_users_enabled_ && |
+ owner_.get(); |
+} |
+ |
+bool UserManager::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 current_user_is_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_) && |
+ !FindUserInList(email); |
+} |
+ |
+const User* UserManager::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 UserManager::StubUserLoggedIn() { |
logged_in_user_ = &stub_user_; |
stub_user_.SetImage(GetDefaultImage(kStubDefaultImageIndex), |
@@ -922,6 +1002,10 @@ void UserManager::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. |
@@ -1073,4 +1157,68 @@ User* UserManager::CreateUser(const std::string& email) const { |
return user; |
} |
+void UserManager::RemoveAllExceptOwnerFromList() { |
+ const std::string owner_email = *owner_; |
+ // If a user is currently logged in and the login occurred before ephemeral |
+ // users were enabled, this user should not be deleted yet either. |
Ivan Korotkov
2012/03/02 12:39:38
Are we sure about that decision? As far as I under
Nikita (slow)
2012/03/02 12:51:42
And this only makes sense when we want "Enable eph
use bartfab instead
2012/03/05 18:07:32
Even with ephemeral users exposed as a consumer se
|
+ std::string logged_in_user_email; |
+ if (user_is_logged_in_ && !current_user_is_ephemeral_) |
+ logged_in_user_email = logged_in_user_->email(); |
+ |
+ PrefService* prefs = g_browser_process->local_state(); |
+ ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers); |
+ DictionaryPrefUpdate prefs_images_update(prefs, kUserImages); |
+ DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus); |
+ DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail); |
+ |
+ scoped_ptr<base::ListValue> users(prefs_users_update->DeepCopy()); |
+ prefs_users_update->Clear(); |
+ 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 || user_email == logged_in_user_email) { |
+ prefs_users_update->Append(Value::CreateStringValue(user_email)); |
+ continue; |
+ } |
+ std::string image_path_string; |
+ prefs_images_update->GetStringWithoutPathExpansion(user_email, |
+ &image_path_string); |
+ prefs_images_update->RemoveWithoutPathExpansion(user_email, NULL); |
+ prefs_oauth_update->RemoveWithoutPathExpansion(user_email, NULL); |
+ prefs_display_email_update->RemoveWithoutPathExpansion(user_email, NULL); |
+ |
+ 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(&UserManager::DeleteUserImage, |
+ base::Unretained(this), |
+ image_path)); |
+ } |
+ } |
+ |
+ if (!users_.empty()) { |
+ UserList users_update; |
+ for (UserList::iterator user = users_.begin(); user != users_.end(); |
+ ++user) { |
+ if ((*user)->email() == owner_email || *user == logged_in_user_) { |
+ users_update.push_back(*user); |
+ } else { |
+ --display_name_count_[(*user)->GetDisplayName()]; |
+ delete *user; |
+ } |
+ } |
+ users_ = users_update; |
+ // Trigger a redraw of the login window. |
+ content::NotificationService::current()->Notify( |
+ chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, |
+ content::Source<UserManager>(this), |
+ content::NotificationService::NoDetails()); |
+ } |
+} |
+ |
} // namespace chromeos |