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/memory/scoped_ptr.h"
8 #include "base/run_loop.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
11 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller_delegate.h"
12 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
13 #include "chrome/browser/chromeos/policy/policy_cert_service.h"
14 #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
15 #include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
16 #include "chrome/browser/chromeos/profiles/profile_helper.h"
17 #include "chrome/browser/prefs/browser_prefs.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/scoped_testing_local_state.h"
20 #include "chrome/test/base/testing_browser_process.h"
21 #include "chrome/test/base/testing_pref_service_syncable.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "chrome/test/base/testing_profile_manager.h"
24 #include "components/user_manager/user_manager.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "net/cert/x509_certificate.h"
27 #include "testing/gtest/include/gtest/gtest.h"
33 const char* kUsers[] = {"a@gmail.com", "b@gmail.com" };
35 struct BehaviorTestCase {
37 const char* secondary;
38 MultiProfileUserController::UserAllowedInSessionReason
39 expected_primary_policy;
40 MultiProfileUserController::UserAllowedInSessionReason
41 expected_secondary_allowed;
44 const BehaviorTestCase kBehaviorTestCases[] = {
46 MultiProfileUserController::kBehaviorUnrestricted,
47 MultiProfileUserController::kBehaviorUnrestricted,
48 MultiProfileUserController::ALLOWED, MultiProfileUserController::ALLOWED,
51 MultiProfileUserController::kBehaviorUnrestricted,
52 MultiProfileUserController::kBehaviorPrimaryOnly,
53 MultiProfileUserController::ALLOWED,
54 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
57 MultiProfileUserController::kBehaviorUnrestricted,
58 MultiProfileUserController::kBehaviorNotAllowed,
59 MultiProfileUserController::ALLOWED,
60 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
63 MultiProfileUserController::kBehaviorPrimaryOnly,
64 MultiProfileUserController::kBehaviorUnrestricted,
65 MultiProfileUserController::ALLOWED, MultiProfileUserController::ALLOWED,
68 MultiProfileUserController::kBehaviorPrimaryOnly,
69 MultiProfileUserController::kBehaviorPrimaryOnly,
70 MultiProfileUserController::ALLOWED,
71 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
74 MultiProfileUserController::kBehaviorPrimaryOnly,
75 MultiProfileUserController::kBehaviorNotAllowed,
76 MultiProfileUserController::ALLOWED,
77 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
80 MultiProfileUserController::kBehaviorNotAllowed,
81 MultiProfileUserController::kBehaviorUnrestricted,
82 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
83 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
86 MultiProfileUserController::kBehaviorNotAllowed,
87 MultiProfileUserController::kBehaviorPrimaryOnly,
88 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
89 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
92 MultiProfileUserController::kBehaviorNotAllowed,
93 MultiProfileUserController::kBehaviorNotAllowed,
94 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
95 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
99 // Weak ptr to PolicyCertVerifier - object is freed in test destructor once
100 // we've ensured the profile has been shut down.
101 policy::PolicyCertVerifier* g_policy_cert_verifier_for_factory = NULL;
103 KeyedService* TestPolicyCertServiceFactory(content::BrowserContext* context) {
104 return policy::PolicyCertService::CreateForTesting(
106 g_policy_cert_verifier_for_factory,
107 user_manager::UserManager::Get()).release();
112 class MultiProfileUserControllerTest
113 : public testing::Test,
114 public MultiProfileUserControllerDelegate {
116 MultiProfileUserControllerTest()
117 : fake_user_manager_(new FakeUserManager),
118 user_manager_enabler_(fake_user_manager_),
119 user_not_allowed_count_(0) {}
120 virtual ~MultiProfileUserControllerTest() {}
122 virtual void SetUp() OVERRIDE {
123 profile_manager_.reset(
124 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
125 ASSERT_TRUE(profile_manager_->SetUp());
126 controller_.reset(new MultiProfileUserController(
127 this, TestingBrowserProcess::GetGlobal()->local_state()));
129 for (size_t i = 0; i < arraysize(kUsers); ++i) {
130 const std::string user_email(kUsers[i]);
131 const user_manager::User* user = fake_user_manager_->AddUser(user_email);
133 // Note that user profiles are created after user login in reality.
134 TestingProfile* user_profile =
135 profile_manager_->CreateTestingProfile(user_email);
136 user_profile->set_profile_name(user_email);
137 user_profiles_.push_back(user_profile);
139 ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
144 virtual void TearDown() OVERRIDE {
145 // Clear our cached pointer to the PolicyCertVerifier.
146 g_policy_cert_verifier_for_factory = NULL;
148 // We must ensure that the PolicyCertVerifier outlives the
149 // PolicyCertService so shutdown the profile here. Additionally, we need
150 // to run the message loop between freeing the PolicyCertService and
151 // freeing the PolicyCertVerifier (see
152 // PolicyCertService::OnTrustAnchorsChanged() which is called from
153 // PolicyCertService::Shutdown()).
155 profile_manager_.reset();
156 base::RunLoop().RunUntilIdle();
159 void LoginUser(size_t user_index) {
160 ASSERT_LT(user_index, arraysize(kUsers));
161 fake_user_manager_->LoginUser(kUsers[user_index]);
162 controller_->StartObserving(user_profiles_[user_index]);
165 void SetOwner(size_t user_index) {
166 fake_user_manager_->set_owner_email(kUsers[user_index]);
169 PrefService* GetUserPrefs(size_t user_index) {
170 return user_profiles_[user_index]->GetPrefs();
173 void SetPrefBehavior(size_t user_index, const std::string& behavior) {
174 GetUserPrefs(user_index)->SetString(prefs::kMultiProfileUserBehavior,
178 std::string GetCachedBehavior(size_t user_index) {
179 return controller_->GetCachedValue(kUsers[user_index]);
182 void SetCachedBehavior(size_t user_index,
183 const std::string& behavior) {
184 controller_->SetCachedValue(kUsers[user_index], behavior);
188 user_not_allowed_count_ = 0;
191 // MultiProfileUserControllerDeleagte overrides:
192 virtual void OnUserNotAllowed(const std::string& user_email) OVERRIDE {
193 ++user_not_allowed_count_;
196 MultiProfileUserController* controller() { return controller_.get(); }
197 int user_not_allowed_count() const { return user_not_allowed_count_; }
199 TestingProfile* profile(int index) {
200 return user_profiles_[index];
203 content::TestBrowserThreadBundle threads_;
204 scoped_ptr<policy::PolicyCertVerifier> cert_verifier_;
205 scoped_ptr<TestingProfileManager> profile_manager_;
206 FakeUserManager* fake_user_manager_; // Not owned
207 ScopedUserManagerEnabler user_manager_enabler_;
209 scoped_ptr<MultiProfileUserController> controller_;
211 std::vector<TestingProfile*> user_profiles_;
213 int user_not_allowed_count_;
215 DISALLOW_COPY_AND_ASSIGN(MultiProfileUserControllerTest);
218 // Tests that everyone is allowed before a session starts.
219 TEST_F(MultiProfileUserControllerTest, AllAllowedBeforeLogin) {
220 const char* kTestCases[] = {
221 MultiProfileUserController::kBehaviorUnrestricted,
222 MultiProfileUserController::kBehaviorPrimaryOnly,
223 MultiProfileUserController::kBehaviorNotAllowed,
225 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
226 SetCachedBehavior(0, kTestCases[i]);
227 MultiProfileUserController::UserAllowedInSessionReason reason;
228 EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason))
230 EXPECT_EQ(MultiProfileUserController::ALLOWED, reason) << "Case " << i;
231 EXPECT_EQ(MultiProfileUserController::ALLOWED,
232 MultiProfileUserController::GetPrimaryUserPolicy())
237 // Tests that invalid cache value would become the default "unrestricted".
238 TEST_F(MultiProfileUserControllerTest, InvalidCacheBecomesDefault) {
239 const char kBad[] = "some invalid value";
240 SetCachedBehavior(0, kBad);
241 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted,
242 GetCachedBehavior(0));
245 // Tests that cached behavior value changes with user pref after login.
246 TEST_F(MultiProfileUserControllerTest, CachedBehaviorUpdate) {
249 const char* kTestCases[] = {
250 MultiProfileUserController::kBehaviorUnrestricted,
251 MultiProfileUserController::kBehaviorPrimaryOnly,
252 MultiProfileUserController::kBehaviorNotAllowed,
253 MultiProfileUserController::kBehaviorUnrestricted,
255 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
256 SetPrefBehavior(0, kTestCases[i]);
257 EXPECT_EQ(kTestCases[i], GetCachedBehavior(0));
261 // Tests that compromised cache value would be fixed and pref value is checked
263 TEST_F(MultiProfileUserControllerTest, CompromisedCacheFixedOnLogin) {
264 SetPrefBehavior(0, MultiProfileUserController::kBehaviorPrimaryOnly);
265 SetCachedBehavior(0, MultiProfileUserController::kBehaviorUnrestricted);
266 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted,
267 GetCachedBehavior(0));
269 EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly,
270 GetCachedBehavior(0));
272 EXPECT_EQ(0, user_not_allowed_count());
273 SetPrefBehavior(1, MultiProfileUserController::kBehaviorPrimaryOnly);
274 SetCachedBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);
275 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted,
276 GetCachedBehavior(1));
278 EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly,
279 GetCachedBehavior(1));
280 EXPECT_EQ(1, user_not_allowed_count());
283 // Tests cases before the second user login.
284 TEST_F(MultiProfileUserControllerTest, IsSecondaryAllowed) {
287 for (size_t i = 0; i < arraysize(kBehaviorTestCases); ++i) {
288 SetPrefBehavior(0, kBehaviorTestCases[i].primary);
289 SetCachedBehavior(1, kBehaviorTestCases[i].secondary);
290 EXPECT_EQ(kBehaviorTestCases[i].expected_primary_policy,
291 MultiProfileUserController::GetPrimaryUserPolicy())
293 MultiProfileUserController::UserAllowedInSessionReason reason;
294 controller()->IsUserAllowedInSession(kUsers[1], &reason);
295 EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed, reason)
300 // Tests user behavior changes within a two-user session.
301 TEST_F(MultiProfileUserControllerTest, PrimaryBehaviorChange) {
305 for (size_t i = 0; i < arraysize(kBehaviorTestCases); ++i) {
306 SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted);
307 SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);
310 SetPrefBehavior(0, kBehaviorTestCases[i].primary);
311 SetPrefBehavior(1, kBehaviorTestCases[i].secondary);
312 if (user_not_allowed_count() == 0) {
313 EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed,
314 MultiProfileUserController::ALLOWED)
317 EXPECT_NE(kBehaviorTestCases[i].expected_secondary_allowed,
318 MultiProfileUserController::ALLOWED)
324 // Tests that owner could not be a secondary user.
325 TEST_F(MultiProfileUserControllerTest, NoSecondaryOwner) {
329 MultiProfileUserController::UserAllowedInSessionReason reason;
330 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
331 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY, reason);
333 EXPECT_EQ(0, user_not_allowed_count());
335 EXPECT_EQ(1, user_not_allowed_count());
338 TEST_F(MultiProfileUserControllerTest,
339 UsedPolicyCertificatesAllowedForPrimary) {
340 // Verifies that any user can sign-in as the primary user, regardless of the
342 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
343 MultiProfileUserController::UserAllowedInSessionReason reason;
344 EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason));
345 EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
346 EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
347 EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
348 EXPECT_EQ(MultiProfileUserController::ALLOWED,
349 MultiProfileUserController::GetPrimaryUserPolicy());
352 TEST_F(MultiProfileUserControllerTest,
353 UsedPolicyCertificatesDisallowedForSecondary) {
354 // Verifies that if a regular user is signed-in then other regular users can
355 // be added but tainted users can't.
358 // TODO(xiyuan): Remove the following SetPrefBehavor when default is
359 // changed back to enabled.
360 SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);
362 MultiProfileUserController::UserAllowedInSessionReason reason;
363 EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason));
364 EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
366 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
367 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[0], &reason));
368 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED,
372 TEST_F(MultiProfileUserControllerTest,
373 UsedPolicyCertificatesDisallowsSecondaries) {
374 // Verifies that if a tainted user is signed-in then no other users can
376 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]);
379 cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure()));
380 g_policy_cert_verifier_for_factory = cert_verifier_.get();
382 policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
383 profile(0), TestPolicyCertServiceFactory));
385 MultiProfileUserController::UserAllowedInSessionReason reason;
386 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
387 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
389 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
390 MultiProfileUserController::GetPrimaryUserPolicy());
391 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[1]);
392 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
393 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED,
395 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
396 MultiProfileUserController::GetPrimaryUserPolicy());
398 // Flush tasks posted to IO.
399 base::RunLoop().RunUntilIdle();
402 TEST_F(MultiProfileUserControllerTest,
403 PolicyCertificatesInMemoryDisallowsSecondaries) {
404 // Verifies that if a user is signed-in and has policy certificates installed
405 // then no other users can be added.
408 // TODO(xiyuan): Remove the following SetPrefBehavor when default is
409 // changed back to enabled.
410 SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted);
412 cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure()));
413 g_policy_cert_verifier_for_factory = cert_verifier_.get();
415 policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
416 profile(0), TestPolicyCertServiceFactory));
417 policy::PolicyCertService* service =
418 policy::PolicyCertServiceFactory::GetForProfile(profile(0));
419 ASSERT_TRUE(service);
421 EXPECT_FALSE(service->has_policy_certificates());
422 MultiProfileUserController::UserAllowedInSessionReason reason;
423 EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
424 EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
425 EXPECT_EQ(MultiProfileUserController::ALLOWED,
426 MultiProfileUserController::GetPrimaryUserPolicy());
428 net::CertificateList certificates;
429 certificates.push_back(new net::X509Certificate(
430 "subject", "issuer", base::Time(), base::Time()));
431 service->OnTrustAnchorsChanged(certificates);
432 EXPECT_TRUE(service->has_policy_certificates());
433 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
434 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
436 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
437 MultiProfileUserController::GetPrimaryUserPolicy());
439 // Flush tasks posted to IO.
440 base::RunLoop().RunUntilIdle();
443 } // namespace chromeos