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