ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / chromeos / login / users / multi_profile_user_controller.cc
blob6a3a1c8b4cc92bad2ca965e28490f25b7e3d4cae
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.
5 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
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/users/multi_profile_user_controller_delegate.h"
14 #include "chrome/browser/chromeos/policy/policy_cert_service.h"
15 #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "chrome/browser/prefs/pref_service_syncable.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/pref_names.h"
20 #include "components/user_manager/user.h"
21 #include "components/user_manager/user_manager.h"
22 #include "google_apis/gaia/gaia_auth_util.h"
24 namespace chromeos {
26 namespace {
28 std::string SanitizeBehaviorValue(const std::string& value) {
29 if (value == MultiProfileUserController::kBehaviorUnrestricted ||
30 value == MultiProfileUserController::kBehaviorPrimaryOnly ||
31 value == MultiProfileUserController::kBehaviorNotAllowed) {
32 return value;
35 return std::string(MultiProfileUserController::kBehaviorUnrestricted);
38 bool SetUserAllowedReason(
39 MultiProfileUserController::UserAllowedInSessionReason* reason,
40 MultiProfileUserController::UserAllowedInSessionReason value) {
41 if (reason)
42 *reason = value;
43 return value == MultiProfileUserController::ALLOWED;
46 } // namespace
48 // static
49 const char MultiProfileUserController::kBehaviorUnrestricted[] = "unrestricted";
50 const char MultiProfileUserController::kBehaviorPrimaryOnly[] = "primary-only";
51 const char MultiProfileUserController::kBehaviorNotAllowed[] = "not-allowed";
53 // Note: this policy value is not a real one an is only returned locally for
54 // owner users instead of default one kBehaviorUnrestricted.
55 const char MultiProfileUserController::kBehaviorOwnerPrimaryOnly[] =
56 "owner-primary-only";
58 MultiProfileUserController::MultiProfileUserController(
59 MultiProfileUserControllerDelegate* delegate,
60 PrefService* local_state)
61 : delegate_(delegate),
62 local_state_(local_state) {
65 MultiProfileUserController::~MultiProfileUserController() {}
67 // static
68 void MultiProfileUserController::RegisterPrefs(
69 PrefRegistrySimple* registry) {
70 registry->RegisterDictionaryPref(prefs::kCachedMultiProfileUserBehavior);
73 // static
74 void MultiProfileUserController::RegisterProfilePrefs(
75 user_prefs::PrefRegistrySyncable* registry) {
76 registry->RegisterStringPref(
77 prefs::kMultiProfileUserBehavior,
78 kBehaviorUnrestricted,
79 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
80 registry->RegisterBooleanPref(
81 prefs::kMultiProfileNeverShowIntro,
82 false,
83 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
84 registry->RegisterBooleanPref(
85 prefs::kMultiProfileWarningShowDismissed,
86 false,
87 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
90 // static
91 MultiProfileUserController::UserAllowedInSessionReason
92 MultiProfileUserController::GetPrimaryUserPolicy() {
93 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
94 CHECK(user_manager);
96 const user_manager::User* user = user_manager->GetPrimaryUser();
97 if (!user)
98 return ALLOWED;
100 // Don't allow any secondary profiles if the primary profile is tainted.
101 if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(user->email())) {
102 // Check directly in local_state before checking if the primary user has
103 // a PolicyCertService. His profile may have been tainted previously though
104 // he didn't get a PolicyCertService created for this session.
105 return NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED;
108 Profile* profile = ProfileHelper::Get()->GetProfileByUser(user);
109 if (!profile)
110 return ALLOWED;
112 // If the primary profile already has policy certificates installed but
113 // hasn't used them yet then it can become tainted at any time during this
114 // session disable secondary profiles in this case too.
115 policy::PolicyCertService* service =
116 policy::PolicyCertServiceFactory::GetForProfile(profile);
117 if (service && service->has_policy_certificates())
118 return NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED;
120 // No user is allowed if the primary user policy forbids it.
121 const std::string behavior = profile->GetPrefs()->GetString(
122 prefs::kMultiProfileUserBehavior);
123 if (behavior == kBehaviorNotAllowed)
124 return NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS;
126 return ALLOWED;
129 bool MultiProfileUserController::IsUserAllowedInSession(
130 const std::string& user_email,
131 MultiProfileUserController::UserAllowedInSessionReason* reason) const {
132 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
133 CHECK(user_manager);
135 const user_manager::User* primary_user = user_manager->GetPrimaryUser();
136 std::string primary_user_email;
137 if (primary_user)
138 primary_user_email = primary_user->email();
140 // Always allow if there is no primary user or user being checked is the
141 // primary user.
142 if (primary_user_email.empty() || primary_user_email == user_email)
143 return SetUserAllowedReason(reason, ALLOWED);
145 // Don't allow profiles potentially tainted by data fetched with policy-pushed
146 // certificates to join a multiprofile session.
147 if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(user_email))
148 return SetUserAllowedReason(reason, NOT_ALLOWED_POLICY_CERT_TAINTED);
150 UserAllowedInSessionReason primary_user_policy = GetPrimaryUserPolicy();
151 if (primary_user_policy != ALLOWED)
152 return SetUserAllowedReason(reason, primary_user_policy);
154 // The user must have 'unrestricted' policy to be a secondary user.
155 const std::string behavior = GetCachedValue(user_email);
156 return SetUserAllowedReason(
157 reason,
158 behavior == kBehaviorUnrestricted ? ALLOWED : NOT_ALLOWED_POLICY_FORBIDS);
161 void MultiProfileUserController::StartObserving(Profile* user_profile) {
162 // Profile name could be empty during tests.
163 if (user_profile->GetProfileUserName().empty())
164 return;
166 scoped_ptr<PrefChangeRegistrar> registrar(new PrefChangeRegistrar);
167 registrar->Init(user_profile->GetPrefs());
168 registrar->Add(
169 prefs::kMultiProfileUserBehavior,
170 base::Bind(&MultiProfileUserController::OnUserPrefChanged,
171 base::Unretained(this),
172 user_profile));
173 pref_watchers_.push_back(registrar.release());
175 OnUserPrefChanged(user_profile);
178 void MultiProfileUserController::RemoveCachedValues(
179 const std::string& user_email) {
180 DictionaryPrefUpdate update(local_state_,
181 prefs::kCachedMultiProfileUserBehavior);
182 update->RemoveWithoutPathExpansion(user_email, NULL);
183 policy::PolicyCertServiceFactory::ClearUsedPolicyCertificates(user_email);
186 std::string MultiProfileUserController::GetCachedValue(
187 const std::string& user_email) const {
188 const base::DictionaryValue* dict =
189 local_state_->GetDictionary(prefs::kCachedMultiProfileUserBehavior);
190 std::string value;
191 if (dict && dict->GetStringWithoutPathExpansion(user_email, &value))
192 return SanitizeBehaviorValue(value);
194 return std::string(kBehaviorUnrestricted);
197 void MultiProfileUserController::SetCachedValue(
198 const std::string& user_email,
199 const std::string& behavior) {
200 DictionaryPrefUpdate update(local_state_,
201 prefs::kCachedMultiProfileUserBehavior);
202 update->SetStringWithoutPathExpansion(user_email,
203 SanitizeBehaviorValue(behavior));
206 void MultiProfileUserController::CheckSessionUsers() {
207 const user_manager::UserList& users =
208 user_manager::UserManager::Get()->GetLoggedInUsers();
209 for (user_manager::UserList::const_iterator it = users.begin();
210 it != users.end();
211 ++it) {
212 if (!IsUserAllowedInSession((*it)->email(), NULL)) {
213 delegate_->OnUserNotAllowed((*it)->email());
214 return;
219 void MultiProfileUserController::OnUserPrefChanged(
220 Profile* user_profile) {
221 std::string user_email = user_profile->GetProfileUserName();
222 CHECK(!user_email.empty());
223 user_email = gaia::CanonicalizeEmail(user_email);
225 PrefService* prefs = user_profile->GetPrefs();
226 if (prefs->FindPreference(prefs::kMultiProfileUserBehavior)
227 ->IsDefaultValue()) {
228 // Migration code to clear cached default behavior.
229 // TODO(xiyuan): Remove this after M35.
230 DictionaryPrefUpdate update(local_state_,
231 prefs::kCachedMultiProfileUserBehavior);
232 update->RemoveWithoutPathExpansion(user_email, NULL);
233 } else {
234 const std::string behavior =
235 prefs->GetString(prefs::kMultiProfileUserBehavior);
236 SetCachedValue(user_email, behavior);
239 CheckSessionUsers();
242 } // namespace chromeos