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/multi_profile_user_controller.h" 6 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" 28 29namespace chromeos { 30 31namespace { 32 33const char* kUsers[] = {"a@gmail.com", "b@gmail.com" }; 34 35struct BehaviorTestCase { 36 const char* primary; 37 const char* secondary; 38 MultiProfileUserController::UserAllowedInSessionReason 39 expected_primary_policy; 40 MultiProfileUserController::UserAllowedInSessionReason 41 expected_secondary_allowed; 42}; 43 44const BehaviorTestCase kBehaviorTestCases[] = { 45 { 46 MultiProfileUserController::kBehaviorUnrestricted, 47 MultiProfileUserController::kBehaviorUnrestricted, 48 MultiProfileUserController::ALLOWED, MultiProfileUserController::ALLOWED, 49 }, 50 { 51 MultiProfileUserController::kBehaviorUnrestricted, 52 MultiProfileUserController::kBehaviorPrimaryOnly, 53 MultiProfileUserController::ALLOWED, 54 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, 55 }, 56 { 57 MultiProfileUserController::kBehaviorUnrestricted, 58 MultiProfileUserController::kBehaviorNotAllowed, 59 MultiProfileUserController::ALLOWED, 60 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, 61 }, 62 { 63 MultiProfileUserController::kBehaviorPrimaryOnly, 64 MultiProfileUserController::kBehaviorUnrestricted, 65 MultiProfileUserController::ALLOWED, MultiProfileUserController::ALLOWED, 66 }, 67 { 68 MultiProfileUserController::kBehaviorPrimaryOnly, 69 MultiProfileUserController::kBehaviorPrimaryOnly, 70 MultiProfileUserController::ALLOWED, 71 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, 72 }, 73 { 74 MultiProfileUserController::kBehaviorPrimaryOnly, 75 MultiProfileUserController::kBehaviorNotAllowed, 76 MultiProfileUserController::ALLOWED, 77 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, 78 }, 79 { 80 MultiProfileUserController::kBehaviorNotAllowed, 81 MultiProfileUserController::kBehaviorUnrestricted, 82 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, 83 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, 84 }, 85 { 86 MultiProfileUserController::kBehaviorNotAllowed, 87 MultiProfileUserController::kBehaviorPrimaryOnly, 88 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, 89 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, 90 }, 91 { 92 MultiProfileUserController::kBehaviorNotAllowed, 93 MultiProfileUserController::kBehaviorNotAllowed, 94 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, 95 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, 96 }, 97}; 98 99// Weak ptr to PolicyCertVerifier - object is freed in test destructor once 100// we've ensured the profile has been shut down. 101policy::PolicyCertVerifier* g_policy_cert_verifier_for_factory = NULL; 102 103KeyedService* TestPolicyCertServiceFactory(content::BrowserContext* context) { 104 return policy::PolicyCertService::CreateForTesting( 105 kUsers[0], 106 g_policy_cert_verifier_for_factory, 107 user_manager::UserManager::Get()).release(); 108} 109 110} // namespace 111 112class MultiProfileUserControllerTest 113 : public testing::Test, 114 public MultiProfileUserControllerDelegate { 115 public: 116 MultiProfileUserControllerTest() 117 : fake_user_manager_(new FakeUserManager), 118 user_manager_enabler_(fake_user_manager_), 119 user_not_allowed_count_(0) {} 120 virtual ~MultiProfileUserControllerTest() {} 121 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())); 128 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); 132 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); 138 139 ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, 140 user_profile); 141 } 142 } 143 144 virtual void TearDown() OVERRIDE { 145 // Clear our cached pointer to the PolicyCertVerifier. 146 g_policy_cert_verifier_for_factory = NULL; 147 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()). 154 controller_.reset(); 155 profile_manager_.reset(); 156 base::RunLoop().RunUntilIdle(); 157 } 158 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]); 163 } 164 165 void SetOwner(size_t user_index) { 166 fake_user_manager_->set_owner_email(kUsers[user_index]); 167 } 168 169 PrefService* GetUserPrefs(size_t user_index) { 170 return user_profiles_[user_index]->GetPrefs(); 171 } 172 173 void SetPrefBehavior(size_t user_index, const std::string& behavior) { 174 GetUserPrefs(user_index)->SetString(prefs::kMultiProfileUserBehavior, 175 behavior); 176 } 177 178 std::string GetCachedBehavior(size_t user_index) { 179 return controller_->GetCachedValue(kUsers[user_index]); 180 } 181 182 void SetCachedBehavior(size_t user_index, 183 const std::string& behavior) { 184 controller_->SetCachedValue(kUsers[user_index], behavior); 185 } 186 187 void ResetCounts() { 188 user_not_allowed_count_ = 0; 189 } 190 191 // MultiProfileUserControllerDeleagte overrides: 192 virtual void OnUserNotAllowed(const std::string& user_email) OVERRIDE { 193 ++user_not_allowed_count_; 194 } 195 196 MultiProfileUserController* controller() { return controller_.get(); } 197 int user_not_allowed_count() const { return user_not_allowed_count_; } 198 199 TestingProfile* profile(int index) { 200 return user_profiles_[index]; 201 } 202 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_; 208 209 scoped_ptr<MultiProfileUserController> controller_; 210 211 std::vector<TestingProfile*> user_profiles_; 212 213 int user_not_allowed_count_; 214 215 DISALLOW_COPY_AND_ASSIGN(MultiProfileUserControllerTest); 216}; 217 218// Tests that everyone is allowed before a session starts. 219TEST_F(MultiProfileUserControllerTest, AllAllowedBeforeLogin) { 220 const char* kTestCases[] = { 221 MultiProfileUserController::kBehaviorUnrestricted, 222 MultiProfileUserController::kBehaviorPrimaryOnly, 223 MultiProfileUserController::kBehaviorNotAllowed, 224 }; 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)) 229 << "Case " << i; 230 EXPECT_EQ(MultiProfileUserController::ALLOWED, reason) << "Case " << i; 231 EXPECT_EQ(MultiProfileUserController::ALLOWED, 232 MultiProfileUserController::GetPrimaryUserPolicy()) 233 << "Case " << i; 234 } 235} 236 237// Tests that invalid cache value would become the default "unrestricted". 238TEST_F(MultiProfileUserControllerTest, InvalidCacheBecomesDefault) { 239 const char kBad[] = "some invalid value"; 240 SetCachedBehavior(0, kBad); 241 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted, 242 GetCachedBehavior(0)); 243} 244 245// Tests that cached behavior value changes with user pref after login. 246TEST_F(MultiProfileUserControllerTest, CachedBehaviorUpdate) { 247 LoginUser(0); 248 249 const char* kTestCases[] = { 250 MultiProfileUserController::kBehaviorUnrestricted, 251 MultiProfileUserController::kBehaviorPrimaryOnly, 252 MultiProfileUserController::kBehaviorNotAllowed, 253 MultiProfileUserController::kBehaviorUnrestricted, 254 }; 255 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 256 SetPrefBehavior(0, kTestCases[i]); 257 EXPECT_EQ(kTestCases[i], GetCachedBehavior(0)); 258 } 259} 260 261// Tests that compromised cache value would be fixed and pref value is checked 262// upon login. 263TEST_F(MultiProfileUserControllerTest, CompromisedCacheFixedOnLogin) { 264 SetPrefBehavior(0, MultiProfileUserController::kBehaviorPrimaryOnly); 265 SetCachedBehavior(0, MultiProfileUserController::kBehaviorUnrestricted); 266 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted, 267 GetCachedBehavior(0)); 268 LoginUser(0); 269 EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly, 270 GetCachedBehavior(0)); 271 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)); 277 LoginUser(1); 278 EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly, 279 GetCachedBehavior(1)); 280 EXPECT_EQ(1, user_not_allowed_count()); 281} 282 283// Tests cases before the second user login. 284TEST_F(MultiProfileUserControllerTest, IsSecondaryAllowed) { 285 LoginUser(0); 286 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()) 292 << "Case " << i; 293 MultiProfileUserController::UserAllowedInSessionReason reason; 294 controller()->IsUserAllowedInSession(kUsers[1], &reason); 295 EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed, reason) 296 << "Case " << i; 297 } 298} 299 300// Tests user behavior changes within a two-user session. 301TEST_F(MultiProfileUserControllerTest, PrimaryBehaviorChange) { 302 LoginUser(0); 303 LoginUser(1); 304 305 for (size_t i = 0; i < arraysize(kBehaviorTestCases); ++i) { 306 SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted); 307 SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted); 308 ResetCounts(); 309 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) 315 << "Case " << i; 316 } else { 317 EXPECT_NE(kBehaviorTestCases[i].expected_secondary_allowed, 318 MultiProfileUserController::ALLOWED) 319 << "Case " << i; 320 } 321 } 322} 323 324// Tests that owner could not be a secondary user. 325TEST_F(MultiProfileUserControllerTest, NoSecondaryOwner) { 326 LoginUser(0); 327 SetOwner(1); 328 329 MultiProfileUserController::UserAllowedInSessionReason reason; 330 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason)); 331 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY, reason); 332 333 EXPECT_EQ(0, user_not_allowed_count()); 334 LoginUser(1); 335 EXPECT_EQ(1, user_not_allowed_count()); 336} 337 338TEST_F(MultiProfileUserControllerTest, 339 UsedPolicyCertificatesAllowedForPrimary) { 340 // Verifies that any user can sign-in as the primary user, regardless of the 341 // tainted state. 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()); 350} 351 352TEST_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. 356 LoginUser(1); 357 358 // TODO(xiyuan): Remove the following SetPrefBehavor when default is 359 // changed back to enabled. 360 SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted); 361 362 MultiProfileUserController::UserAllowedInSessionReason reason; 363 EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason)); 364 EXPECT_EQ(MultiProfileUserController::ALLOWED, reason); 365 366 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]); 367 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[0], &reason)); 368 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED, 369 reason); 370} 371 372TEST_F(MultiProfileUserControllerTest, 373 UsedPolicyCertificatesDisallowsSecondaries) { 374 // Verifies that if a tainted user is signed-in then no other users can 375 // be added. 376 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]); 377 LoginUser(0); 378 379 cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure())); 380 g_policy_cert_verifier_for_factory = cert_verifier_.get(); 381 ASSERT_TRUE( 382 policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse( 383 profile(0), TestPolicyCertServiceFactory)); 384 385 MultiProfileUserController::UserAllowedInSessionReason reason; 386 EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason)); 387 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED, 388 reason); 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, 394 reason); 395 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED, 396 MultiProfileUserController::GetPrimaryUserPolicy()); 397 398 // Flush tasks posted to IO. 399 base::RunLoop().RunUntilIdle(); 400} 401 402TEST_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. 406 LoginUser(0); 407 408 // TODO(xiyuan): Remove the following SetPrefBehavor when default is 409 // changed back to enabled. 410 SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted); 411 412 cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure())); 413 g_policy_cert_verifier_for_factory = cert_verifier_.get(); 414 ASSERT_TRUE( 415 policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse( 416 profile(0), TestPolicyCertServiceFactory)); 417 policy::PolicyCertService* service = 418 policy::PolicyCertServiceFactory::GetForProfile(profile(0)); 419 ASSERT_TRUE(service); 420 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()); 427 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, 435 reason); 436 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED, 437 MultiProfileUserController::GetPrimaryUserPolicy()); 438 439 // Flush tasks posted to IO. 440 base::RunLoop().RunUntilIdle(); 441} 442 443} // namespace chromeos 444