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/memory/scoped_ptr.h" | |
8 #include "base/run_loop.h" | |
9 #include "base/strings/utf_string_conversions.h" | |
10 #include "chrome/browser/chromeos/login/fake_user_manager.h" | |
11 #include "chrome/browser/chromeos/login/multi_profile_user_controller_delegate.h
" | |
12 #include "chrome/browser/chromeos/login/user_manager.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/prefs/browser_prefs.h" | |
17 #include "chrome/common/pref_names.h" | |
18 #include "chrome/test/base/scoped_testing_local_state.h" | |
19 #include "chrome/test/base/testing_browser_process.h" | |
20 #include "chrome/test/base/testing_pref_service_syncable.h" | |
21 #include "chrome/test/base/testing_profile.h" | |
22 #include "chrome/test/base/testing_profile_manager.h" | |
23 #include "content/public/test/test_browser_thread_bundle.h" | |
24 #include "net/cert/x509_certificate.h" | |
25 #include "testing/gtest/include/gtest/gtest.h" | |
26 | |
27 namespace chromeos { | |
28 | |
29 namespace { | |
30 | |
31 const char* kUsers[] = {"a@gmail.com", "b@gmail.com" }; | |
32 | |
33 struct BehaviorTestCase { | |
34 const char* primary; | |
35 const char* secondary; | |
36 MultiProfileUserController::UserAllowedInSessionResult expected_allowed; | |
37 }; | |
38 | |
39 const BehaviorTestCase kBehaviorTestCases[] = { | |
40 { | |
41 MultiProfileUserController::kBehaviorUnrestricted, | |
42 MultiProfileUserController::kBehaviorUnrestricted, | |
43 MultiProfileUserController::ALLOWED, | |
44 }, | |
45 { | |
46 MultiProfileUserController::kBehaviorUnrestricted, | |
47 MultiProfileUserController::kBehaviorPrimaryOnly, | |
48 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, | |
49 }, | |
50 { | |
51 MultiProfileUserController::kBehaviorUnrestricted, | |
52 MultiProfileUserController::kBehaviorNotAllowed, | |
53 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, | |
54 }, | |
55 { | |
56 MultiProfileUserController::kBehaviorPrimaryOnly, | |
57 MultiProfileUserController::kBehaviorUnrestricted, | |
58 MultiProfileUserController::ALLOWED, | |
59 }, | |
60 { | |
61 MultiProfileUserController::kBehaviorPrimaryOnly, | |
62 MultiProfileUserController::kBehaviorPrimaryOnly, | |
63 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, | |
64 }, | |
65 { | |
66 MultiProfileUserController::kBehaviorPrimaryOnly, | |
67 MultiProfileUserController::kBehaviorNotAllowed, | |
68 MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS, | |
69 }, | |
70 { | |
71 MultiProfileUserController::kBehaviorNotAllowed, | |
72 MultiProfileUserController::kBehaviorUnrestricted, | |
73 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, | |
74 }, | |
75 { | |
76 MultiProfileUserController::kBehaviorNotAllowed, | |
77 MultiProfileUserController::kBehaviorPrimaryOnly, | |
78 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, | |
79 }, | |
80 { | |
81 MultiProfileUserController::kBehaviorNotAllowed, | |
82 MultiProfileUserController::kBehaviorNotAllowed, | |
83 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS, | |
84 }, | |
85 }; | |
86 | |
87 // Weak ptr to PolicyCertVerifier - object is freed in test destructor once | |
88 // we've ensured the profile has been shut down. | |
89 policy::PolicyCertVerifier* g_policy_cert_verifier_for_factory = NULL; | |
90 | |
91 KeyedService* TestPolicyCertServiceFactory(content::BrowserContext* context) { | |
92 return policy::PolicyCertService::CreateForTesting( | |
93 kUsers[0], g_policy_cert_verifier_for_factory, UserManager::Get()) | |
94 .release(); | |
95 } | |
96 | |
97 } // namespace | |
98 | |
99 class MultiProfileUserControllerTest | |
100 : public testing::Test, | |
101 public MultiProfileUserControllerDelegate { | |
102 public: | |
103 MultiProfileUserControllerTest() | |
104 : fake_user_manager_(new FakeUserManager), | |
105 user_manager_enabler_(fake_user_manager_), | |
106 user_not_allowed_count_(0) {} | |
107 virtual ~MultiProfileUserControllerTest() {} | |
108 | |
109 virtual void SetUp() OVERRIDE { | |
110 profile_manager_.reset( | |
111 new TestingProfileManager(TestingBrowserProcess::GetGlobal())); | |
112 ASSERT_TRUE(profile_manager_->SetUp()); | |
113 controller_.reset(new MultiProfileUserController( | |
114 this, TestingBrowserProcess::GetGlobal()->local_state())); | |
115 | |
116 for (size_t i = 0; i < arraysize(kUsers); ++i) { | |
117 const std::string user_email(kUsers[i]); | |
118 const User* user = fake_user_manager_->AddUser(user_email); | |
119 | |
120 // Note that user profiles are created after user login in reality. | |
121 TestingProfile* user_profile = | |
122 profile_manager_->CreateTestingProfile(user_email); | |
123 user_profile->set_profile_name(user_email); | |
124 user_profiles_.push_back(user_profile); | |
125 | |
126 fake_user_manager_->SetProfileForUser(user, user_profile); | |
127 } | |
128 } | |
129 | |
130 virtual void TearDown() OVERRIDE { | |
131 // Clear our cached pointer to the PolicyCertVerifier. | |
132 g_policy_cert_verifier_for_factory = NULL; | |
133 | |
134 // We must ensure that the PolicyCertVerifier outlives the | |
135 // PolicyCertService so shutdown the profile here. Additionally, we need | |
136 // to run the message loop between freeing the PolicyCertService and | |
137 // freeing the PolicyCertVerifier (see | |
138 // PolicyCertService::OnTrustAnchorsChanged() which is called from | |
139 // PolicyCertService::Shutdown()). | |
140 controller_.reset(); | |
141 profile_manager_.reset(); | |
142 base::RunLoop().RunUntilIdle(); | |
143 } | |
144 | |
145 void LoginUser(size_t user_index) { | |
146 ASSERT_LT(user_index, arraysize(kUsers)); | |
147 fake_user_manager_->LoginUser(kUsers[user_index]); | |
148 controller_->StartObserving(user_profiles_[user_index]); | |
149 } | |
150 | |
151 void SetOwner(size_t user_index) { | |
152 fake_user_manager_->set_owner_email(kUsers[user_index]); | |
153 } | |
154 | |
155 PrefService* GetUserPrefs(size_t user_index) { | |
156 return user_profiles_[user_index]->GetPrefs(); | |
157 } | |
158 | |
159 void SetPrefBehavior(size_t user_index, const std::string& behavior) { | |
160 GetUserPrefs(user_index)->SetString(prefs::kMultiProfileUserBehavior, | |
161 behavior); | |
162 } | |
163 | |
164 std::string GetCachedBehavior(size_t user_index) { | |
165 return controller_->GetCachedValue(kUsers[user_index]); | |
166 } | |
167 | |
168 void SetCachedBehavior(size_t user_index, | |
169 const std::string& behavior) { | |
170 controller_->SetCachedValue(kUsers[user_index], behavior); | |
171 } | |
172 | |
173 void ResetCounts() { | |
174 user_not_allowed_count_ = 0; | |
175 } | |
176 | |
177 // MultiProfileUserControllerDeleagte overrides: | |
178 virtual void OnUserNotAllowed(const std::string& user_email) OVERRIDE { | |
179 ++user_not_allowed_count_; | |
180 } | |
181 | |
182 MultiProfileUserController* controller() { return controller_.get(); } | |
183 int user_not_allowed_count() const { return user_not_allowed_count_; } | |
184 | |
185 TestingProfile* profile(int index) { | |
186 return user_profiles_[index]; | |
187 } | |
188 | |
189 content::TestBrowserThreadBundle threads_; | |
190 scoped_ptr<policy::PolicyCertVerifier> cert_verifier_; | |
191 scoped_ptr<TestingProfileManager> profile_manager_; | |
192 FakeUserManager* fake_user_manager_; // Not owned | |
193 ScopedUserManagerEnabler user_manager_enabler_; | |
194 | |
195 scoped_ptr<MultiProfileUserController> controller_; | |
196 | |
197 std::vector<TestingProfile*> user_profiles_; | |
198 | |
199 int user_not_allowed_count_; | |
200 | |
201 DISALLOW_COPY_AND_ASSIGN(MultiProfileUserControllerTest); | |
202 }; | |
203 | |
204 // Tests that everyone is allowed before a session starts. | |
205 TEST_F(MultiProfileUserControllerTest, AllAllowedBeforeLogin) { | |
206 const char* kTestCases[] = { | |
207 MultiProfileUserController::kBehaviorUnrestricted, | |
208 MultiProfileUserController::kBehaviorPrimaryOnly, | |
209 MultiProfileUserController::kBehaviorNotAllowed, | |
210 }; | |
211 for (size_t i = 0; i < arraysize(kTestCases); ++i) { | |
212 SetCachedBehavior(0, kTestCases[i]); | |
213 EXPECT_EQ(MultiProfileUserController::ALLOWED, | |
214 controller()->IsUserAllowedInSession(kUsers[0])) | |
215 << "Case " << i; | |
216 } | |
217 } | |
218 | |
219 // Tests that invalid cache value would become the default "unrestricted". | |
220 TEST_F(MultiProfileUserControllerTest, InvalidCacheBecomesDefault) { | |
221 const char kBad[] = "some invalid value"; | |
222 SetCachedBehavior(0, kBad); | |
223 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted, | |
224 GetCachedBehavior(0)); | |
225 } | |
226 | |
227 // Tests that cached behavior value changes with user pref after login. | |
228 TEST_F(MultiProfileUserControllerTest, CachedBehaviorUpdate) { | |
229 LoginUser(0); | |
230 | |
231 const char* kTestCases[] = { | |
232 MultiProfileUserController::kBehaviorUnrestricted, | |
233 MultiProfileUserController::kBehaviorPrimaryOnly, | |
234 MultiProfileUserController::kBehaviorNotAllowed, | |
235 MultiProfileUserController::kBehaviorUnrestricted, | |
236 }; | |
237 for (size_t i = 0; i < arraysize(kTestCases); ++i) { | |
238 SetPrefBehavior(0, kTestCases[i]); | |
239 EXPECT_EQ(kTestCases[i], GetCachedBehavior(0)); | |
240 } | |
241 } | |
242 | |
243 // Tests that compromised cache value would be fixed and pref value is checked | |
244 // upon login. | |
245 TEST_F(MultiProfileUserControllerTest, CompromisedCacheFixedOnLogin) { | |
246 SetPrefBehavior(0, MultiProfileUserController::kBehaviorPrimaryOnly); | |
247 SetCachedBehavior(0, MultiProfileUserController::kBehaviorUnrestricted); | |
248 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted, | |
249 GetCachedBehavior(0)); | |
250 LoginUser(0); | |
251 EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly, | |
252 GetCachedBehavior(0)); | |
253 | |
254 EXPECT_EQ(0, user_not_allowed_count()); | |
255 SetPrefBehavior(1, MultiProfileUserController::kBehaviorPrimaryOnly); | |
256 SetCachedBehavior(1, MultiProfileUserController::kBehaviorUnrestricted); | |
257 EXPECT_EQ(MultiProfileUserController::kBehaviorUnrestricted, | |
258 GetCachedBehavior(1)); | |
259 LoginUser(1); | |
260 EXPECT_EQ(MultiProfileUserController::kBehaviorPrimaryOnly, | |
261 GetCachedBehavior(1)); | |
262 EXPECT_EQ(1, user_not_allowed_count()); | |
263 } | |
264 | |
265 // Tests cases before the second user login. | |
266 TEST_F(MultiProfileUserControllerTest, IsSecondaryAllowed) { | |
267 LoginUser(0); | |
268 | |
269 for (size_t i = 0; i < arraysize(kBehaviorTestCases); ++i) { | |
270 SetPrefBehavior(0, kBehaviorTestCases[i].primary); | |
271 SetCachedBehavior(1, kBehaviorTestCases[i].secondary); | |
272 EXPECT_EQ(kBehaviorTestCases[i].expected_allowed, | |
273 controller()->IsUserAllowedInSession(kUsers[1])) << "Case " << i; | |
274 } | |
275 } | |
276 | |
277 // Tests user behavior changes within a two-user session. | |
278 TEST_F(MultiProfileUserControllerTest, PrimaryBehaviorChange) { | |
279 LoginUser(0); | |
280 LoginUser(1); | |
281 | |
282 for (size_t i = 0; i < arraysize(kBehaviorTestCases); ++i) { | |
283 SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted); | |
284 SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted); | |
285 ResetCounts(); | |
286 | |
287 SetPrefBehavior(0, kBehaviorTestCases[i].primary); | |
288 SetPrefBehavior(1, kBehaviorTestCases[i].secondary); | |
289 if (user_not_allowed_count() == 0) { | |
290 EXPECT_EQ(kBehaviorTestCases[i].expected_allowed, | |
291 MultiProfileUserController::ALLOWED) << "Case " << i; | |
292 } else { | |
293 EXPECT_NE(kBehaviorTestCases[i].expected_allowed, | |
294 MultiProfileUserController::ALLOWED) << "Case " << i; | |
295 } | |
296 } | |
297 } | |
298 | |
299 // Tests that owner could not be a secondary user. | |
300 TEST_F(MultiProfileUserControllerTest, NoSecondaryOwner) { | |
301 LoginUser(0); | |
302 SetOwner(1); | |
303 | |
304 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY, | |
305 controller()->IsUserAllowedInSession(kUsers[1])); | |
306 | |
307 EXPECT_EQ(0, user_not_allowed_count()); | |
308 LoginUser(1); | |
309 EXPECT_EQ(1, user_not_allowed_count()); | |
310 } | |
311 | |
312 TEST_F(MultiProfileUserControllerTest, | |
313 UsedPolicyCertificatesAllowedForPrimary) { | |
314 // Verifies that any user can sign-in as the primary user, regardless of the | |
315 // tainted state. | |
316 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]); | |
317 EXPECT_EQ(MultiProfileUserController::ALLOWED, | |
318 controller()->IsUserAllowedInSession(kUsers[0])); | |
319 EXPECT_EQ(MultiProfileUserController::ALLOWED, | |
320 controller()->IsUserAllowedInSession(kUsers[1])); | |
321 } | |
322 | |
323 TEST_F(MultiProfileUserControllerTest, | |
324 UsedPolicyCertificatesDisallowedForSecondary) { | |
325 // Verifies that if a regular user is signed-in then other regular users can | |
326 // be added but tainted users can't. | |
327 LoginUser(1); | |
328 | |
329 // TODO(xiyuan): Remove the following SetPrefBehavor when default is | |
330 // changed back to enabled. | |
331 SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted); | |
332 | |
333 EXPECT_EQ(MultiProfileUserController::ALLOWED, | |
334 controller()->IsUserAllowedInSession(kUsers[0])); | |
335 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]); | |
336 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED, | |
337 controller()->IsUserAllowedInSession(kUsers[0])); | |
338 } | |
339 | |
340 TEST_F(MultiProfileUserControllerTest, | |
341 UsedPolicyCertificatesDisallowsSecondaries) { | |
342 // Verifies that if a tainted user is signed-in then no other users can | |
343 // be added. | |
344 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[0]); | |
345 LoginUser(0); | |
346 | |
347 cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure())); | |
348 g_policy_cert_verifier_for_factory = cert_verifier_.get(); | |
349 ASSERT_TRUE( | |
350 policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse( | |
351 profile(0), TestPolicyCertServiceFactory)); | |
352 | |
353 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED, | |
354 controller()->IsUserAllowedInSession(kUsers[1])); | |
355 policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[1]); | |
356 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED, | |
357 controller()->IsUserAllowedInSession(kUsers[1])); | |
358 | |
359 // Flush tasks posted to IO. | |
360 base::RunLoop().RunUntilIdle(); | |
361 } | |
362 | |
363 TEST_F(MultiProfileUserControllerTest, | |
364 PolicyCertificatesInMemoryDisallowsSecondaries) { | |
365 // Verifies that if a user is signed-in and has policy certificates installed | |
366 // then no other users can be added. | |
367 LoginUser(0); | |
368 | |
369 // TODO(xiyuan): Remove the following SetPrefBehavor when default is | |
370 // changed back to enabled. | |
371 SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted); | |
372 | |
373 cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure())); | |
374 g_policy_cert_verifier_for_factory = cert_verifier_.get(); | |
375 ASSERT_TRUE( | |
376 policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse( | |
377 profile(0), TestPolicyCertServiceFactory)); | |
378 policy::PolicyCertService* service = | |
379 policy::PolicyCertServiceFactory::GetForProfile(profile(0)); | |
380 ASSERT_TRUE(service); | |
381 | |
382 EXPECT_FALSE(service->has_policy_certificates()); | |
383 EXPECT_EQ(MultiProfileUserController::ALLOWED, | |
384 controller()->IsUserAllowedInSession(kUsers[1])); | |
385 | |
386 net::CertificateList certificates; | |
387 certificates.push_back(new net::X509Certificate( | |
388 "subject", "issuer", base::Time(), base::Time())); | |
389 service->OnTrustAnchorsChanged(certificates); | |
390 EXPECT_TRUE(service->has_policy_certificates()); | |
391 EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED, | |
392 controller()->IsUserAllowedInSession(kUsers[1])); | |
393 | |
394 // Flush tasks posted to IO. | |
395 base::RunLoop().RunUntilIdle(); | |
396 } | |
397 | |
398 } // namespace chromeos | |
OLD | NEW |