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

Unified Diff: components/user_manager/user_manager_base.cc

Issue 2711113003: Track whether a given user session has completed initialization, and use (Closed)
Patch Set: Added tests. Created 3 years, 10 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: components/user_manager/user_manager_base.cc
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 30fe4559b1880c57b96b9c7797f508bcfc3b24c6..30d0c29147c9375fab39e72c4efa8c10d058b0ab 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -54,6 +54,13 @@ const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
// authentication against GAIA should be enforced during the next sign-in.
const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
+// A dictionary that maps user IDs to a flag indicating whether session
+// initialization has been completed at least once on this session. If the
+// flag is set to false (or the user ID is missing from the dictionary) then
+// the session did not complete initialization and the next signin should
+// require a network connection (for example, to register for policy).
+const char kUserSessionInitialized[] = "UserSessionInitialized";
emaxx 2017/02/23 21:45:25 To me, the name sounds a bit misleading: the flag
Andrew T Wilson (Slow) 2017/02/24 16:15:15 Yeah, the problem is that profile initialization i
emaxx 2017/02/24 17:54:09 But the notification to set this new flag is set e
+
// A dictionary that maps user ID to the user type.
const char kUserType[] = "UserType";
@@ -82,6 +89,7 @@ void UserManagerBase::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(kUserDisplayEmail);
registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
registry->RegisterDictionaryPref(kUserForceOnlineSignin);
+ registry->RegisterDictionaryPref(kUserSessionInitialized);
registry->RegisterDictionaryPref(kUserType);
registry->RegisterStringPref(kLastActiveUser, std::string());
@@ -263,6 +271,26 @@ void UserManagerBase::OnSessionStarted() {
GetLocalState()->CommitPendingWrite();
}
+void UserManagerBase::OnSessionInitialized(User* user) {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+
+ // Mark the user as having an initialized session.
+ user->set_session_initialized(true);
+
+ // Do not update local state if data stored or cached outside the user's
emaxx 2017/02/23 21:45:25 I'm curious how then is the flag preserved for the
Andrew T Wilson (Slow) 2017/02/24 16:15:15 Great catch. I suspect the way to deal with this i
emaxx 2017/02/24 17:54:09 Could you please drop a note regarding ephemeral u
+ // cryptohome is to be treated as ephemeral.
+ if (IsUserNonCryptohomeDataEphemeral(user->GetAccountId()))
+ return;
+
+ {
+ DictionaryPrefUpdate user_session_initialized(GetLocalState(),
+ kUserSessionInitialized);
+ user_session_initialized->SetBooleanWithoutPathExpansion(
Alexander Alekseev 2017/02/24 09:58:11 We have known_user database for this. Could you us
Andrew T Wilson (Slow) 2017/02/24 16:15:15 Done.
+ user->GetAccountId().GetUserEmail(), true);
emaxx 2017/02/23 21:45:25 The docs for AccountId prescribe to use GetAccount
Andrew T Wilson (Slow) 2017/02/24 16:15:15 I'm now just using known_user, so I think we're OK
+ }
+ GetLocalState()->CommitPendingWrite();
+}
+
void UserManagerBase::RemoveUser(const AccountId& account_id,
RemoveUserDelegate* delegate) {
DCHECK(task_runner_->RunsTasksOnCurrentThread());
@@ -782,8 +810,24 @@ void UserManagerBase::EnsureUsersLoaded() {
std::set<AccountId> regular_users_set;
ParseUserList(*prefs_regular_users, device_local_accounts_set, &regular_users,
&regular_users_set);
+
+ // If there is no stored SessionInitialized state, this either means this is
+ // the first boot on a new device or this is a migration from an older device
+ // that was not tracking SessionInitialized state. If there are already users
emaxx 2017/02/23 21:45:25 It's not clear how this will work in the following
Andrew T Wilson (Slow) 2017/02/24 16:15:15 I don't think this can really happen - very very e
emaxx 2017/02/24 17:54:09 Acknowledged. And looks like the existing tests ve
+ // on the device then we know this is a migration, so we will mark all of
+ // the sessions as initialized.
+ const bool mark_user_sessions_initialized =
emaxx 2017/02/23 21:45:25 Maybe reorganize the migration code so that it for
Andrew T Wilson (Slow) 2017/02/24 16:15:15 Moved migration code to known_user::IsSessionIniti
+ !local_state->HasPrefPath(kUserSessionInitialized);
+
for (std::vector<AccountId>::const_iterator it = regular_users.begin();
it != regular_users.end(); ++it) {
+ if (mark_user_sessions_initialized) {
+ LOG(WARNING) << "Migrating existing user to session_initialized=true";
emaxx 2017/02/23 21:45:25 nit: Maybe also log something that specifies the u
emaxx 2017/02/23 21:45:25 nit: Isn't the INFO level better here? Because thi
Andrew T Wilson (Slow) 2017/02/24 16:15:15 Yes, but should be a one-off per user. So it's a w
Andrew T Wilson (Slow) 2017/02/24 16:15:15 Intentionally not doing this since I believe loggi
+ DictionaryPrefUpdate user_session_initialized(GetLocalState(),
+ kUserSessionInitialized);
+ user_session_initialized->SetBooleanWithoutPathExpansion(
+ it->GetUserEmail(), true);
+ }
User* user = nullptr;
if (IsSupervisedAccountId(*it)) {
user = User::CreateSupervisedUser(*it);
@@ -799,6 +843,7 @@ void UserManagerBase::EnsureUsersLoaded() {
const AccountId account_id = user->GetAccountId();
user->set_oauth_token_status(LoadUserOAuthStatus(*it));
user->set_force_online_signin(LoadForceOnlineSignin(*it));
+ user->set_session_initialized(LoadSessionInitialized(*it));
user->set_using_saml(known_user::IsUsingSAML(*it));
users_.push_back(user);
@@ -821,6 +866,9 @@ void UserManagerBase::EnsureUsersLoaded() {
}
}
+ if (mark_user_sessions_initialized)
+ local_state->CommitPendingWrite();
+
user_loading_stage_ = STAGE_LOADED;
PerformPostUserListLoadingActions();
@@ -883,6 +931,11 @@ void UserManagerBase::RegularUserLoggedIn(const AccountId& account_id) {
active_user_->set_oauth_token_status(LoadUserOAuthStatus(account_id));
SaveUserDisplayName(active_user_->GetAccountId(),
base::UTF8ToUTF16(active_user_->GetAccountName(true)));
+ DictionaryPrefUpdate user_session_initialized(GetLocalState(),
+ kUserSessionInitialized);
+ user_session_initialized->SetBooleanWithoutPathExpansion(
+ active_user_->GetAccountId().GetUserEmail(),
+ active_user_->session_initialized());
}
AddUserRecord(active_user_);
@@ -939,6 +992,20 @@ bool UserManagerBase::LoadForceOnlineSignin(const AccountId& account_id) const {
return force_online_signin;
}
+bool UserManagerBase::LoadSessionInitialized(
+ const AccountId& account_id) const {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+
+ const base::DictionaryValue* prefs_session_initialized =
+ GetLocalState()->GetDictionary(kUserSessionInitialized);
+ bool session_initialized = false;
+ if (prefs_session_initialized) {
+ prefs_session_initialized->GetBooleanWithoutPathExpansion(
+ account_id.GetUserEmail(), &session_initialized);
+ }
+ return session_initialized;
+}
+
void UserManagerBase::RemoveNonCryptohomeData(const AccountId& account_id) {
PrefService* prefs = GetLocalState();
DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
@@ -961,6 +1028,11 @@ void UserManagerBase::RemoveNonCryptohomeData(const AccountId& account_id) {
prefs_force_online_update->RemoveWithoutPathExpansion(
account_id.GetUserEmail(), nullptr);
+ DictionaryPrefUpdate prefs_session_initialized(prefs,
+ kUserSessionInitialized);
+ prefs_session_initialized->RemoveWithoutPathExpansion(
+ account_id.GetUserEmail(), nullptr);
+
known_user::RemovePrefs(account_id);
const AccountId last_active_user =

Powered by Google App Engine
This is Rietveld 408576698