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.
5 #include "base/memory/scoped_ptr.h"
6 #include "base/path_service.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/prefs/scoped_user_pref_update.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service.h"
17 #include "chrome/browser/supervised_user/legacy/custodian_profile_downloader_service_factory.h"
18 #include "chrome/browser/supervised_user/permission_request_creator.h"
19 #include "chrome/browser/supervised_user/supervised_user_service.h"
20 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
21 #include "chrome/browser/supervised_user/supervised_user_whitelist_service.h"
22 #include "chrome/browser/ui/browser_list.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/test/base/testing_profile.h"
26 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
27 #include "components/signin/core/browser/signin_manager.h"
28 #include "components/version_info/version_info.h"
29 #include "content/public/test/test_browser_thread_bundle.h"
30 #include "content/public/test/test_utils.h"
31 #include "testing/gtest/include/gtest/gtest.h"
33 #if defined(ENABLE_EXTENSIONS)
34 #include "chrome/browser/extensions/extension_service.h"
35 #include "chrome/browser/extensions/extension_service_test_base.h"
36 #include "chrome/browser/extensions/unpacked_installer.h"
37 #include "chrome/common/extensions/features/feature_channel.h"
38 #include "extensions/common/extension.h"
39 #include "extensions/common/extension_builder.h"
40 #include "extensions/common/manifest_constants.h"
43 using content::MessageLoopRunner
;
47 #if !defined(OS_ANDROID) && !defined(OS_IOS)
48 void OnProfileDownloadedFail(const base::string16
& full_name
) {
49 ASSERT_TRUE(false) << "Profile download should not have succeeded.";
53 // Base class for helper objects that wait for certain events to happen.
54 // This class will ensure that calls to QuitRunLoop() (triggered by a subclass)
55 // are balanced with Wait() calls.
56 class AsyncTestHelper
{
65 // |quit_called_| will be initialized in Reset().
70 EXPECT_FALSE(quit_called_
);
74 // QuitRunLoop() can not be called more than once between calls to Wait().
75 ASSERT_FALSE(quit_called_
);
83 run_loop_
.reset(new base::RunLoop
);
86 scoped_ptr
<base::RunLoop
> run_loop_
;
89 DISALLOW_COPY_AND_ASSIGN(AsyncTestHelper
);
92 class SupervisedUserURLFilterObserver
93 : public AsyncTestHelper
,
94 public SupervisedUserURLFilter::Observer
{
96 SupervisedUserURLFilterObserver() : scoped_observer_(this) {}
97 ~SupervisedUserURLFilterObserver() {}
99 void Init(SupervisedUserURLFilter
* url_filter
) {
100 scoped_observer_
.Add(url_filter
);
103 // SupervisedUserURLFilter::Observer
104 void OnSiteListUpdated() override
{
109 ScopedObserver
<SupervisedUserURLFilter
, SupervisedUserURLFilter::Observer
>
112 DISALLOW_COPY_AND_ASSIGN(SupervisedUserURLFilterObserver
);
115 class SiteListObserver
: public AsyncTestHelper
{
117 SiteListObserver() {}
118 ~SiteListObserver() {}
120 void Init(SupervisedUserWhitelistService
* service
) {
121 service
->AddSiteListsChangedCallback(base::Bind(
122 &SiteListObserver::OnSiteListsChanged
, base::Unretained(this)));
124 // The initial call to AddSiteListsChangedCallback will call
125 // OnSiteListsChanged(), so we balance it out by calling Wait().
129 const std::vector
<scoped_refptr
<SupervisedUserSiteList
>>& site_lists() {
133 const std::vector
<SupervisedUserSiteList::Site
>& sites() {
138 void OnSiteListsChanged(
139 const std::vector
<scoped_refptr
<SupervisedUserSiteList
>>& site_lists
) {
140 site_lists_
= site_lists
;
142 for (const scoped_refptr
<SupervisedUserSiteList
>& site_list
: site_lists
) {
143 const std::vector
<SupervisedUserSiteList::Site
>& sites
=
145 sites_
.insert(sites_
.end(), sites
.begin(), sites
.end());
151 std::vector
<scoped_refptr
<SupervisedUserSiteList
>> site_lists_
;
152 std::vector
<SupervisedUserSiteList::Site
> sites_
;
154 DISALLOW_COPY_AND_ASSIGN(SiteListObserver
);
157 class AsyncResultHolder
{
159 AsyncResultHolder() : result_(false) {}
160 ~AsyncResultHolder() {}
162 void SetResult(bool result
) {
173 base::RunLoop run_loop_
;
176 DISALLOW_COPY_AND_ASSIGN(AsyncResultHolder
);
179 class SupervisedUserServiceTest
: public ::testing::Test
{
181 SupervisedUserServiceTest() {}
183 void SetUp() override
{
184 TestingProfile::Builder builder
;
185 builder
.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
186 BuildFakeProfileOAuth2TokenService
);
187 profile_
= builder
.Build();
188 supervised_user_service_
=
189 SupervisedUserServiceFactory::GetForProfile(profile_
.get());
192 void TearDown() override
{ profile_
.reset(); }
194 ~SupervisedUserServiceTest() override
{}
197 void AddURLAccessRequest(const GURL
& url
, AsyncResultHolder
* result_holder
) {
198 supervised_user_service_
->AddURLAccessRequest(
199 url
, base::Bind(&AsyncResultHolder::SetResult
,
200 base::Unretained(result_holder
)));
203 content::TestBrowserThreadBundle thread_bundle_
;
204 scoped_ptr
<TestingProfile
> profile_
;
205 SupervisedUserService
* supervised_user_service_
;
210 TEST_F(SupervisedUserServiceTest
, ChangesIncludedSessionOnChangedSettings
) {
211 supervised_user_service_
->Init();
212 EXPECT_TRUE(supervised_user_service_
->IncludesSyncSessionsType());
213 profile_
->GetPrefs()->SetBoolean(prefs::kRecordHistory
, false);
214 EXPECT_FALSE(supervised_user_service_
->IncludesSyncSessionsType());
217 #if !defined(OS_ANDROID) && !defined(OS_IOS)
218 // Ensure that the CustodianProfileDownloaderService shuts down cleanly. If no
219 // DCHECK is hit when the service is destroyed, this test passed.
220 TEST_F(SupervisedUserServiceTest
, ShutDownCustodianProfileDownloader
) {
221 CustodianProfileDownloaderService
* downloader_service
=
222 CustodianProfileDownloaderServiceFactory::GetForProfile(profile_
.get());
224 // Emulate being logged in, then start to download a profile so a
225 // ProfileDownloader gets created.
226 SigninManagerFactory::GetForProfile(profile_
.get())->
227 SetAuthenticatedAccountInfo("12345", "Logged In");
228 downloader_service
->DownloadProfile(base::Bind(&OnProfileDownloadedFail
));
234 class MockPermissionRequestCreator
: public PermissionRequestCreator
{
236 MockPermissionRequestCreator() : enabled_(false) {}
237 ~MockPermissionRequestCreator() override
{}
239 void set_enabled(bool enabled
) {
243 const std::vector
<GURL
>& requested_urls() const {
244 return requested_urls_
;
247 void AnswerRequest(size_t index
, bool result
) {
248 ASSERT_LT(index
, requested_urls_
.size());
249 callbacks_
[index
].Run(result
);
250 callbacks_
.erase(callbacks_
.begin() + index
);
251 requested_urls_
.erase(requested_urls_
.begin() + index
);
255 // PermissionRequestCreator:
256 bool IsEnabled() const override
{ return enabled_
; }
258 void CreateURLAccessRequest(const GURL
& url_requested
,
259 const SuccessCallback
& callback
) override
{
260 ASSERT_TRUE(enabled_
);
261 requested_urls_
.push_back(url_requested
);
262 callbacks_
.push_back(callback
);
265 void CreateExtensionUpdateRequest(const std::string
& id
,
266 const SuccessCallback
& callback
) override
{
271 std::vector
<GURL
> requested_urls_
;
272 std::vector
<SuccessCallback
> callbacks_
;
274 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator
);
279 TEST_F(SupervisedUserServiceTest
, CreatePermissionRequest
) {
280 GURL
url("http://www.example.com");
282 // Without any permission request creators, it should be disabled, and any
283 // AddURLAccessRequest() calls should fail.
284 EXPECT_FALSE(supervised_user_service_
->AccessRequestsEnabled());
286 AsyncResultHolder result_holder
;
287 AddURLAccessRequest(url
, &result_holder
);
288 EXPECT_FALSE(result_holder
.GetResult());
291 // Add a disabled permission request creator. This should not change anything.
292 MockPermissionRequestCreator
* creator
= new MockPermissionRequestCreator
;
293 supervised_user_service_
->AddPermissionRequestCreator(
294 make_scoped_ptr(creator
));
296 EXPECT_FALSE(supervised_user_service_
->AccessRequestsEnabled());
298 AsyncResultHolder result_holder
;
299 AddURLAccessRequest(url
, &result_holder
);
300 EXPECT_FALSE(result_holder
.GetResult());
303 // Enable the permission request creator. This should enable permission
304 // requests and queue them up.
305 creator
->set_enabled(true);
306 EXPECT_TRUE(supervised_user_service_
->AccessRequestsEnabled());
308 AsyncResultHolder result_holder
;
309 AddURLAccessRequest(url
, &result_holder
);
310 ASSERT_EQ(1u, creator
->requested_urls().size());
311 EXPECT_EQ(url
.spec(), creator
->requested_urls()[0].spec());
313 creator
->AnswerRequest(0, true);
314 EXPECT_TRUE(result_holder
.GetResult());
318 AsyncResultHolder result_holder
;
319 AddURLAccessRequest(url
, &result_holder
);
320 ASSERT_EQ(1u, creator
->requested_urls().size());
321 EXPECT_EQ(url
.spec(), creator
->requested_urls()[0].spec());
323 creator
->AnswerRequest(0, false);
324 EXPECT_FALSE(result_holder
.GetResult());
327 // Add a second permission request creator.
328 MockPermissionRequestCreator
* creator_2
= new MockPermissionRequestCreator
;
329 creator_2
->set_enabled(true);
330 supervised_user_service_
->AddPermissionRequestCreator(
331 make_scoped_ptr(creator_2
));
334 AsyncResultHolder result_holder
;
335 AddURLAccessRequest(url
, &result_holder
);
336 ASSERT_EQ(1u, creator
->requested_urls().size());
337 EXPECT_EQ(url
.spec(), creator
->requested_urls()[0].spec());
339 // Make the first creator succeed. This should make the whole thing succeed.
340 creator
->AnswerRequest(0, true);
341 EXPECT_TRUE(result_holder
.GetResult());
345 AsyncResultHolder result_holder
;
346 AddURLAccessRequest(url
, &result_holder
);
347 ASSERT_EQ(1u, creator
->requested_urls().size());
348 EXPECT_EQ(url
.spec(), creator
->requested_urls()[0].spec());
350 // Make the first creator fail. This should fall back to the second one.
351 creator
->AnswerRequest(0, false);
352 ASSERT_EQ(1u, creator_2
->requested_urls().size());
353 EXPECT_EQ(url
.spec(), creator_2
->requested_urls()[0].spec());
355 // Make the second creator succeed, which will make the whole thing succeed.
356 creator_2
->AnswerRequest(0, true);
357 EXPECT_TRUE(result_holder
.GetResult());
361 #if defined(ENABLE_EXTENSIONS)
362 class SupervisedUserServiceExtensionTestBase
363 : public extensions::ExtensionServiceTestBase
{
365 explicit SupervisedUserServiceExtensionTestBase(bool is_supervised
)
366 : is_supervised_(is_supervised
),
367 channel_(version_info::Channel::DEV
) {}
368 ~SupervisedUserServiceExtensionTestBase() override
{}
370 void SetUp() override
{
371 ExtensionServiceTestBase::SetUp();
372 ExtensionServiceTestBase::ExtensionServiceInitParams params
=
373 CreateDefaultInitParams();
374 params
.profile_is_supervised
= is_supervised_
;
375 InitializeExtensionService(params
);
376 SupervisedUserService
* service
=
377 SupervisedUserServiceFactory::GetForProfile(profile_
.get());
379 site_list_observer_
.Init(service
->GetWhitelistService());
381 SupervisedUserURLFilter
* url_filter
= service
->GetURLFilterForUIThread();
382 url_filter
->SetBlockingTaskRunnerForTesting(
383 base::ThreadTaskRunnerHandle::Get());
384 url_filter_observer_
.Init(url_filter
);
386 // Wait for the initial update to finish.
387 url_filter_observer_
.Wait();
390 void TearDown() override
{
391 // Flush the message loop, to ensure all posted tasks run.
392 base::RunLoop().RunUntilIdle();
396 scoped_refptr
<extensions::Extension
> MakeThemeExtension() {
397 scoped_ptr
<base::DictionaryValue
> source(new base::DictionaryValue());
398 source
->SetString(extensions::manifest_keys::kName
, "Theme");
399 source
->Set(extensions::manifest_keys::kTheme
, new base::DictionaryValue());
400 source
->SetString(extensions::manifest_keys::kVersion
, "1.0");
401 extensions::ExtensionBuilder builder
;
402 scoped_refptr
<extensions::Extension
> extension
=
403 builder
.SetManifest(source
.Pass()).Build();
407 scoped_refptr
<extensions::Extension
> MakeExtension(bool by_custodian
) {
408 scoped_ptr
<base::DictionaryValue
> manifest
= extensions::DictionaryBuilder()
409 .Set(extensions::manifest_keys::kName
, "Extension")
410 .Set(extensions::manifest_keys::kVersion
, "1.0")
412 int creation_flags
= extensions::Extension::NO_FLAGS
;
414 creation_flags
|= extensions::Extension::WAS_INSTALLED_BY_CUSTODIAN
;
415 extensions::ExtensionBuilder builder
;
416 scoped_refptr
<extensions::Extension
> extension
=
417 builder
.SetManifest(manifest
.Pass()).AddFlags(creation_flags
).Build();
422 extensions::ScopedCurrentChannel channel_
;
423 SiteListObserver site_list_observer_
;
424 SupervisedUserURLFilterObserver url_filter_observer_
;
427 class SupervisedUserServiceExtensionTestUnsupervised
428 : public SupervisedUserServiceExtensionTestBase
{
430 SupervisedUserServiceExtensionTestUnsupervised()
431 : SupervisedUserServiceExtensionTestBase(false) {}
434 class SupervisedUserServiceExtensionTest
435 : public SupervisedUserServiceExtensionTestBase
{
437 SupervisedUserServiceExtensionTest()
438 : SupervisedUserServiceExtensionTestBase(true) {}
441 TEST_F(SupervisedUserServiceExtensionTest
, ExtensionManagementPolicyProvider
) {
442 SupervisedUserService
* supervised_user_service
=
443 SupervisedUserServiceFactory::GetForProfile(profile_
.get());
444 ASSERT_TRUE(profile_
->IsSupervised());
446 // Check that a supervised user can install and uninstall a theme.
448 scoped_refptr
<extensions::Extension
> theme
= MakeThemeExtension();
450 base::string16 error_1
;
451 EXPECT_TRUE(supervised_user_service
->UserMayLoad(theme
.get(), &error_1
));
452 EXPECT_TRUE(error_1
.empty());
454 base::string16 error_2
;
456 supervised_user_service
->MustRemainInstalled(theme
.get(), &error_2
));
457 EXPECT_TRUE(error_2
.empty());
460 // Now check a different kind of extension; the supervised user should not be
463 scoped_refptr
<extensions::Extension
> extension
= MakeExtension(false);
465 base::string16 error
;
466 EXPECT_FALSE(supervised_user_service
->UserMayLoad(extension
.get(), &error
));
467 EXPECT_FALSE(error
.empty());
471 // Check that a custodian-installed extension may be loaded, but not
473 scoped_refptr
<extensions::Extension
> extension
= MakeExtension(true);
475 base::string16 error_1
;
477 supervised_user_service
->UserMayLoad(extension
.get(), &error_1
));
478 EXPECT_TRUE(error_1
.empty());
480 base::string16 error_2
;
482 supervised_user_service
->MustRemainInstalled(extension
.get(),
484 EXPECT_FALSE(error_2
.empty());
488 EXPECT_FALSE(supervised_user_service
->GetDebugPolicyProviderName().empty());
492 TEST_F(SupervisedUserServiceExtensionTest
, NoContentPacks
) {
493 SupervisedUserService
* supervised_user_service
=
494 SupervisedUserServiceFactory::GetForProfile(profile_
.get());
495 SupervisedUserURLFilter
* url_filter
=
496 supervised_user_service
->GetURLFilterForUIThread();
498 // ASSERT_EQ instead of ASSERT_TRUE([...].empty()) so that the error
499 // message contains the size in case of failure.
500 ASSERT_EQ(0u, site_list_observer_
.site_lists().size());
502 GURL
url("http://youtube.com");
503 EXPECT_EQ(SupervisedUserURLFilter::ALLOW
,
504 url_filter
->GetFilteringBehaviorForURL(url
));
507 TEST_F(SupervisedUserServiceExtensionTest
, InstallContentPacks
) {
508 SupervisedUserService
* supervised_user_service
=
509 SupervisedUserServiceFactory::GetForProfile(profile_
.get());
510 SupervisedUserURLFilter
* url_filter
=
511 supervised_user_service
->GetURLFilterForUIThread();
513 GURL
example_url("http://example.com");
514 GURL
moose_url("http://moose.org");
515 EXPECT_EQ(SupervisedUserURLFilter::ALLOW
,
516 url_filter
->GetFilteringBehaviorForURL(example_url
));
518 profile_
->GetPrefs()->SetInteger(
519 prefs::kDefaultSupervisedUserFilteringBehavior
,
520 SupervisedUserURLFilter::BLOCK
);
521 EXPECT_EQ(SupervisedUserURLFilter::BLOCK
,
522 url_filter
->GetFilteringBehaviorForURL(example_url
));
524 profile_
->GetPrefs()->SetInteger(
525 prefs::kDefaultSupervisedUserFilteringBehavior
,
526 SupervisedUserURLFilter::WARN
);
527 EXPECT_EQ(SupervisedUserURLFilter::WARN
,
528 url_filter
->GetFilteringBehaviorForURL(example_url
));
531 base::FilePath test_data_dir
;
532 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &test_data_dir
));
533 SupervisedUserWhitelistService
* whitelist_service
=
534 supervised_user_service
->GetWhitelistService();
535 base::FilePath whitelist_path
=
536 test_data_dir
.AppendASCII("whitelists/content_pack/site_list.json");
537 whitelist_service
->LoadWhitelistForTesting("aaaa", whitelist_path
);
538 site_list_observer_
.Wait();
540 ASSERT_EQ(1u, site_list_observer_
.site_lists().size());
541 ASSERT_EQ(3u, site_list_observer_
.sites().size());
542 EXPECT_EQ(base::ASCIIToUTF16("YouTube"), site_list_observer_
.sites()[0].name
);
543 EXPECT_EQ(base::ASCIIToUTF16("Homestar Runner"),
544 site_list_observer_
.sites()[1].name
);
545 EXPECT_EQ(base::string16(), site_list_observer_
.sites()[2].name
);
547 url_filter_observer_
.Wait();
548 EXPECT_EQ(SupervisedUserURLFilter::ALLOW
,
549 url_filter
->GetFilteringBehaviorForURL(example_url
));
550 EXPECT_EQ(SupervisedUserURLFilter::WARN
,
551 url_filter
->GetFilteringBehaviorForURL(moose_url
));
553 // Load a second whitelist.
555 test_data_dir
.AppendASCII("whitelists/content_pack_2/site_list.json");
556 whitelist_service
->LoadWhitelistForTesting("bbbb", whitelist_path
);
557 site_list_observer_
.Wait();
559 ASSERT_EQ(2u, site_list_observer_
.site_lists().size());
560 ASSERT_EQ(4u, site_list_observer_
.sites().size());
562 // The site lists might be returned in any order, so we put them into a set.
563 std::set
<std::string
> site_names
;
564 for (const SupervisedUserSiteList::Site
& site
: site_list_observer_
.sites())
565 site_names
.insert(base::UTF16ToUTF8(site
.name
));
566 EXPECT_EQ(1u, site_names
.count("YouTube"));
567 EXPECT_EQ(1u, site_names
.count("Homestar Runner"));
568 EXPECT_EQ(1u, site_names
.count(std::string()));
569 EXPECT_EQ(1u, site_names
.count("Moose"));
571 url_filter_observer_
.Wait();
572 EXPECT_EQ(SupervisedUserURLFilter::ALLOW
,
573 url_filter
->GetFilteringBehaviorForURL(example_url
));
574 EXPECT_EQ(SupervisedUserURLFilter::ALLOW
,
575 url_filter
->GetFilteringBehaviorForURL(moose_url
));
577 // Unload the first whitelist.
578 whitelist_service
->UnloadWhitelist("aaaa");
579 site_list_observer_
.Wait();
581 ASSERT_EQ(1u, site_list_observer_
.site_lists().size());
582 ASSERT_EQ(1u, site_list_observer_
.sites().size());
583 EXPECT_EQ(base::ASCIIToUTF16("Moose"), site_list_observer_
.sites()[0].name
);
585 url_filter_observer_
.Wait();
586 EXPECT_EQ(SupervisedUserURLFilter::WARN
,
587 url_filter
->GetFilteringBehaviorForURL(example_url
));
588 EXPECT_EQ(SupervisedUserURLFilter::ALLOW
,
589 url_filter
->GetFilteringBehaviorForURL(moose_url
));
591 #endif // defined(ENABLE_EXTENSIONS)