Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_service_unittest.cc
blob83778b33fa04d261022880319f2c2c893b1258bd
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 "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/signin/fake_profile_oauth2_token_service.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/signin_manager.h"
27 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "content/public/test/test_utils.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 #if defined(ENABLE_EXTENSIONS)
32 #include "chrome/browser/extensions/extension_service.h"
33 #include "chrome/browser/extensions/extension_service_test_base.h"
34 #include "chrome/browser/extensions/unpacked_installer.h"
35 #include "chrome/common/extensions/features/feature_channel.h"
36 #include "extensions/common/extension.h"
37 #include "extensions/common/extension_builder.h"
38 #include "extensions/common/manifest_constants.h"
39 #endif
41 using content::MessageLoopRunner;
43 namespace {
45 void OnProfileDownloadedFail(const base::string16& full_name) {
46 ASSERT_TRUE(false) << "Profile download should not have succeeded.";
49 // Base class for helper objects that wait for certain events to happen.
50 // This class will ensure that calls to QuitRunLoop() (triggered by a subclass)
51 // are balanced with Wait() calls.
52 class AsyncTestHelper {
53 public:
54 void Wait() {
55 run_loop_->Run();
56 Reset();
59 protected:
60 AsyncTestHelper() {
61 // |quit_called_| will be initialized in Reset().
62 Reset();
65 ~AsyncTestHelper() {
66 EXPECT_FALSE(quit_called_);
69 void QuitRunLoop() {
70 // QuitRunLoop() can not be called more than once between calls to Wait().
71 ASSERT_FALSE(quit_called_);
72 quit_called_ = true;
73 run_loop_->Quit();
76 private:
77 void Reset() {
78 quit_called_ = false;
79 run_loop_.reset(new base::RunLoop);
82 scoped_ptr<base::RunLoop> run_loop_;
83 bool quit_called_;
85 DISALLOW_COPY_AND_ASSIGN(AsyncTestHelper);
88 class SupervisedUserURLFilterObserver
89 : public AsyncTestHelper,
90 public SupervisedUserURLFilter::Observer {
91 public:
92 SupervisedUserURLFilterObserver() : scoped_observer_(this) {}
93 ~SupervisedUserURLFilterObserver() {}
95 void Init(SupervisedUserURLFilter* url_filter) {
96 scoped_observer_.Add(url_filter);
99 // SupervisedUserURLFilter::Observer
100 void OnSiteListUpdated() override {
101 QuitRunLoop();
104 private:
105 ScopedObserver<SupervisedUserURLFilter, SupervisedUserURLFilter::Observer>
106 scoped_observer_;
108 DISALLOW_COPY_AND_ASSIGN(SupervisedUserURLFilterObserver);
111 class SiteListObserver : public AsyncTestHelper {
112 public:
113 SiteListObserver() {}
114 ~SiteListObserver() {}
116 void Init(SupervisedUserWhitelistService* service) {
117 service->AddSiteListsChangedCallback(base::Bind(
118 &SiteListObserver::OnSiteListsChanged, base::Unretained(this)));
120 // The initial call to AddSiteListsChangedCallback will call
121 // OnSiteListsChanged(), so we balance it out by calling Wait().
122 Wait();
125 const std::vector<scoped_refptr<SupervisedUserSiteList>>& site_lists() {
126 return site_lists_;
129 const std::vector<SupervisedUserSiteList::Site>& sites() {
130 return sites_;
133 private:
134 void OnSiteListsChanged(
135 const std::vector<scoped_refptr<SupervisedUserSiteList>>& site_lists) {
136 site_lists_ = site_lists;
137 sites_.clear();
138 for (const scoped_refptr<SupervisedUserSiteList>& site_list : site_lists) {
139 const std::vector<SupervisedUserSiteList::Site>& sites =
140 site_list->sites();
141 sites_.insert(sites_.end(), sites.begin(), sites.end());
144 QuitRunLoop();
147 std::vector<scoped_refptr<SupervisedUserSiteList>> site_lists_;
148 std::vector<SupervisedUserSiteList::Site> sites_;
150 DISALLOW_COPY_AND_ASSIGN(SiteListObserver);
153 class AsyncResultHolder {
154 public:
155 AsyncResultHolder() : result_(false) {}
156 ~AsyncResultHolder() {}
158 void SetResult(bool result) {
159 result_ = result;
160 run_loop_.Quit();
163 bool GetResult() {
164 run_loop_.Run();
165 return result_;
168 private:
169 base::RunLoop run_loop_;
170 bool result_;
172 DISALLOW_COPY_AND_ASSIGN(AsyncResultHolder);
175 class SupervisedUserServiceTest : public ::testing::Test {
176 public:
177 SupervisedUserServiceTest() {}
179 void SetUp() override {
180 TestingProfile::Builder builder;
181 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
182 BuildFakeProfileOAuth2TokenService);
183 profile_ = builder.Build();
184 supervised_user_service_ =
185 SupervisedUserServiceFactory::GetForProfile(profile_.get());
188 void TearDown() override { profile_.reset(); }
190 ~SupervisedUserServiceTest() override {}
192 protected:
193 void AddURLAccessRequest(const GURL& url, AsyncResultHolder* result_holder) {
194 supervised_user_service_->AddURLAccessRequest(
195 url, base::Bind(&AsyncResultHolder::SetResult,
196 base::Unretained(result_holder)));
199 content::TestBrowserThreadBundle thread_bundle_;
200 scoped_ptr<TestingProfile> profile_;
201 SupervisedUserService* supervised_user_service_;
204 } // namespace
206 TEST_F(SupervisedUserServiceTest, ChangesIncludedSessionOnChangedSettings) {
207 supervised_user_service_->Init();
208 EXPECT_TRUE(supervised_user_service_->IncludesSyncSessionsType());
209 profile_->GetPrefs()->SetBoolean(prefs::kRecordHistory, false);
210 EXPECT_FALSE(supervised_user_service_->IncludesSyncSessionsType());
213 // Ensure that the CustodianProfileDownloaderService shuts down cleanly. If no
214 // DCHECK is hit when the service is destroyed, this test passed.
215 TEST_F(SupervisedUserServiceTest, ShutDownCustodianProfileDownloader) {
216 CustodianProfileDownloaderService* downloader_service =
217 CustodianProfileDownloaderServiceFactory::GetForProfile(profile_.get());
219 // Emulate being logged in, then start to download a profile so a
220 // ProfileDownloader gets created.
221 SigninManagerFactory::GetForProfile(profile_.get())->
222 SetAuthenticatedUsername("Logged In");
223 downloader_service->DownloadProfile(base::Bind(&OnProfileDownloadedFail));
226 namespace {
228 class MockPermissionRequestCreator : public PermissionRequestCreator {
229 public:
230 MockPermissionRequestCreator() : enabled_(false) {}
231 ~MockPermissionRequestCreator() override {}
233 void set_enabled(bool enabled) {
234 enabled_ = enabled;
237 const std::vector<GURL>& requested_urls() const {
238 return requested_urls_;
241 void AnswerRequest(size_t index, bool result) {
242 ASSERT_LT(index, requested_urls_.size());
243 callbacks_[index].Run(result);
244 callbacks_.erase(callbacks_.begin() + index);
245 requested_urls_.erase(requested_urls_.begin() + index);
248 private:
249 // PermissionRequestCreator:
250 bool IsEnabled() const override { return enabled_; }
252 void CreateURLAccessRequest(const GURL& url_requested,
253 const SuccessCallback& callback) override {
254 ASSERT_TRUE(enabled_);
255 requested_urls_.push_back(url_requested);
256 callbacks_.push_back(callback);
259 void CreateExtensionUpdateRequest(const std::string& id,
260 const SuccessCallback& callback) override {
261 FAIL();
264 bool enabled_;
265 std::vector<GURL> requested_urls_;
266 std::vector<SuccessCallback> callbacks_;
268 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
271 } // namespace
273 TEST_F(SupervisedUserServiceTest, CreatePermissionRequest) {
274 GURL url("http://www.example.com");
276 // Without any permission request creators, it should be disabled, and any
277 // AddURLAccessRequest() calls should fail.
278 EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled());
280 AsyncResultHolder result_holder;
281 AddURLAccessRequest(url, &result_holder);
282 EXPECT_FALSE(result_holder.GetResult());
285 // Add a disabled permission request creator. This should not change anything.
286 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
287 supervised_user_service_->AddPermissionRequestCreator(
288 make_scoped_ptr(creator));
290 EXPECT_FALSE(supervised_user_service_->AccessRequestsEnabled());
292 AsyncResultHolder result_holder;
293 AddURLAccessRequest(url, &result_holder);
294 EXPECT_FALSE(result_holder.GetResult());
297 // Enable the permission request creator. This should enable permission
298 // requests and queue them up.
299 creator->set_enabled(true);
300 EXPECT_TRUE(supervised_user_service_->AccessRequestsEnabled());
302 AsyncResultHolder result_holder;
303 AddURLAccessRequest(url, &result_holder);
304 ASSERT_EQ(1u, creator->requested_urls().size());
305 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
307 creator->AnswerRequest(0, true);
308 EXPECT_TRUE(result_holder.GetResult());
312 AsyncResultHolder result_holder;
313 AddURLAccessRequest(url, &result_holder);
314 ASSERT_EQ(1u, creator->requested_urls().size());
315 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
317 creator->AnswerRequest(0, false);
318 EXPECT_FALSE(result_holder.GetResult());
321 // Add a second permission request creator.
322 MockPermissionRequestCreator* creator_2 = new MockPermissionRequestCreator;
323 creator_2->set_enabled(true);
324 supervised_user_service_->AddPermissionRequestCreator(
325 make_scoped_ptr(creator_2));
328 AsyncResultHolder result_holder;
329 AddURLAccessRequest(url, &result_holder);
330 ASSERT_EQ(1u, creator->requested_urls().size());
331 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
333 // Make the first creator succeed. This should make the whole thing succeed.
334 creator->AnswerRequest(0, true);
335 EXPECT_TRUE(result_holder.GetResult());
339 AsyncResultHolder result_holder;
340 AddURLAccessRequest(url, &result_holder);
341 ASSERT_EQ(1u, creator->requested_urls().size());
342 EXPECT_EQ(url.spec(), creator->requested_urls()[0].spec());
344 // Make the first creator fail. This should fall back to the second one.
345 creator->AnswerRequest(0, false);
346 ASSERT_EQ(1u, creator_2->requested_urls().size());
347 EXPECT_EQ(url.spec(), creator_2->requested_urls()[0].spec());
349 // Make the second creator succeed, which will make the whole thing succeed.
350 creator_2->AnswerRequest(0, true);
351 EXPECT_TRUE(result_holder.GetResult());
355 #if defined(ENABLE_EXTENSIONS)
356 class SupervisedUserServiceExtensionTestBase
357 : public extensions::ExtensionServiceTestBase {
358 public:
359 explicit SupervisedUserServiceExtensionTestBase(bool is_supervised)
360 : is_supervised_(is_supervised),
361 channel_(chrome::VersionInfo::CHANNEL_DEV) {}
362 ~SupervisedUserServiceExtensionTestBase() override {}
364 void SetUp() override {
365 ExtensionServiceTestBase::SetUp();
366 ExtensionServiceTestBase::ExtensionServiceInitParams params =
367 CreateDefaultInitParams();
368 params.profile_is_supervised = is_supervised_;
369 InitializeExtensionService(params);
370 SupervisedUserService* service =
371 SupervisedUserServiceFactory::GetForProfile(profile_.get());
372 service->Init();
373 site_list_observer_.Init(service->GetWhitelistService());
375 SupervisedUserURLFilter* url_filter = service->GetURLFilterForUIThread();
376 url_filter->SetBlockingTaskRunnerForTesting(
377 base::MessageLoopProxy::current());
378 url_filter_observer_.Init(url_filter);
380 // Wait for the initial update to finish.
381 url_filter_observer_.Wait();
384 void TearDown() override {
385 // Flush the message loop, to ensure all posted tasks run.
386 base::RunLoop().RunUntilIdle();
389 protected:
390 scoped_refptr<extensions::Extension> MakeThemeExtension() {
391 scoped_ptr<base::DictionaryValue> source(new base::DictionaryValue());
392 source->SetString(extensions::manifest_keys::kName, "Theme");
393 source->Set(extensions::manifest_keys::kTheme, new base::DictionaryValue());
394 source->SetString(extensions::manifest_keys::kVersion, "1.0");
395 extensions::ExtensionBuilder builder;
396 scoped_refptr<extensions::Extension> extension =
397 builder.SetManifest(source.Pass()).Build();
398 return extension;
401 scoped_refptr<extensions::Extension> MakeExtension(bool by_custodian) {
402 scoped_ptr<base::DictionaryValue> manifest = extensions::DictionaryBuilder()
403 .Set(extensions::manifest_keys::kName, "Extension")
404 .Set(extensions::manifest_keys::kVersion, "1.0")
405 .Build();
406 int creation_flags = extensions::Extension::NO_FLAGS;
407 if (by_custodian)
408 creation_flags |= extensions::Extension::WAS_INSTALLED_BY_CUSTODIAN;
409 extensions::ExtensionBuilder builder;
410 scoped_refptr<extensions::Extension> extension =
411 builder.SetManifest(manifest.Pass()).AddFlags(creation_flags).Build();
412 return extension;
415 bool is_supervised_;
416 extensions::ScopedCurrentChannel channel_;
417 SiteListObserver site_list_observer_;
418 SupervisedUserURLFilterObserver url_filter_observer_;
421 class SupervisedUserServiceExtensionTestUnsupervised
422 : public SupervisedUserServiceExtensionTestBase {
423 public:
424 SupervisedUserServiceExtensionTestUnsupervised()
425 : SupervisedUserServiceExtensionTestBase(false) {}
428 class SupervisedUserServiceExtensionTest
429 : public SupervisedUserServiceExtensionTestBase {
430 public:
431 SupervisedUserServiceExtensionTest()
432 : SupervisedUserServiceExtensionTestBase(true) {}
435 TEST_F(SupervisedUserServiceExtensionTest, ExtensionManagementPolicyProvider) {
436 SupervisedUserService* supervised_user_service =
437 SupervisedUserServiceFactory::GetForProfile(profile_.get());
438 ASSERT_TRUE(profile_->IsSupervised());
440 // Check that a supervised user can install and uninstall a theme.
442 scoped_refptr<extensions::Extension> theme = MakeThemeExtension();
444 base::string16 error_1;
445 EXPECT_TRUE(supervised_user_service->UserMayLoad(theme.get(), &error_1));
446 EXPECT_TRUE(error_1.empty());
448 base::string16 error_2;
449 EXPECT_FALSE(
450 supervised_user_service->MustRemainInstalled(theme.get(), &error_2));
451 EXPECT_TRUE(error_2.empty());
454 // Now check a different kind of extension; the supervised user should not be
455 // able to load it.
457 scoped_refptr<extensions::Extension> extension = MakeExtension(false);
459 base::string16 error;
460 EXPECT_FALSE(supervised_user_service->UserMayLoad(extension.get(), &error));
461 EXPECT_FALSE(error.empty());
465 // Check that a custodian-installed extension may be loaded, but not
466 // uninstalled.
467 scoped_refptr<extensions::Extension> extension = MakeExtension(true);
469 base::string16 error_1;
470 EXPECT_TRUE(
471 supervised_user_service->UserMayLoad(extension.get(), &error_1));
472 EXPECT_TRUE(error_1.empty());
474 base::string16 error_2;
475 EXPECT_TRUE(
476 supervised_user_service->MustRemainInstalled(extension.get(),
477 &error_2));
478 EXPECT_FALSE(error_2.empty());
481 #ifndef NDEBUG
482 EXPECT_FALSE(supervised_user_service->GetDebugPolicyProviderName().empty());
483 #endif
486 TEST_F(SupervisedUserServiceExtensionTest, NoContentPacks) {
487 SupervisedUserService* supervised_user_service =
488 SupervisedUserServiceFactory::GetForProfile(profile_.get());
489 SupervisedUserURLFilter* url_filter =
490 supervised_user_service->GetURLFilterForUIThread();
492 // ASSERT_EQ instead of ASSERT_TRUE([...].empty()) so that the error
493 // message contains the size in case of failure.
494 ASSERT_EQ(0u, site_list_observer_.site_lists().size());
496 GURL url("http://youtube.com");
497 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
498 url_filter->GetFilteringBehaviorForURL(url));
501 TEST_F(SupervisedUserServiceExtensionTest, InstallContentPacks) {
502 SupervisedUserService* supervised_user_service =
503 SupervisedUserServiceFactory::GetForProfile(profile_.get());
504 SupervisedUserURLFilter* url_filter =
505 supervised_user_service->GetURLFilterForUIThread();
507 GURL example_url("http://example.com");
508 GURL moose_url("http://moose.org");
509 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
510 url_filter->GetFilteringBehaviorForURL(example_url));
512 profile_->GetPrefs()->SetInteger(
513 prefs::kDefaultSupervisedUserFilteringBehavior,
514 SupervisedUserURLFilter::BLOCK);
515 EXPECT_EQ(SupervisedUserURLFilter::BLOCK,
516 url_filter->GetFilteringBehaviorForURL(example_url));
518 profile_->GetPrefs()->SetInteger(
519 prefs::kDefaultSupervisedUserFilteringBehavior,
520 SupervisedUserURLFilter::WARN);
521 EXPECT_EQ(SupervisedUserURLFilter::WARN,
522 url_filter->GetFilteringBehaviorForURL(example_url));
524 // Load a whitelist.
525 base::FilePath test_data_dir;
526 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
527 SupervisedUserWhitelistService* whitelist_service =
528 supervised_user_service->GetWhitelistService();
529 base::FilePath whitelist_path =
530 test_data_dir.AppendASCII("whitelists/content_pack/site_list.json");
531 whitelist_service->LoadWhitelistForTesting("aaaa", whitelist_path);
532 site_list_observer_.Wait();
534 ASSERT_EQ(1u, site_list_observer_.site_lists().size());
535 ASSERT_EQ(3u, site_list_observer_.sites().size());
536 EXPECT_EQ(base::ASCIIToUTF16("YouTube"), site_list_observer_.sites()[0].name);
537 EXPECT_EQ(base::ASCIIToUTF16("Homestar Runner"),
538 site_list_observer_.sites()[1].name);
539 EXPECT_EQ(base::string16(), site_list_observer_.sites()[2].name);
541 url_filter_observer_.Wait();
542 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
543 url_filter->GetFilteringBehaviorForURL(example_url));
544 EXPECT_EQ(SupervisedUserURLFilter::WARN,
545 url_filter->GetFilteringBehaviorForURL(moose_url));
547 // Load a second whitelist.
548 whitelist_path =
549 test_data_dir.AppendASCII("whitelists/content_pack_2/site_list.json");
550 whitelist_service->LoadWhitelistForTesting("bbbb", whitelist_path);
551 site_list_observer_.Wait();
553 ASSERT_EQ(2u, site_list_observer_.site_lists().size());
554 ASSERT_EQ(4u, site_list_observer_.sites().size());
556 // The site lists might be returned in any order, so we put them into a set.
557 std::set<std::string> site_names;
558 for (const SupervisedUserSiteList::Site& site : site_list_observer_.sites())
559 site_names.insert(base::UTF16ToUTF8(site.name));
560 EXPECT_EQ(1u, site_names.count("YouTube"));
561 EXPECT_EQ(1u, site_names.count("Homestar Runner"));
562 EXPECT_EQ(1u, site_names.count(std::string()));
563 EXPECT_EQ(1u, site_names.count("Moose"));
565 url_filter_observer_.Wait();
566 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
567 url_filter->GetFilteringBehaviorForURL(example_url));
568 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
569 url_filter->GetFilteringBehaviorForURL(moose_url));
571 // Unload the first whitelist.
572 whitelist_service->UnloadWhitelist("aaaa");
573 site_list_observer_.Wait();
575 ASSERT_EQ(1u, site_list_observer_.site_lists().size());
576 ASSERT_EQ(1u, site_list_observer_.sites().size());
577 EXPECT_EQ(base::ASCIIToUTF16("Moose"), site_list_observer_.sites()[0].name);
579 url_filter_observer_.Wait();
580 EXPECT_EQ(SupervisedUserURLFilter::WARN,
581 url_filter->GetFilteringBehaviorForURL(example_url));
582 EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
583 url_filter->GetFilteringBehaviorForURL(moose_url));
585 #endif // defined(ENABLE_EXTENSIONS)