145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Copyright 2013 The Chromium Authors. All rights reserved.
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Use of this source code is governed by a BSD-style license that can be
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// found in the LICENSE file.
4
5#include "chrome/browser/ui/ash/session_state_delegate_chromeos.h"
6
7#include <string>
8#include <vector>
9
10#include "base/run_loop.h"
11#include "chrome/browser/chromeos/login/users/fake_user_manager.h"
12#include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
13#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.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/policy/policy_cert_verifier.h"
17#include "chrome/browser/chromeos/profiles/profile_helper.h"
18#include "chrome/common/pref_names.h"
19#include "chrome/test/base/testing_browser_process.h"
20#include "chrome/test/base/testing_profile_manager.h"
21#include "components/user_manager/user_manager.h"
22#include "content/public/test/test_browser_thread_bundle.h"
23#include "net/cert/x509_certificate.h"
24#include "testing/gtest/include/gtest/gtest.h"
25
26namespace chromeos {
27
28namespace {
29
30const char* kUser = "user@test.com";
31
32// Weak ptr to PolicyCertVerifier - object is freed in test destructor once
33// we've ensured the profile has been shut down.
34policy::PolicyCertVerifier* g_policy_cert_verifier_for_factory = NULL;
35
36KeyedService* CreateTestPolicyCertService(content::BrowserContext* context) {
37  return policy::PolicyCertService::CreateForTesting(
38             kUser,
39             g_policy_cert_verifier_for_factory,
40             user_manager::UserManager::Get()).release();
41}
42
43}  // namespace
44
45class SessionStateDelegateChromeOSTest : public testing::Test {
46 protected:
47  SessionStateDelegateChromeOSTest() : user_manager_(NULL) {
48  }
49
50  virtual ~SessionStateDelegateChromeOSTest() {
51  }
52
53  virtual void SetUp() OVERRIDE {
54    // Initialize the UserManager singleton to a fresh FakeUserManager instance.
55    user_manager_ = new chromeos::FakeUserManager;
56    user_manager_enabler_.reset(
57        new chromeos::ScopedUserManagerEnabler(user_manager_));
58
59    // Create our SessionStateDelegate to experiment with.
60    session_state_delegate_.reset(new SessionStateDelegateChromeos());
61    testing::Test::SetUp();
62  }
63
64  virtual void TearDown() OVERRIDE {
65    testing::Test::TearDown();
66    session_state_delegate_.reset();
67    user_manager_enabler_.reset();
68    user_manager_ = NULL;
69    // Clear our cached pointer to the PolicyCertVerifier.
70    g_policy_cert_verifier_for_factory = NULL;
71    profile_manager_.reset();
72
73    // We must ensure that the PolicyCertVerifier outlives the
74    // PolicyCertService so shutdown the profile here. Additionally, we need
75    // to run the message loop between freeing the PolicyCertService and
76    // freeing the PolicyCertVerifier (see
77    // PolicyCertService::OnTrustAnchorsChanged() which is called from
78    // PolicyCertService::Shutdown()).
79    base::RunLoop().RunUntilIdle();
80  }
81
82  // Add and log in a user to the session.
83  void UserAddedToSession(std::string user) {
84    user_manager()->AddUser(user);
85    user_manager()->LoginUser(user);
86  }
87
88  // Get the active user.
89  const std::string& GetActiveUser() {
90    return user_manager::UserManager::Get()->GetActiveUser()->email();
91  }
92
93  chromeos::FakeUserManager* user_manager() { return user_manager_; }
94  SessionStateDelegateChromeos* session_state_delegate() {
95    return session_state_delegate_.get();
96  }
97
98  void InitForMultiProfile() {
99    profile_manager_.reset(
100        new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
101    ASSERT_TRUE(profile_manager_->SetUp());
102
103    const std::string user_email(kUser);
104    const user_manager::User* user = user_manager()->AddUser(user_email);
105
106    // Note that user profiles are created after user login in reality.
107    user_profile_ = profile_manager_->CreateTestingProfile(user_email);
108    user_profile_->set_profile_name(user_email);
109    chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
110        user, user_profile_);
111  }
112
113  content::TestBrowserThreadBundle threads_;
114  scoped_ptr<policy::PolicyCertVerifier> cert_verifier_;
115  scoped_ptr<TestingProfileManager> profile_manager_;
116  TestingProfile* user_profile_;
117
118 private:
119  scoped_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
120  scoped_ptr<SessionStateDelegateChromeos> session_state_delegate_;
121
122  // Not owned.
123  chromeos::FakeUserManager* user_manager_;
124
125  DISALLOW_COPY_AND_ASSIGN(SessionStateDelegateChromeOSTest);
126};
127
128// Make sure that cycling one user does not cause any harm.
129TEST_F(SessionStateDelegateChromeOSTest, CyclingOneUser) {
130  UserAddedToSession("firstuser@test.com");
131
132  EXPECT_EQ("firstuser@test.com", GetActiveUser());
133  session_state_delegate()->CycleActiveUser(
134      ash::SessionStateDelegate::CYCLE_TO_NEXT_USER);
135  EXPECT_EQ("firstuser@test.com", GetActiveUser());
136  session_state_delegate()->CycleActiveUser(
137      ash::SessionStateDelegate::CYCLE_TO_PREVIOUS_USER);
138  EXPECT_EQ("firstuser@test.com", GetActiveUser());
139}
140
141// Cycle three users forwards and backwards to see that it works.
142TEST_F(SessionStateDelegateChromeOSTest, CyclingThreeUsers) {
143  UserAddedToSession("firstuser@test.com");
144  UserAddedToSession("seconduser@test.com");
145  UserAddedToSession("thirduser@test.com");
146  const ash::SessionStateDelegate::CycleUser forward =
147      ash::SessionStateDelegate::CYCLE_TO_NEXT_USER;
148
149  // Cycle forward.
150  EXPECT_EQ("firstuser@test.com", GetActiveUser());
151  session_state_delegate()->CycleActiveUser(forward);
152  EXPECT_EQ("seconduser@test.com", GetActiveUser());
153  session_state_delegate()->CycleActiveUser(forward);
154  EXPECT_EQ("thirduser@test.com", GetActiveUser());
155  session_state_delegate()->CycleActiveUser(forward);
156  EXPECT_EQ("firstuser@test.com", GetActiveUser());
157
158  // Cycle backwards.
159  const ash::SessionStateDelegate::CycleUser backward =
160      ash::SessionStateDelegate::CYCLE_TO_PREVIOUS_USER;
161  session_state_delegate()->CycleActiveUser(backward);
162  EXPECT_EQ("thirduser@test.com", GetActiveUser());
163  session_state_delegate()->CycleActiveUser(backward);
164  EXPECT_EQ("seconduser@test.com", GetActiveUser());
165  session_state_delegate()->CycleActiveUser(backward);
166  EXPECT_EQ("firstuser@test.com", GetActiveUser());
167}
168
169// Make sure MultiProfile disabled by primary user policy.
170TEST_F(SessionStateDelegateChromeOSTest, MultiProfileDisallowedByUserPolicy) {
171  InitForMultiProfile();
172  EXPECT_TRUE(
173      session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
174  const std::string user_email(kUser);
175  user_manager()->LoginUser(user_email);
176  EXPECT_TRUE(
177      session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
178
179  user_profile_->GetPrefs()->SetString(
180      prefs::kMultiProfileUserBehavior,
181      chromeos::MultiProfileUserController::kBehaviorNotAllowed);
182  EXPECT_FALSE(
183      session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
184}
185
186// Make sure MultiProfile disabled by primary user policy certificates.
187TEST_F(SessionStateDelegateChromeOSTest,
188       MultiProfileDisallowedByPolicyCertificates) {
189  InitForMultiProfile();
190  const std::string user_email(kUser);
191  user_manager()->LoginUser(user_email);
192  EXPECT_TRUE(
193      session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
194  policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(user_email);
195  EXPECT_FALSE(
196      session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
197
198  // Flush tasks posted to IO.
199  base::RunLoop().RunUntilIdle();
200}
201
202// Make sure MultiProfile disabled by primary user certificates in memory.
203TEST_F(SessionStateDelegateChromeOSTest,
204       MultiProfileDisallowedByPrimaryUserCertificatesInMemory) {
205  InitForMultiProfile();
206  const std::string user_email(kUser);
207  user_manager()->LoginUser(user_email);
208  EXPECT_TRUE(
209      session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
210  cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure()));
211  g_policy_cert_verifier_for_factory = cert_verifier_.get();
212  ASSERT_TRUE(
213      policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
214          user_profile_, CreateTestPolicyCertService));
215  policy::PolicyCertService* service =
216      policy::PolicyCertServiceFactory::GetForProfile(user_profile_);
217  ASSERT_TRUE(service);
218
219  EXPECT_FALSE(service->has_policy_certificates());
220  net::CertificateList certificates;
221  certificates.push_back(new net::X509Certificate(
222      "subject", "issuer", base::Time(), base::Time()));
223  service->OnTrustAnchorsChanged(certificates);
224  EXPECT_TRUE(service->has_policy_certificates());
225  EXPECT_FALSE(
226      session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
227
228  // Flush tasks posted to IO.
229  base::RunLoop().RunUntilIdle();
230}
231
232// Make sure adding users to multiprofiles disabled by reaching maximum
233// number of users in sessions.
234TEST_F(SessionStateDelegateChromeOSTest,
235       AddUserToMultiprofileDisallowedByMaximumUsers) {
236  InitForMultiProfile();
237  ash::SessionStateDelegate::AddUserError add_user_error;
238
239  EXPECT_TRUE(
240      session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
241  const std::string user_email(kUser);
242  user_manager()->LoginUser(user_email);
243  while (session_state_delegate()->NumberOfLoggedInUsers() <
244         session_state_delegate()->GetMaximumNumberOfLoggedInUsers()) {
245    UserAddedToSession("bb@b.b");
246  }
247  EXPECT_FALSE(
248      session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
249  EXPECT_EQ(ash::SessionStateDelegate::ADD_USER_ERROR_MAXIMUM_USERS_REACHED,
250            add_user_error);
251}
252
253// Make sure adding users to multiprofiles disabled by logging in all possible
254// users.
255TEST_F(SessionStateDelegateChromeOSTest,
256       AddUserToMultiprofileDisallowedByAllUsersLogged) {
257  InitForMultiProfile();
258  ash::SessionStateDelegate::AddUserError add_user_error;
259
260  EXPECT_TRUE(
261      session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
262  const std::string user_email(kUser);
263  user_manager()->LoginUser(user_email);
264  UserAddedToSession("bb@b.b");
265  EXPECT_FALSE(
266      session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
267  EXPECT_EQ(ash::SessionStateDelegate::ADD_USER_ERROR_OUT_OF_USERS,
268            add_user_error);
269}
270
271// Make sure adding users to multiprofiles disabled by primary user policy.
272TEST_F(SessionStateDelegateChromeOSTest,
273       AddUserToMultiprofileDisallowedByPrimaryUserPolicy) {
274  InitForMultiProfile();
275  ash::SessionStateDelegate::AddUserError add_user_error;
276
277  EXPECT_TRUE(
278      session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
279  const std::string user_email(kUser);
280  user_manager()->LoginUser(user_email);
281  user_profile_->GetPrefs()->SetString(
282      prefs::kMultiProfileUserBehavior,
283      chromeos::MultiProfileUserController::kBehaviorNotAllowed);
284  user_manager()->AddUser("bb@b.b");
285  EXPECT_FALSE(
286      session_state_delegate()->CanAddUserToMultiProfile(&add_user_error));
287  EXPECT_EQ(ash::SessionStateDelegate::ADD_USER_ERROR_NOT_ALLOWED_PRIMARY_USER,
288            add_user_error);
289}
290
291}  // namespace chromeos
292