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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/user_manager/user_manager_base.h" 5 #include "components/user_manager/user_manager_base.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 // A dictionary that maps user IDs to the displayed (non-canonical) emails. 47 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
48 const char kUserDisplayEmail[] = "UserDisplayEmail"; 48 const char kUserDisplayEmail[] = "UserDisplayEmail";
49 49
50 // A dictionary that maps user IDs to OAuth token presence flag. 50 // A dictionary that maps user IDs to OAuth token presence flag.
51 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus"; 51 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
52 52
53 // A dictionary that maps user IDs to a flag indicating whether online 53 // A dictionary that maps user IDs to a flag indicating whether online
54 // authentication against GAIA should be enforced during the next sign-in. 54 // authentication against GAIA should be enforced during the next sign-in.
55 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin"; 55 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
56 56
57 // A dictionary that maps user IDs to a flag indicating whether session
58 // initialization has been completed at least once on this session. If the
59 // flag is set to false (or the user ID is missing from the dictionary) then
60 // the session did not complete initialization and the next signin should
61 // require a network connection (for example, to register for policy).
62 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
63
57 // A dictionary that maps user ID to the user type. 64 // A dictionary that maps user ID to the user type.
58 const char kUserType[] = "UserType"; 65 const char kUserType[] = "UserType";
59 66
60 // A string pref containing the ID of the last user who logged in if it was 67 // A string pref containing the ID of the last user who logged in if it was
61 // a user with gaia account (regular) or an empty string if it was another type 68 // a user with gaia account (regular) or an empty string if it was another type
62 // of user (guest, kiosk, public account, etc.). 69 // of user (guest, kiosk, public account, etc.).
63 const char kLastLoggedInGaiaUser[] = "LastLoggedInRegularUser"; 70 const char kLastLoggedInGaiaUser[] = "LastLoggedInRegularUser";
64 71
65 // A string pref containing the ID of the last active user. 72 // A string pref containing the ID of the last active user.
66 // In case of browser crash, this pref will be used to set active user after 73 // In case of browser crash, this pref will be used to set active user after
67 // session restore. 74 // session restore.
68 const char kLastActiveUser[] = "LastActiveUser"; 75 const char kLastActiveUser[] = "LastActiveUser";
69 76
70 // Upper bound for a histogram metric reporting the amount of time between 77 // Upper bound for a histogram metric reporting the amount of time between
71 // one regular user logging out and a different regular user logging in. 78 // one regular user logging out and a different regular user logging in.
72 const int kLogoutToLoginDelayMaxSec = 1800; 79 const int kLogoutToLoginDelayMaxSec = 1800;
73 80
74 } // namespace 81 } // namespace
75 82
76 // static 83 // static
77 void UserManagerBase::RegisterPrefs(PrefRegistrySimple* registry) { 84 void UserManagerBase::RegisterPrefs(PrefRegistrySimple* registry) {
78 registry->RegisterListPref(kRegularUsers); 85 registry->RegisterListPref(kRegularUsers);
79 registry->RegisterStringPref(kLastLoggedInGaiaUser, std::string()); 86 registry->RegisterStringPref(kLastLoggedInGaiaUser, std::string());
80 registry->RegisterDictionaryPref(kUserDisplayName); 87 registry->RegisterDictionaryPref(kUserDisplayName);
81 registry->RegisterDictionaryPref(kUserGivenName); 88 registry->RegisterDictionaryPref(kUserGivenName);
82 registry->RegisterDictionaryPref(kUserDisplayEmail); 89 registry->RegisterDictionaryPref(kUserDisplayEmail);
83 registry->RegisterDictionaryPref(kUserOAuthTokenStatus); 90 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
84 registry->RegisterDictionaryPref(kUserForceOnlineSignin); 91 registry->RegisterDictionaryPref(kUserForceOnlineSignin);
92 registry->RegisterDictionaryPref(kUserSessionInitialized);
85 registry->RegisterDictionaryPref(kUserType); 93 registry->RegisterDictionaryPref(kUserType);
86 registry->RegisterStringPref(kLastActiveUser, std::string()); 94 registry->RegisterStringPref(kLastActiveUser, std::string());
87 95
88 known_user::RegisterPrefs(registry); 96 known_user::RegisterPrefs(registry);
89 } 97 }
90 98
91 UserManagerBase::UserManagerBase(scoped_refptr<base::TaskRunner> task_runner) 99 UserManagerBase::UserManagerBase(scoped_refptr<base::TaskRunner> task_runner)
92 : task_runner_(task_runner), weak_factory_(this) {} 100 : task_runner_(task_runner), weak_factory_(this) {}
93 101
94 UserManagerBase::~UserManagerBase() { 102 UserManagerBase::~UserManagerBase() {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 last_session_active_account_id_.clear(); 264 last_session_active_account_id_.clear();
257 } 265 }
258 266
259 void UserManagerBase::OnSessionStarted() { 267 void UserManagerBase::OnSessionStarted() {
260 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 268 DCHECK(task_runner_->RunsTasksOnCurrentThread());
261 269
262 CallUpdateLoginState(); 270 CallUpdateLoginState();
263 GetLocalState()->CommitPendingWrite(); 271 GetLocalState()->CommitPendingWrite();
264 } 272 }
265 273
274 void UserManagerBase::OnSessionInitialized(User* user) {
275 DCHECK(task_runner_->RunsTasksOnCurrentThread());
276
277 // Mark the user as having an initialized session.
278 user->set_session_initialized(true);
279
280 // 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
281 // cryptohome is to be treated as ephemeral.
282 if (IsUserNonCryptohomeDataEphemeral(user->GetAccountId()))
283 return;
284
285 {
286 DictionaryPrefUpdate user_session_initialized(GetLocalState(),
287 kUserSessionInitialized);
288 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.
289 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
290 }
291 GetLocalState()->CommitPendingWrite();
292 }
293
266 void UserManagerBase::RemoveUser(const AccountId& account_id, 294 void UserManagerBase::RemoveUser(const AccountId& account_id,
267 RemoveUserDelegate* delegate) { 295 RemoveUserDelegate* delegate) {
268 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 296 DCHECK(task_runner_->RunsTasksOnCurrentThread());
269 297
270 if (!CanUserBeRemoved(FindUser(account_id))) 298 if (!CanUserBeRemoved(FindUser(account_id)))
271 return; 299 return;
272 300
273 RemoveUserInternal(account_id, delegate); 301 RemoveUserInternal(account_id, delegate);
274 } 302 }
275 303
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 803
776 // Load public sessions first. 804 // Load public sessions first.
777 std::set<AccountId> device_local_accounts_set; 805 std::set<AccountId> device_local_accounts_set;
778 LoadDeviceLocalAccounts(&device_local_accounts_set); 806 LoadDeviceLocalAccounts(&device_local_accounts_set);
779 807
780 // Load regular users and supervised users. 808 // Load regular users and supervised users.
781 std::vector<AccountId> regular_users; 809 std::vector<AccountId> regular_users;
782 std::set<AccountId> regular_users_set; 810 std::set<AccountId> regular_users_set;
783 ParseUserList(*prefs_regular_users, device_local_accounts_set, &regular_users, 811 ParseUserList(*prefs_regular_users, device_local_accounts_set, &regular_users,
784 &regular_users_set); 812 &regular_users_set);
813
814 // If there is no stored SessionInitialized state, this either means this is
815 // the first boot on a new device or this is a migration from an older device
816 // 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
817 // on the device then we know this is a migration, so we will mark all of
818 // the sessions as initialized.
819 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
820 !local_state->HasPrefPath(kUserSessionInitialized);
821
785 for (std::vector<AccountId>::const_iterator it = regular_users.begin(); 822 for (std::vector<AccountId>::const_iterator it = regular_users.begin();
786 it != regular_users.end(); ++it) { 823 it != regular_users.end(); ++it) {
824 if (mark_user_sessions_initialized) {
825 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
826 DictionaryPrefUpdate user_session_initialized(GetLocalState(),
827 kUserSessionInitialized);
828 user_session_initialized->SetBooleanWithoutPathExpansion(
829 it->GetUserEmail(), true);
830 }
787 User* user = nullptr; 831 User* user = nullptr;
788 if (IsSupervisedAccountId(*it)) { 832 if (IsSupervisedAccountId(*it)) {
789 user = User::CreateSupervisedUser(*it); 833 user = User::CreateSupervisedUser(*it);
790 } else { 834 } else {
791 user = User::CreateRegularUser(*it); 835 user = User::CreateRegularUser(*it);
792 int user_type; 836 int user_type;
793 if (prefs_user_types->GetIntegerWithoutPathExpansion(it->GetUserEmail(), 837 if (prefs_user_types->GetIntegerWithoutPathExpansion(it->GetUserEmail(),
794 &user_type) && 838 &user_type) &&
795 user_type == USER_TYPE_CHILD) { 839 user_type == USER_TYPE_CHILD) {
796 ChangeUserChildStatus(user, true /* is child */); 840 ChangeUserChildStatus(user, true /* is child */);
797 } 841 }
798 } 842 }
799 const AccountId account_id = user->GetAccountId(); 843 const AccountId account_id = user->GetAccountId();
800 user->set_oauth_token_status(LoadUserOAuthStatus(*it)); 844 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
801 user->set_force_online_signin(LoadForceOnlineSignin(*it)); 845 user->set_force_online_signin(LoadForceOnlineSignin(*it));
846 user->set_session_initialized(LoadSessionInitialized(*it));
802 user->set_using_saml(known_user::IsUsingSAML(*it)); 847 user->set_using_saml(known_user::IsUsingSAML(*it));
803 users_.push_back(user); 848 users_.push_back(user);
804 849
805 base::string16 display_name; 850 base::string16 display_name;
806 if (prefs_display_names->GetStringWithoutPathExpansion(it->GetUserEmail(), 851 if (prefs_display_names->GetStringWithoutPathExpansion(it->GetUserEmail(),
807 &display_name)) { 852 &display_name)) {
808 user->set_display_name(display_name); 853 user->set_display_name(display_name);
809 } 854 }
810 855
811 base::string16 given_name; 856 base::string16 given_name;
812 if (prefs_given_names->GetStringWithoutPathExpansion(it->GetUserEmail(), 857 if (prefs_given_names->GetStringWithoutPathExpansion(it->GetUserEmail(),
813 &given_name)) { 858 &given_name)) {
814 user->set_given_name(given_name); 859 user->set_given_name(given_name);
815 } 860 }
816 861
817 std::string display_email; 862 std::string display_email;
818 if (prefs_display_emails->GetStringWithoutPathExpansion(it->GetUserEmail(), 863 if (prefs_display_emails->GetStringWithoutPathExpansion(it->GetUserEmail(),
819 &display_email)) { 864 &display_email)) {
820 user->set_display_email(display_email); 865 user->set_display_email(display_email);
821 } 866 }
822 } 867 }
823 868
869 if (mark_user_sessions_initialized)
870 local_state->CommitPendingWrite();
871
824 user_loading_stage_ = STAGE_LOADED; 872 user_loading_stage_ = STAGE_LOADED;
825 873
826 PerformPostUserListLoadingActions(); 874 PerformPostUserListLoadingActions();
827 } 875 }
828 876
829 UserList& UserManagerBase::GetUsersAndModify() { 877 UserList& UserManagerBase::GetUsersAndModify() {
830 EnsureUsersLoaded(); 878 EnsureUsersLoaded();
831 return users_; 879 return users_;
832 } 880 }
833 881
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 // Remove the user from the user list. 924 // Remove the user from the user list.
877 active_user_ = RemoveRegularOrSupervisedUserFromList(account_id); 925 active_user_ = RemoveRegularOrSupervisedUserFromList(account_id);
878 926
879 // If the user was not found on the user list, create a new user. 927 // If the user was not found on the user list, create a new user.
880 SetIsCurrentUserNew(!active_user_); 928 SetIsCurrentUserNew(!active_user_);
881 if (IsCurrentUserNew()) { 929 if (IsCurrentUserNew()) {
882 active_user_ = User::CreateRegularUser(account_id); 930 active_user_ = User::CreateRegularUser(account_id);
883 active_user_->set_oauth_token_status(LoadUserOAuthStatus(account_id)); 931 active_user_->set_oauth_token_status(LoadUserOAuthStatus(account_id));
884 SaveUserDisplayName(active_user_->GetAccountId(), 932 SaveUserDisplayName(active_user_->GetAccountId(),
885 base::UTF8ToUTF16(active_user_->GetAccountName(true))); 933 base::UTF8ToUTF16(active_user_->GetAccountName(true)));
934 DictionaryPrefUpdate user_session_initialized(GetLocalState(),
935 kUserSessionInitialized);
936 user_session_initialized->SetBooleanWithoutPathExpansion(
937 active_user_->GetAccountId().GetUserEmail(),
938 active_user_->session_initialized());
886 } 939 }
887 940
888 AddUserRecord(active_user_); 941 AddUserRecord(active_user_);
889 942
890 // Make sure that new data is persisted to Local State. 943 // Make sure that new data is persisted to Local State.
891 GetLocalState()->CommitPendingWrite(); 944 GetLocalState()->CommitPendingWrite();
892 } 945 }
893 946
894 void UserManagerBase::RegularUserLoggedInAsEphemeral( 947 void UserManagerBase::RegularUserLoggedInAsEphemeral(
895 const AccountId& account_id) { 948 const AccountId& account_id) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 const base::DictionaryValue* prefs_force_online = 985 const base::DictionaryValue* prefs_force_online =
933 GetLocalState()->GetDictionary(kUserForceOnlineSignin); 986 GetLocalState()->GetDictionary(kUserForceOnlineSignin);
934 bool force_online_signin = false; 987 bool force_online_signin = false;
935 if (prefs_force_online) { 988 if (prefs_force_online) {
936 prefs_force_online->GetBooleanWithoutPathExpansion( 989 prefs_force_online->GetBooleanWithoutPathExpansion(
937 account_id.GetUserEmail(), &force_online_signin); 990 account_id.GetUserEmail(), &force_online_signin);
938 } 991 }
939 return force_online_signin; 992 return force_online_signin;
940 } 993 }
941 994
995 bool UserManagerBase::LoadSessionInitialized(
996 const AccountId& account_id) const {
997 DCHECK(task_runner_->RunsTasksOnCurrentThread());
998
999 const base::DictionaryValue* prefs_session_initialized =
1000 GetLocalState()->GetDictionary(kUserSessionInitialized);
1001 bool session_initialized = false;
1002 if (prefs_session_initialized) {
1003 prefs_session_initialized->GetBooleanWithoutPathExpansion(
1004 account_id.GetUserEmail(), &session_initialized);
1005 }
1006 return session_initialized;
1007 }
1008
942 void UserManagerBase::RemoveNonCryptohomeData(const AccountId& account_id) { 1009 void UserManagerBase::RemoveNonCryptohomeData(const AccountId& account_id) {
943 PrefService* prefs = GetLocalState(); 1010 PrefService* prefs = GetLocalState();
944 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName); 1011 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
945 prefs_display_name_update->RemoveWithoutPathExpansion( 1012 prefs_display_name_update->RemoveWithoutPathExpansion(
946 account_id.GetUserEmail(), nullptr); 1013 account_id.GetUserEmail(), nullptr);
947 1014
948 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName); 1015 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
949 prefs_given_name_update->RemoveWithoutPathExpansion(account_id.GetUserEmail(), 1016 prefs_given_name_update->RemoveWithoutPathExpansion(account_id.GetUserEmail(),
950 nullptr); 1017 nullptr);
951 1018
952 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail); 1019 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
953 prefs_display_email_update->RemoveWithoutPathExpansion( 1020 prefs_display_email_update->RemoveWithoutPathExpansion(
954 account_id.GetUserEmail(), nullptr); 1021 account_id.GetUserEmail(), nullptr);
955 1022
956 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus); 1023 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
957 prefs_oauth_update->RemoveWithoutPathExpansion(account_id.GetUserEmail(), 1024 prefs_oauth_update->RemoveWithoutPathExpansion(account_id.GetUserEmail(),
958 nullptr); 1025 nullptr);
959 1026
960 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin); 1027 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
961 prefs_force_online_update->RemoveWithoutPathExpansion( 1028 prefs_force_online_update->RemoveWithoutPathExpansion(
962 account_id.GetUserEmail(), nullptr); 1029 account_id.GetUserEmail(), nullptr);
963 1030
1031 DictionaryPrefUpdate prefs_session_initialized(prefs,
1032 kUserSessionInitialized);
1033 prefs_session_initialized->RemoveWithoutPathExpansion(
1034 account_id.GetUserEmail(), nullptr);
1035
964 known_user::RemovePrefs(account_id); 1036 known_user::RemovePrefs(account_id);
965 1037
966 const AccountId last_active_user = 1038 const AccountId last_active_user =
967 AccountId::FromUserEmail(GetLocalState()->GetString(kLastActiveUser)); 1039 AccountId::FromUserEmail(GetLocalState()->GetString(kLastActiveUser));
968 if (account_id == last_active_user) 1040 if (account_id == last_active_user)
969 GetLocalState()->SetString(kLastActiveUser, std::string()); 1041 GetLocalState()->SetString(kLastActiveUser, std::string());
970 } 1042 }
971 1043
972 User* UserManagerBase::RemoveRegularOrSupervisedUserFromList( 1044 User* UserManagerBase::RemoveRegularOrSupervisedUserFromList(
973 const AccountId& account_id) { 1045 const AccountId& account_id) {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 } 1161 }
1090 1162
1091 void UserManagerBase::DeleteUser(User* user) { 1163 void UserManagerBase::DeleteUser(User* user) {
1092 const bool is_active_user = (user == active_user_); 1164 const bool is_active_user = (user == active_user_);
1093 delete user; 1165 delete user;
1094 if (is_active_user) 1166 if (is_active_user)
1095 active_user_ = nullptr; 1167 active_user_ = nullptr;
1096 } 1168 }
1097 1169
1098 } // namespace user_manager 1170 } // namespace user_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698