OLD | NEW |
| (Empty) |
1 // Copyright 2013 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/multi_profile_user_controller.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/prefs/pref_change_registrar.h" | |
10 #include "base/prefs/pref_registry_simple.h" | |
11 #include "base/prefs/pref_service.h" | |
12 #include "base/prefs/scoped_user_pref_update.h" | |
13 #include "chrome/browser/chromeos/login/multi_profile_user_controller_delegate.h
" | |
14 #include "chrome/browser/chromeos/login/user.h" | |
15 #include "chrome/browser/chromeos/login/user_manager.h" | |
16 #include "chrome/browser/chromeos/policy/policy_cert_service.h" | |
17 #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" | |
18 #include "chrome/browser/prefs/pref_service_syncable.h" | |
19 #include "chrome/browser/profiles/profile.h" | |
20 #include "chrome/common/pref_names.h" | |
21 #include "google_apis/gaia/gaia_auth_util.h" | |
22 | |
23 namespace chromeos { | |
24 | |
25 namespace { | |
26 | |
27 std::string SanitizeBehaviorValue(const std::string& value) { | |
28 if (value == MultiProfileUserController::kBehaviorUnrestricted || | |
29 value == MultiProfileUserController::kBehaviorPrimaryOnly || | |
30 value == MultiProfileUserController::kBehaviorNotAllowed) { | |
31 return value; | |
32 } | |
33 | |
34 return std::string(MultiProfileUserController::kBehaviorUnrestricted); | |
35 } | |
36 | |
37 } // namespace | |
38 | |
39 // static | |
40 const char MultiProfileUserController::kBehaviorUnrestricted[] = "unrestricted"; | |
41 const char MultiProfileUserController::kBehaviorPrimaryOnly[] = "primary-only"; | |
42 const char MultiProfileUserController::kBehaviorNotAllowed[] = "not-allowed"; | |
43 | |
44 MultiProfileUserController::MultiProfileUserController( | |
45 MultiProfileUserControllerDelegate* delegate, | |
46 PrefService* local_state) | |
47 : delegate_(delegate), | |
48 local_state_(local_state) { | |
49 } | |
50 | |
51 MultiProfileUserController::~MultiProfileUserController() {} | |
52 | |
53 // static | |
54 void MultiProfileUserController::RegisterPrefs( | |
55 PrefRegistrySimple* registry) { | |
56 registry->RegisterDictionaryPref(prefs::kCachedMultiProfileUserBehavior); | |
57 } | |
58 | |
59 // static | |
60 void MultiProfileUserController::RegisterProfilePrefs( | |
61 user_prefs::PrefRegistrySyncable* registry) { | |
62 registry->RegisterStringPref( | |
63 prefs::kMultiProfileUserBehavior, | |
64 kBehaviorUnrestricted, | |
65 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
66 registry->RegisterBooleanPref( | |
67 prefs::kMultiProfileNeverShowIntro, | |
68 false, | |
69 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | |
70 registry->RegisterBooleanPref( | |
71 prefs::kMultiProfileWarningShowDismissed, | |
72 false, | |
73 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | |
74 } | |
75 | |
76 MultiProfileUserController::UserAllowedInSessionResult | |
77 MultiProfileUserController::IsUserAllowedInSession( | |
78 const std::string& user_email) const { | |
79 UserManager* user_manager = UserManager::Get(); | |
80 CHECK(user_manager); | |
81 | |
82 const User* primary_user = user_manager->GetPrimaryUser(); | |
83 std::string primary_user_email; | |
84 if (primary_user) | |
85 primary_user_email = primary_user->email(); | |
86 | |
87 // Always allow if there is no primary user or user being checked is the | |
88 // primary user. | |
89 if (primary_user_email.empty() || primary_user_email == user_email) | |
90 return ALLOWED; | |
91 | |
92 // Owner is not allowed to be secondary user. | |
93 if (user_manager->GetOwnerEmail() == user_email) | |
94 return NOT_ALLOWED_OWNER_AS_SECONDARY; | |
95 | |
96 // Don't allow profiles potentially tainted by data fetched with policy-pushed | |
97 // certificates to join a multiprofile session. | |
98 if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(user_email)) | |
99 return NOT_ALLOWED_POLICY_CERT_TAINTED; | |
100 | |
101 // Don't allow any secondary profiles if the primary profile is tainted. | |
102 if (policy::PolicyCertServiceFactory::UsedPolicyCertificates( | |
103 primary_user_email)) { | |
104 // Check directly in local_state before checking if the primary user has | |
105 // a PolicyCertService. His profile may have been tainted previously though | |
106 // he didn't get a PolicyCertService created for this session. | |
107 return NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED; | |
108 } | |
109 | |
110 // If the primary profile already has policy certificates installed but hasn't | |
111 // used them yet then it can become tainted at any time during this session; | |
112 // disable secondary profiles in this case too. | |
113 Profile* primary_user_profile = | |
114 primary_user ? user_manager->GetProfileByUser(primary_user) : NULL; | |
115 policy::PolicyCertService* service = | |
116 primary_user_profile ? policy::PolicyCertServiceFactory::GetForProfile( | |
117 primary_user_profile) | |
118 : NULL; | |
119 if (service && service->has_policy_certificates()) | |
120 return NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED; | |
121 | |
122 // No user is allowed if the primary user policy forbids it. | |
123 const std::string primary_user_behavior = | |
124 primary_user_profile->GetPrefs()->GetString( | |
125 prefs::kMultiProfileUserBehavior); | |
126 if (primary_user_behavior == kBehaviorNotAllowed) | |
127 return NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS; | |
128 | |
129 // The user must have 'unrestricted' policy to be a secondary user. | |
130 const std::string behavior = GetCachedValue(user_email); | |
131 return behavior == kBehaviorUnrestricted ? ALLOWED : | |
132 NOT_ALLOWED_POLICY_FORBIDS; | |
133 } | |
134 | |
135 void MultiProfileUserController::StartObserving(Profile* user_profile) { | |
136 // Profile name could be empty during tests. | |
137 if (user_profile->GetProfileName().empty()) | |
138 return; | |
139 | |
140 scoped_ptr<PrefChangeRegistrar> registrar(new PrefChangeRegistrar); | |
141 registrar->Init(user_profile->GetPrefs()); | |
142 registrar->Add( | |
143 prefs::kMultiProfileUserBehavior, | |
144 base::Bind(&MultiProfileUserController::OnUserPrefChanged, | |
145 base::Unretained(this), | |
146 user_profile)); | |
147 pref_watchers_.push_back(registrar.release()); | |
148 | |
149 OnUserPrefChanged(user_profile); | |
150 } | |
151 | |
152 void MultiProfileUserController::RemoveCachedValues( | |
153 const std::string& user_email) { | |
154 DictionaryPrefUpdate update(local_state_, | |
155 prefs::kCachedMultiProfileUserBehavior); | |
156 update->RemoveWithoutPathExpansion(user_email, NULL); | |
157 policy::PolicyCertServiceFactory::ClearUsedPolicyCertificates(user_email); | |
158 } | |
159 | |
160 std::string MultiProfileUserController::GetCachedValue( | |
161 const std::string& user_email) const { | |
162 const base::DictionaryValue* dict = | |
163 local_state_->GetDictionary(prefs::kCachedMultiProfileUserBehavior); | |
164 std::string value; | |
165 if (dict && dict->GetStringWithoutPathExpansion(user_email, &value)) | |
166 return SanitizeBehaviorValue(value); | |
167 | |
168 return std::string(kBehaviorUnrestricted); | |
169 } | |
170 | |
171 void MultiProfileUserController::SetCachedValue( | |
172 const std::string& user_email, | |
173 const std::string& behavior) { | |
174 DictionaryPrefUpdate update(local_state_, | |
175 prefs::kCachedMultiProfileUserBehavior); | |
176 update->SetStringWithoutPathExpansion(user_email, | |
177 SanitizeBehaviorValue(behavior)); | |
178 } | |
179 | |
180 void MultiProfileUserController::CheckSessionUsers() { | |
181 const UserList& users = UserManager::Get()->GetLoggedInUsers(); | |
182 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { | |
183 if (IsUserAllowedInSession((*it)->email()) != ALLOWED) { | |
184 delegate_->OnUserNotAllowed((*it)->email()); | |
185 return; | |
186 } | |
187 } | |
188 } | |
189 | |
190 void MultiProfileUserController::OnUserPrefChanged( | |
191 Profile* user_profile) { | |
192 std::string user_email = user_profile->GetProfileName(); | |
193 CHECK(!user_email.empty()); | |
194 user_email = gaia::CanonicalizeEmail(user_email); | |
195 | |
196 PrefService* prefs = user_profile->GetPrefs(); | |
197 if (prefs->FindPreference(prefs::kMultiProfileUserBehavior) | |
198 ->IsDefaultValue()) { | |
199 // Migration code to clear cached default behavior. | |
200 // TODO(xiyuan): Remove this after M35. | |
201 DictionaryPrefUpdate update(local_state_, | |
202 prefs::kCachedMultiProfileUserBehavior); | |
203 update->RemoveWithoutPathExpansion(user_email, NULL); | |
204 } else { | |
205 const std::string behavior = | |
206 prefs->GetString(prefs::kMultiProfileUserBehavior); | |
207 SetCachedValue(user_email, behavior); | |
208 } | |
209 | |
210 CheckSessionUsers(); | |
211 } | |
212 | |
213 } // namespace chromeos | |
OLD | NEW |