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 <cstdlib>
6#include <cstring>
7
8#include "base/command_line.h"
9#include "base/files/scoped_temp_dir.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/prefs/pref_service.h"
12#include "base/run_loop.h"
13#include "base/values.h"
14#include "chrome/browser/browser_process.h"
15#include "chrome/browser/chromeos/login/users/user.h"
16#include "chrome/browser/chromeos/login/users/user_manager.h"
17#include "chrome/browser/chromeos/login/users/user_manager_impl.h"
18#include "chrome/browser/chromeos/settings/cros_settings.h"
19#include "chrome/browser/chromeos/settings/device_settings_service.h"
20#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
21#include "chrome/browser/profiles/profile_manager.h"
22#include "chrome/test/base/scoped_testing_local_state.h"
23#include "chrome/test/base/testing_browser_process.h"
24#include "chrome/test/base/testing_profile.h"
25#include "chromeos/chromeos_switches.h"
26#include "chromeos/dbus/dbus_thread_manager.h"
27#include "chromeos/dbus/fake_dbus_thread_manager.h"
28#include "chromeos/settings/cros_settings_names.h"
29#include "chromeos/settings/cros_settings_provider.h"
30#include "content/public/common/content_switches.h"
31#include "content/public/test/test_browser_thread_bundle.h"
32#include "testing/gtest/include/gtest/gtest.h"
33
34namespace chromeos {
35
36class UnittestProfileManager : public ::ProfileManagerWithoutInit {
37 public:
38  explicit UnittestProfileManager(const base::FilePath& user_data_dir)
39      : ::ProfileManagerWithoutInit(user_data_dir) {}
40
41 protected:
42  virtual Profile* CreateProfileHelper(
43      const base::FilePath& file_path) OVERRIDE {
44    if (!base::PathExists(file_path)) {
45      if (!base::CreateDirectory(file_path))
46        return NULL;
47    }
48    return new TestingProfile(file_path, NULL);
49  }
50};
51
52
53class UserManagerTest : public testing::Test {
54 protected:
55  virtual void SetUp() OVERRIDE {
56    CommandLine& command_line = *CommandLine::ForCurrentProcess();
57    command_line.AppendSwitch(::switches::kTestType);
58    command_line.AppendSwitch(
59        chromeos::switches::kIgnoreUserProfileMappingForTests);
60
61    cros_settings_ = CrosSettings::Get();
62
63    // Replace the real DeviceSettingsProvider with a stub.
64    device_settings_provider_ =
65        cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo);
66    EXPECT_TRUE(device_settings_provider_);
67    EXPECT_TRUE(
68        cros_settings_->RemoveSettingsProvider(device_settings_provider_));
69    cros_settings_->AddSettingsProvider(&stub_settings_provider_);
70
71    // Populate the stub DeviceSettingsProvider with valid values.
72    SetDeviceSettings(false, "", false);
73
74    // Register an in-memory local settings instance.
75    local_state_.reset(
76        new ScopedTestingLocalState(TestingBrowserProcess::GetGlobal()));
77
78    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
79    TestingBrowserProcess::GetGlobal()->SetProfileManager(
80        new UnittestProfileManager(temp_dir_.path()));
81
82    chromeos::FakeDBusThreadManager* dbus_manager =
83        new chromeos::FakeDBusThreadManager();
84    chromeos::DBusThreadManager::InitializeForTesting(dbus_manager);
85
86    ResetUserManager();
87  }
88
89  virtual void TearDown() OVERRIDE {
90    // Unregister the in-memory local settings instance.
91    local_state_.reset();
92
93    // Restore the real DeviceSettingsProvider.
94    EXPECT_TRUE(
95      cros_settings_->RemoveSettingsProvider(&stub_settings_provider_));
96    cros_settings_->AddSettingsProvider(device_settings_provider_);
97
98    // Shut down the DeviceSettingsService.
99    DeviceSettingsService::Get()->UnsetSessionManager();
100    TestingBrowserProcess::GetGlobal()->SetProfileManager(NULL);
101
102    base::RunLoop().RunUntilIdle();
103    chromeos::DBusThreadManager::Shutdown();
104  }
105
106  UserManagerImpl* GetUserManagerImpl() const {
107    return static_cast<UserManagerImpl*>(UserManager::Get());
108  }
109
110  bool GetUserManagerEphemeralUsersEnabled() const {
111    return GetUserManagerImpl()->ephemeral_users_enabled_;
112  }
113
114  void SetUserManagerEphemeralUsersEnabled(bool ephemeral_users_enabled) {
115    GetUserManagerImpl()->ephemeral_users_enabled_ = ephemeral_users_enabled;
116  }
117
118  const std::string& GetUserManagerOwnerEmail() const {
119    return GetUserManagerImpl()-> owner_email_;
120  }
121
122  void SetUserManagerOwnerEmail(const std::string& owner_email) {
123    GetUserManagerImpl()->owner_email_ = owner_email;
124  }
125
126  void ResetUserManager() {
127    // Reset the UserManager singleton.
128    user_manager_enabler_.reset();
129    // Initialize the UserManager singleton to a fresh UserManagerImpl instance.
130    user_manager_enabler_.reset(
131        new ScopedUserManagerEnabler(new UserManagerImpl));
132  }
133
134  void SetDeviceSettings(bool ephemeral_users_enabled,
135                         const std::string &owner,
136                         bool locally_managed_users_enabled) {
137    base::FundamentalValue
138        ephemeral_users_enabled_value(ephemeral_users_enabled);
139    stub_settings_provider_.Set(kAccountsPrefEphemeralUsersEnabled,
140        ephemeral_users_enabled_value);
141    base::StringValue owner_value(owner);
142    stub_settings_provider_.Set(kDeviceOwner, owner_value);
143    stub_settings_provider_.Set(kAccountsPrefSupervisedUsersEnabled,
144        base::FundamentalValue(locally_managed_users_enabled));
145  }
146
147  void RetrieveTrustedDevicePolicies() {
148    GetUserManagerImpl()->RetrieveTrustedDevicePolicies();
149  }
150
151 protected:
152  content::TestBrowserThreadBundle thread_bundle_;
153
154  CrosSettings* cros_settings_;
155  CrosSettingsProvider* device_settings_provider_;
156  StubCrosSettingsProvider stub_settings_provider_;
157  scoped_ptr<ScopedTestingLocalState> local_state_;
158
159  ScopedTestDeviceSettingsService test_device_settings_service_;
160  ScopedTestCrosSettings test_cros_settings_;
161
162  scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
163  base::ScopedTempDir temp_dir_;
164};
165
166TEST_F(UserManagerTest, RetrieveTrustedDevicePolicies) {
167  SetUserManagerEphemeralUsersEnabled(true);
168  SetUserManagerOwnerEmail("");
169
170  SetDeviceSettings(false, "owner@invalid.domain", false);
171  RetrieveTrustedDevicePolicies();
172
173  EXPECT_FALSE(GetUserManagerEphemeralUsersEnabled());
174  EXPECT_EQ(GetUserManagerOwnerEmail(), "owner@invalid.domain");
175}
176
177TEST_F(UserManagerTest, RemoveAllExceptOwnerFromList) {
178  UserManager::Get()->UserLoggedIn(
179      "owner@invalid.domain", "owner@invalid.domain", false);
180  ResetUserManager();
181  UserManager::Get()->UserLoggedIn(
182      "user0@invalid.domain", "owner@invalid.domain", false);
183  ResetUserManager();
184  UserManager::Get()->UserLoggedIn(
185      "user1@invalid.domain", "owner@invalid.domain", false);
186  ResetUserManager();
187
188  const UserList* users = &UserManager::Get()->GetUsers();
189  ASSERT_EQ(3U, users->size());
190  EXPECT_EQ((*users)[0]->email(), "user1@invalid.domain");
191  EXPECT_EQ((*users)[1]->email(), "user0@invalid.domain");
192  EXPECT_EQ((*users)[2]->email(), "owner@invalid.domain");
193
194  SetDeviceSettings(true, "owner@invalid.domain", false);
195  RetrieveTrustedDevicePolicies();
196
197  users = &UserManager::Get()->GetUsers();
198  EXPECT_EQ(1U, users->size());
199  EXPECT_EQ((*users)[0]->email(), "owner@invalid.domain");
200}
201
202TEST_F(UserManagerTest, RegularUserLoggedInAsEphemeral) {
203  SetDeviceSettings(true, "owner@invalid.domain", false);
204  RetrieveTrustedDevicePolicies();
205
206  UserManager::Get()->UserLoggedIn(
207      "owner@invalid.domain", "user0@invalid.domain", false);
208  ResetUserManager();
209  UserManager::Get()->UserLoggedIn(
210      "user0@invalid.domain", "user0@invalid.domain", false);
211  ResetUserManager();
212
213  const UserList* users = &UserManager::Get()->GetUsers();
214  EXPECT_EQ(1U, users->size());
215  EXPECT_EQ((*users)[0]->email(), "owner@invalid.domain");
216}
217
218}  // namespace chromeos
219