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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "chrome/browser/supervised_user/supervised_user_service.h"
18 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
19 #include "chromeos/settings/cros_settings_names.h"
20 #include "components/prefs/pref_registry_simple.h"
21 #include "components/prefs/pref_service.h"
22 #include "components/prefs/scoped_user_pref_update.h"
23 #include "components/user_manager/user_type.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "google_apis/gaia/gaia_auth_util.h"
26
27 using content::BrowserThread;
28
29 namespace {
30
31 // Names for pref keys in Local State.
32 // A map from supervised user local user id to sync user id.
33 const char kSupervisedUserSyncId[] = "ManagedUserSyncId";
34
35 // A map from supervised user id to manager user id.
36 const char kSupervisedUserManagers[] = "ManagedUserManagers";
37
38 // A map from supervised user id to manager display name.
39 const char kSupervisedUserManagerNames[] = "ManagedUserManagerNames";
40
41 // A map from supervised user id to manager display e-mail.
42 const char kSupervisedUserManagerDisplayEmails[] =
43 "ManagedUserManagerDisplayEmails";
44
45 // A vector pref of the supervised accounts defined on this device, that had
46 // not logged in yet.
47 const char kSupervisedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
48
49 // A map from user id to password schema id.
50 const char kSupervisedUserPasswordSchema[] = "SupervisedUserPasswordSchema";
51
52 // A map from user id to password salt.
53 const char kSupervisedUserPasswordSalt[] = "SupervisedUserPasswordSalt";
54
55 // A map from user id to password revision.
56 const char kSupervisedUserPasswordRevision[] = "SupervisedUserPasswordRevision";
57
58 // A map from user id to flag indicating if password should be updated upon
59 // signin.
60 const char kSupervisedUserNeedPasswordUpdate[] =
61 "SupervisedUserNeedPasswordUpdate";
62
63 // A map from user id to flag indicating if cryptohome does not have signature
64 // key.
65 const char kSupervisedUserIncompleteKey[] = "SupervisedUserHasIncompleteKey";
66
67 } // namespace
68
69 namespace chromeos {
70
71 const char kSchemaVersion[] = "SchemaVersion";
72 const char kPasswordRevision[] = "PasswordRevision";
73 const char kSalt[] = "PasswordSalt";
74 const char kRequirePasswordUpdate[] = "RequirePasswordUpdate";
75 const char kHasIncompleteKey[] = "HasIncompleteKey";
76
77 // static
RegisterLocalStatePrefs(PrefRegistrySimple * registry)78 void SupervisedUserManager::RegisterLocalStatePrefs(
79 PrefRegistrySimple* registry) {
80 registry->RegisterListPref(kSupervisedUsersFirstRun);
81 registry->RegisterDictionaryPref(kSupervisedUserSyncId);
82 registry->RegisterDictionaryPref(kSupervisedUserManagers);
83 registry->RegisterDictionaryPref(kSupervisedUserManagerNames);
84 registry->RegisterDictionaryPref(kSupervisedUserManagerDisplayEmails);
85
86 registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
87 registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
88 registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
89
90 registry->RegisterDictionaryPref(kSupervisedUserNeedPasswordUpdate);
91 registry->RegisterDictionaryPref(kSupervisedUserIncompleteKey);
92 }
93
SupervisedUserManagerImpl(ChromeUserManagerImpl * owner)94 SupervisedUserManagerImpl::SupervisedUserManagerImpl(
95 ChromeUserManagerImpl* owner)
96 : owner_(owner), cros_settings_(CrosSettings::Get()) {
97 // SupervisedUserManager instance should be used only on UI thread.
98 // (or in unit_tests)
99 if (base::ThreadTaskRunnerHandle::IsSet())
100 DCHECK_CURRENTLY_ON(BrowserThread::UI);
101 }
102
~SupervisedUserManagerImpl()103 SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {}
104
GetUserSyncId(const std::string & user_id) const105 std::string SupervisedUserManagerImpl::GetUserSyncId(
106 const std::string& user_id) const {
107 std::string result;
108 GetUserStringValue(user_id, kSupervisedUserSyncId, &result);
109 return result;
110 }
111
GetManagerDisplayName(const std::string & user_id) const112 base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
113 const std::string& user_id) const {
114 PrefService* local_state = g_browser_process->local_state();
115 const base::DictionaryValue* manager_names =
116 local_state->GetDictionary(kSupervisedUserManagerNames);
117 base::string16 result;
118 if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
119 !result.empty())
120 return result;
121 return base::UTF8ToUTF16(GetManagerDisplayEmail(user_id));
122 }
123
GetManagerUserId(const std::string & user_id) const124 std::string SupervisedUserManagerImpl::GetManagerUserId(
125 const std::string& user_id) const {
126 std::string result;
127 GetUserStringValue(user_id, kSupervisedUserManagers, &result);
128 return result;
129 }
130
GetManagerDisplayEmail(const std::string & user_id) const131 std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
132 const std::string& user_id) const {
133 std::string result;
134 if (GetUserStringValue(user_id, kSupervisedUserManagerDisplayEmails,
135 &result) &&
136 !result.empty())
137 return result;
138 return GetManagerUserId(user_id);
139 }
140
GetPasswordInformation(const std::string & user_id,base::DictionaryValue * result)141 void SupervisedUserManagerImpl::GetPasswordInformation(
142 const std::string& user_id,
143 base::DictionaryValue* result) {
144 int value;
145 if (GetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, &value))
146 result->SetKey(kSchemaVersion, base::Value(value));
147 if (GetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, &value))
148 result->SetKey(kPasswordRevision, base::Value(value));
149
150 bool flag;
151 if (GetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, &flag))
152 result->SetKey(kRequirePasswordUpdate, base::Value(flag));
153 if (GetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, &flag))
154 result->SetKey(kHasIncompleteKey, base::Value(flag));
155
156 std::string salt;
157 if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
158 result->SetKey(kSalt, base::Value(salt));
159 }
160
SetPasswordInformation(const std::string & user_id,const base::DictionaryValue * password_info)161 void SupervisedUserManagerImpl::SetPasswordInformation(
162 const std::string& user_id,
163 const base::DictionaryValue* password_info) {
164 int value;
165 if (password_info->GetIntegerWithoutPathExpansion(kSchemaVersion, &value))
166 SetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, value);
167 if (password_info->GetIntegerWithoutPathExpansion(kPasswordRevision, &value))
168 SetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, value);
169
170 bool flag;
171 if (password_info->GetBooleanWithoutPathExpansion(kRequirePasswordUpdate,
172 &flag)) {
173 SetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, flag);
174 }
175 if (password_info->GetBooleanWithoutPathExpansion(kHasIncompleteKey, &flag))
176 SetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, flag);
177
178 std::string salt;
179 if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
180 SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
181 g_browser_process->local_state()->CommitPendingWrite();
182 }
183
GetUserStringValue(const std::string & user_id,const char * key,std::string * out_value) const184 bool SupervisedUserManagerImpl::GetUserStringValue(
185 const std::string& user_id,
186 const char* key,
187 std::string* out_value) const {
188 PrefService* local_state = g_browser_process->local_state();
189 const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
190 return dictionary->GetStringWithoutPathExpansion(user_id, out_value);
191 }
192
GetUserIntegerValue(const std::string & user_id,const char * key,int * out_value) const193 bool SupervisedUserManagerImpl::GetUserIntegerValue(const std::string& user_id,
194 const char* key,
195 int* out_value) const {
196 PrefService* local_state = g_browser_process->local_state();
197 const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
198 return dictionary->GetIntegerWithoutPathExpansion(user_id, out_value);
199 }
200
GetUserBooleanValue(const std::string & user_id,const char * key,bool * out_value) const201 bool SupervisedUserManagerImpl::GetUserBooleanValue(const std::string& user_id,
202 const char* key,
203 bool* out_value) const {
204 PrefService* local_state = g_browser_process->local_state();
205 const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
206 return dictionary->GetBooleanWithoutPathExpansion(user_id, out_value);
207 }
208
SetUserStringValue(const std::string & user_id,const char * key,const std::string & value)209 void SupervisedUserManagerImpl::SetUserStringValue(const std::string& user_id,
210 const char* key,
211 const std::string& value) {
212 PrefService* local_state = g_browser_process->local_state();
213 DictionaryPrefUpdate update(local_state, key);
214 update->SetKey(user_id, base::Value(value));
215 }
216
SetUserIntegerValue(const std::string & user_id,const char * key,const int value)217 void SupervisedUserManagerImpl::SetUserIntegerValue(const std::string& user_id,
218 const char* key,
219 const int value) {
220 PrefService* local_state = g_browser_process->local_state();
221 DictionaryPrefUpdate update(local_state, key);
222 update->SetKey(user_id, base::Value(value));
223 }
224
SetUserBooleanValue(const std::string & user_id,const char * key,const bool value)225 void SupervisedUserManagerImpl::SetUserBooleanValue(const std::string& user_id,
226 const char* key,
227 const bool value) {
228 PrefService* local_state = g_browser_process->local_state();
229 DictionaryPrefUpdate update(local_state, key);
230 update->SetKey(user_id, base::Value(value));
231 }
232
RemoveNonCryptohomeData(const std::string & user_id)233 void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
234 const std::string& user_id) {
235 PrefService* prefs = g_browser_process->local_state();
236 ListPrefUpdate prefs_new_users_update(prefs, kSupervisedUsersFirstRun);
237 prefs_new_users_update->Remove(base::Value(user_id), NULL);
238
239 CleanPref(user_id, kSupervisedUserSyncId);
240 CleanPref(user_id, kSupervisedUserManagers);
241 CleanPref(user_id, kSupervisedUserManagerNames);
242 CleanPref(user_id, kSupervisedUserManagerDisplayEmails);
243 CleanPref(user_id, kSupervisedUserPasswordSalt);
244 CleanPref(user_id, kSupervisedUserPasswordSchema);
245 CleanPref(user_id, kSupervisedUserPasswordRevision);
246 CleanPref(user_id, kSupervisedUserNeedPasswordUpdate);
247 CleanPref(user_id, kSupervisedUserIncompleteKey);
248 }
249
CleanPref(const std::string & user_id,const char * key)250 void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
251 const char* key) {
252 PrefService* prefs = g_browser_process->local_state();
253 DictionaryPrefUpdate dict_update(prefs, key);
254 dict_update->RemoveWithoutPathExpansion(user_id, NULL);
255 }
256
CheckForFirstRun(const std::string & user_id)257 bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
258 ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
259 kSupervisedUsersFirstRun);
260 return prefs_new_users_update->Remove(base::Value(user_id), NULL);
261 }
262
UpdateManagerName(const std::string & manager_id,const base::string16 & new_display_name)263 void SupervisedUserManagerImpl::UpdateManagerName(
264 const std::string& manager_id,
265 const base::string16& new_display_name) {
266 PrefService* local_state = g_browser_process->local_state();
267
268 const base::DictionaryValue* manager_ids =
269 local_state->GetDictionary(kSupervisedUserManagers);
270
271 DictionaryPrefUpdate manager_name_update(local_state,
272 kSupervisedUserManagerNames);
273 for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
274 it.Advance()) {
275 std::string user_id;
276 bool has_manager_id = it.value().GetAsString(&user_id);
277 DCHECK(has_manager_id);
278 if (user_id == manager_id) {
279 manager_name_update->SetWithoutPathExpansion(
280 it.key(), std::make_unique<base::Value>(new_display_name));
281 }
282 }
283 }
284
285 } // namespace chromeos
286