OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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, ®ular_users, | 811 ParseUserList(*prefs_regular_users, device_local_accounts_set, ®ular_users, |
784 ®ular_users_set); | 812 ®ular_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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |