1 // Copyright 2019 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/assistant/assistant_util.h"
6 
7 #include <memory>
8 #include <string>
9 
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
12 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
13 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
14 #include "chrome/test/base/testing_browser_process.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "chrome/test/base/testing_profile_manager.h"
17 #include "components/account_id/account_id.h"
18 #include "components/language/core/browser/pref_names.h"
19 #include "components/prefs/testing_pref_service.h"
20 #include "components/signin/public/identity_manager/consent_level.h"
21 #include "components/signin/public/identity_manager/identity_manager.h"
22 #include "components/signin/public/identity_manager/identity_test_environment.h"
23 #include "components/user_manager/scoped_user_manager.h"
24 #include "components/user_manager/user_manager.h"
25 #include "components/user_manager/user_type.h"
26 #include "content/public/common/content_switches.h"
27 #include "content/public/test/browser_task_environment.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "third_party/icu/source/common/unicode/locid.h"
30 #include "ui/events/devices/device_data_manager.h"
31 
32 namespace assistant {
33 namespace {
34 
35 constexpr char kTestProfileName[] = "user@gmail.com";
36 constexpr char kTestGaiaId[] = "1234567890";
37 
38 class ScopedSpoofGoogleBrandedDevice {
39  public:
ScopedSpoofGoogleBrandedDevice()40   ScopedSpoofGoogleBrandedDevice() { OverrideIsGoogleDeviceForTesting(true); }
~ScopedSpoofGoogleBrandedDevice()41   ~ScopedSpoofGoogleBrandedDevice() { OverrideIsGoogleDeviceForTesting(false); }
42 };
43 
44 class FakeUserManagerWithLocalState : public chromeos::FakeChromeUserManager {
45  public:
FakeUserManagerWithLocalState(TestingProfileManager * testing_profile_manager)46   explicit FakeUserManagerWithLocalState(
47       TestingProfileManager* testing_profile_manager)
48       : testing_profile_manager_(testing_profile_manager),
49         test_local_state_(std::make_unique<TestingPrefServiceSimple>()) {
50     RegisterPrefs(test_local_state_->registry());
51   }
52 
GetLocalState() const53   PrefService* GetLocalState() const override {
54     return test_local_state_.get();
55   }
56 
testing_profile_manager()57   TestingProfileManager* testing_profile_manager() {
58     return testing_profile_manager_;
59   }
60 
61  private:
62   // Unowned pointer.
63   TestingProfileManager* const testing_profile_manager_;
64 
65   std::unique_ptr<TestingPrefServiceSimple> test_local_state_;
66 
67   DISALLOW_COPY_AND_ASSIGN(FakeUserManagerWithLocalState);
68 };
69 
70 class ScopedLogIn {
71  public:
ScopedLogIn(FakeUserManagerWithLocalState * fake_user_manager,signin::IdentityTestEnvironment * identity_test_env,const AccountId & account_id,user_manager::UserType user_type=user_manager::USER_TYPE_REGULAR)72   ScopedLogIn(
73       FakeUserManagerWithLocalState* fake_user_manager,
74       signin::IdentityTestEnvironment* identity_test_env,
75       const AccountId& account_id,
76       user_manager::UserType user_type = user_manager::USER_TYPE_REGULAR)
77       : fake_user_manager_(fake_user_manager),
78         identity_test_env_(identity_test_env),
79         account_id_(account_id) {
80     PreventAccessToDBus();
81     RunValidityChecks(user_type);
82     AddUser(user_type);
83 
84     fake_user_manager_->LoginUser(account_id_);
85 
86     MakeAccountAvailableAsPrimaryAccount(user_type);
87   }
88 
~ScopedLogIn()89   ~ScopedLogIn() { fake_user_manager_->RemoveUserFromList(account_id_); }
90 
91  private:
92   // Prevent access to DBus. This switch is reset in case set from test SetUp
93   // due massive usage of InitFromArgv.
PreventAccessToDBus()94   void PreventAccessToDBus() {
95     base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
96     if (!command_line.HasSwitch(switches::kTestType))
97       command_line.AppendSwitch(switches::kTestType);
98   }
99 
MakeAccountAvailableAsPrimaryAccount(user_manager::UserType user_type)100   void MakeAccountAvailableAsPrimaryAccount(user_manager::UserType user_type) {
101     // Guest user can never be a primary account.
102     if (user_type == user_manager::USER_TYPE_GUEST)
103       return;
104 
105     if (!identity_test_env_->identity_manager()->HasPrimaryAccount(
106             signin::ConsentLevel::kNotRequired)) {
107       identity_test_env_->MakeUnconsentedPrimaryAccountAvailable(
108           account_id_.GetUserEmail());
109     }
110   }
111 
112   // Run validity checks ensuring the account id is valid for the given user
113   // type. If these checks go off your test is testing something that can not
114   // happen.
RunValidityChecks(user_manager::UserType user_type) const115   void RunValidityChecks(user_manager::UserType user_type) const {
116     switch (user_type) {
117       case user_manager::USER_TYPE_REGULAR:
118       case user_manager::USER_TYPE_CHILD:
119         EXPECT_TRUE(IsGaiaAccount());
120         return;
121       case user_manager::USER_TYPE_ACTIVE_DIRECTORY:
122       case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
123       case user_manager::USER_TYPE_KIOSK_APP:
124       case user_manager::USER_TYPE_ARC_KIOSK_APP:
125       case user_manager::USER_TYPE_WEB_KIOSK_APP:
126         EXPECT_FALSE(IsGaiaAccount());
127         return;
128       case user_manager::USER_TYPE_GUEST:
129         // Guest user must use the guest user account id.
130         EXPECT_EQ(account_id_, fake_user_manager_->GetGuestAccountId());
131         return;
132       case user_manager::NUM_USER_TYPES:
133       case user_manager::USER_TYPE_SUPERVISED:
134         NOTREACHED();
135     }
136   }
137 
AddUser(user_manager::UserType user_type)138   void AddUser(user_manager::UserType user_type) {
139     switch (user_type) {
140       case user_manager::USER_TYPE_REGULAR:
141         fake_user_manager_->AddUser(account_id_);
142         return;
143       case user_manager::USER_TYPE_ACTIVE_DIRECTORY:
144         fake_user_manager_->AddActiveDirectoryUser(account_id_);
145         return;
146       case user_manager::USER_TYPE_PUBLIC_ACCOUNT:
147         fake_user_manager_->AddPublicAccountUser(account_id_);
148         return;
149       case user_manager::USER_TYPE_KIOSK_APP:
150         fake_user_manager_->AddKioskAppUser(account_id_);
151         return;
152       case user_manager::USER_TYPE_ARC_KIOSK_APP:
153         fake_user_manager_->AddArcKioskAppUser(account_id_);
154         return;
155       case user_manager::USER_TYPE_WEB_KIOSK_APP:
156         fake_user_manager_->AddWebKioskAppUser(account_id_);
157         return;
158       case user_manager::USER_TYPE_CHILD:
159         fake_user_manager_->AddChildUser(account_id_);
160         return;
161       case user_manager::USER_TYPE_GUEST:
162         fake_user_manager_->AddGuestUser();
163         return;
164       case user_manager::USER_TYPE_SUPERVISED:
165       case user_manager::NUM_USER_TYPES:
166         NOTREACHED();
167     }
168   }
169 
IsGaiaAccount() const170   bool IsGaiaAccount() const {
171     return account_id_.GetAccountType() == AccountType::GOOGLE;
172   }
173 
174   FakeUserManagerWithLocalState* fake_user_manager_;
175   signin::IdentityTestEnvironment* identity_test_env_;
176   const AccountId account_id_;
177 
178   DISALLOW_COPY_AND_ASSIGN(ScopedLogIn);
179 };
180 
181 }  // namespace
182 
183 class ChromeAssistantUtilTest : public testing::Test {
184  public:
185   ChromeAssistantUtilTest() = default;
186   ~ChromeAssistantUtilTest() override = default;
187 
SetUp()188   void SetUp() override {
189     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
190     profile_manager_ = std::make_unique<TestingProfileManager>(
191         TestingBrowserProcess::GetGlobal());
192     ASSERT_TRUE(profile_manager_->SetUp());
193 
194     profile_ = profile_manager_->CreateTestingProfile(
195         kTestProfileName, /*prefs=*/{}, base::UTF8ToUTF16(kTestProfileName),
196         /*avatar_id=*/0, /*supervised_user_id=*/{},
197         IdentityTestEnvironmentProfileAdaptor::
198             GetIdentityTestEnvironmentFactories());
199     identity_test_env_adaptor_ =
200         std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile_);
201     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
202         std::make_unique<FakeUserManagerWithLocalState>(
203             profile_manager_.get()));
204 
205     ui::DeviceDataManager::CreateInstance();
206   }
207 
TearDown()208   void TearDown() override {
209     ui::DeviceDataManager::DeleteInstance();
210     identity_test_env_adaptor_.reset();
211     user_manager_enabler_.reset();
212     profile_manager_->DeleteTestingProfile(kTestProfileName);
213     profile_ = nullptr;
214     profile_manager_.reset();
215   }
216 
profile()217   TestingProfile* profile() { return profile_; }
218 
identity_test_env()219   signin::IdentityTestEnvironment* identity_test_env() {
220     return identity_test_env_adaptor_->identity_test_env();
221   }
222 
GetFakeUserManager() const223   FakeUserManagerWithLocalState* GetFakeUserManager() const {
224     return static_cast<FakeUserManagerWithLocalState*>(
225         user_manager::UserManager::Get());
226   }
227 
GetActiveDirectoryUserAccountId(const TestingProfile * profile)228   AccountId GetActiveDirectoryUserAccountId(const TestingProfile* profile) {
229     return AccountId::AdFromUserEmailObjGuid(profile->GetProfileUserName(),
230                                              "<obj_guid>");
231   }
232 
GetNonGaiaUserAccountId(const TestingProfile * profile)233   AccountId GetNonGaiaUserAccountId(const TestingProfile* profile) {
234     return AccountId::FromUserEmail(profile->GetProfileUserName());
235   }
236 
GetGaiaUserAccountId(const TestingProfile * profile)237   AccountId GetGaiaUserAccountId(const TestingProfile* profile) {
238     return AccountId::FromUserEmailGaiaId(profile->GetProfileUserName(),
239                                           kTestGaiaId);
240   }
241 
GetGaiaUserAccountId(const std::string & user_name,const std::string & gaia_id)242   AccountId GetGaiaUserAccountId(const std::string& user_name,
243                                  const std::string& gaia_id) {
244     return AccountId::FromUserEmailGaiaId(user_name, gaia_id);
245   }
246 
GetGuestAccountId()247   AccountId GetGuestAccountId() {
248     return GetFakeUserManager()->GetGuestAccountId();
249   }
250 
251  private:
252   content::BrowserTaskEnvironment task_environment_;
253   base::ScopedTempDir data_dir_;
254   std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
255       identity_test_env_adaptor_;
256   std::unique_ptr<TestingProfileManager> profile_manager_;
257   std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
258   // Owned by |profile_manager_|
259   TestingProfile* profile_ = nullptr;
260 
261   DISALLOW_COPY_AND_ASSIGN(ChromeAssistantUtilTest);
262 };
263 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_PrimaryUser)264 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_PrimaryUser) {
265   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
266                     GetGaiaUserAccountId(profile()));
267 
268   EXPECT_EQ(chromeos::assistant::AssistantAllowedState::ALLOWED,
269             IsAssistantAllowedForProfile(profile()));
270 }
271 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_SecondaryUser)272 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_SecondaryUser) {
273   ScopedLogIn secondary_user_login(
274       GetFakeUserManager(), identity_test_env(),
275       GetGaiaUserAccountId("user2@gmail.com", "0123456789"));
276   ScopedLogIn primary_user_login(GetFakeUserManager(), identity_test_env(),
277                                  GetGaiaUserAccountId(profile()));
278 
279   EXPECT_EQ(
280       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_NONPRIMARY_USER,
281       IsAssistantAllowedForProfile(profile()));
282 }
283 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_ChildUser)284 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_ChildUser) {
285   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
286                     GetGaiaUserAccountId(profile()),
287                     user_manager::USER_TYPE_CHILD);
288 
289   EXPECT_EQ(chromeos::assistant::AssistantAllowedState::ALLOWED,
290             IsAssistantAllowedForProfile(profile()));
291 }
292 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_GuestUser)293 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_GuestUser) {
294   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
295                     GetGuestAccountId(), user_manager::USER_TYPE_GUEST);
296 
297   EXPECT_EQ(
298       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_NONPRIMARY_USER,
299       IsAssistantAllowedForProfile(profile()));
300 }
301 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_Locale)302 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_Locale) {
303   profile()->GetTestingPrefService()->SetString(
304       language::prefs::kApplicationLocale, "he");
305   UErrorCode error_code = U_ZERO_ERROR;
306   const icu::Locale& old_locale = icu::Locale::getDefault();
307   icu::Locale::setDefault(icu::Locale("he"), error_code);
308   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
309                     GetGaiaUserAccountId(profile()));
310 
311   EXPECT_EQ(chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_LOCALE,
312             IsAssistantAllowedForProfile(profile()));
313   icu::Locale::setDefault(old_locale, error_code);
314 }
315 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_DemoMode)316 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_DemoMode) {
317   chromeos::DemoSession::SetDemoConfigForTesting(
318       chromeos::DemoSession::DemoModeConfig::kOnline);
319   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
320                     GetNonGaiaUserAccountId(profile()),
321                     user_manager::USER_TYPE_PUBLIC_ACCOUNT);
322   EXPECT_EQ(chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_DEMO_MODE,
323             IsAssistantAllowedForProfile(profile()));
324 
325   chromeos::DemoSession::SetDemoConfigForTesting(
326       chromeos::DemoSession::DemoModeConfig::kNone);
327 }
328 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_PublicSession)329 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_PublicSession) {
330   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
331                     GetNonGaiaUserAccountId(profile()),
332                     user_manager::USER_TYPE_PUBLIC_ACCOUNT);
333   EXPECT_EQ(
334       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_PUBLIC_SESSION,
335       IsAssistantAllowedForProfile(profile()));
336 }
337 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_NonGmail)338 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_NonGmail) {
339   ScopedLogIn login(
340       GetFakeUserManager(), identity_test_env(),
341       GetGaiaUserAccountId("user2@someotherdomain.com", "0123456789"));
342 
343   EXPECT_EQ(
344       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE,
345       IsAssistantAllowedForProfile(profile()));
346 }
347 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_GoogleMail)348 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForProfile_GoogleMail) {
349   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
350                     GetGaiaUserAccountId("user2@googlemail.com", "0123456789"));
351 
352   EXPECT_EQ(chromeos::assistant::AssistantAllowedState::ALLOWED,
353             IsAssistantAllowedForProfile(profile()));
354 }
355 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowed_AllowsNonGmailOnGoogleBrandedDevices)356 TEST_F(ChromeAssistantUtilTest,
357        IsAssistantAllowed_AllowsNonGmailOnGoogleBrandedDevices) {
358   ScopedLogIn login(
359       GetFakeUserManager(), identity_test_env(),
360       GetGaiaUserAccountId("user2@someotherdomain.com", "0123456789"));
361 
362   ScopedSpoofGoogleBrandedDevice make_google_branded_device;
363   EXPECT_EQ(chromeos::assistant::AssistantAllowedState::ALLOWED,
364             IsAssistantAllowedForProfile(profile()));
365 }
366 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForProfile_ActiveDirectoryUser)367 TEST_F(ChromeAssistantUtilTest,
368        IsAssistantAllowedForProfile_ActiveDirectoryUser) {
369   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
370                     GetActiveDirectoryUserAccountId(profile()),
371                     user_manager::USER_TYPE_ACTIVE_DIRECTORY);
372 
373   EXPECT_EQ(
374       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_ACCOUNT_TYPE,
375       IsAssistantAllowedForProfile(profile()));
376 }
377 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForKiosk_KioskApp)378 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForKiosk_KioskApp) {
379   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
380                     GetNonGaiaUserAccountId(profile()),
381                     user_manager::USER_TYPE_KIOSK_APP);
382 
383   EXPECT_EQ(
384       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_KIOSK_MODE,
385       IsAssistantAllowedForProfile(profile()));
386 }
387 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForKiosk_ArcKioskApp)388 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForKiosk_ArcKioskApp) {
389   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
390                     GetNonGaiaUserAccountId(profile()),
391                     user_manager::USER_TYPE_ARC_KIOSK_APP);
392 
393   EXPECT_EQ(
394       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_KIOSK_MODE,
395       IsAssistantAllowedForProfile(profile()));
396 }
397 
TEST_F(ChromeAssistantUtilTest,IsAssistantAllowedForKiosk_WebKioskApp)398 TEST_F(ChromeAssistantUtilTest, IsAssistantAllowedForKiosk_WebKioskApp) {
399   ScopedLogIn login(GetFakeUserManager(), identity_test_env(),
400                     GetNonGaiaUserAccountId(profile()),
401                     user_manager::USER_TYPE_WEB_KIOSK_APP);
402 
403   EXPECT_EQ(
404       chromeos::assistant::AssistantAllowedState::DISALLOWED_BY_KIOSK_MODE,
405       IsAssistantAllowedForProfile(profile()));
406 }
407 
408 }  // namespace assistant
409