Home | History | Annotate | Download | only in managed_mode
      1 // Copyright (c) 2013 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 "base/path_service.h"
      6 #include "base/prefs/pref_service.h"
      7 #include "base/prefs/scoped_user_pref_update.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/chrome_notification_types.h"
     10 #include "chrome/browser/extensions/extension_service_unittest.h"
     11 #include "chrome/browser/extensions/unpacked_installer.h"
     12 #include "chrome/browser/managed_mode/custodian_profile_downloader_service.h"
     13 #include "chrome/browser/managed_mode/custodian_profile_downloader_service_factory.h"
     14 #include "chrome/browser/managed_mode/managed_user_service.h"
     15 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
     16 #include "chrome/browser/profiles/profile.h"
     17 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
     18 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     19 #include "chrome/browser/ui/browser_list.h"
     20 #include "chrome/common/chrome_paths.h"
     21 #include "chrome/common/extensions/features/feature_channel.h"
     22 #include "chrome/common/pref_names.h"
     23 #include "chrome/test/base/testing_profile.h"
     24 #include "content/public/test/test_browser_thread_bundle.h"
     25 #include "content/public/test/test_utils.h"
     26 #include "extensions/common/extension.h"
     27 #include "extensions/common/extension_builder.h"
     28 #include "extensions/common/manifest_constants.h"
     29 #include "testing/gtest/include/gtest/gtest.h"
     30 
     31 using content::MessageLoopRunner;
     32 
     33 namespace {
     34 
     35 void OnProfileDownloadedFail(const base::string16& full_name) {
     36   ASSERT_TRUE(false) << "Profile download should not have succeeded.";
     37 }
     38 
     39 class ManagedModeURLFilterObserver : public ManagedModeURLFilter::Observer {
     40  public:
     41   explicit ManagedModeURLFilterObserver(ManagedModeURLFilter* url_filter)
     42       : url_filter_(url_filter) {
     43     Reset();
     44     url_filter_->AddObserver(this);
     45   }
     46 
     47   ~ManagedModeURLFilterObserver() {
     48     url_filter_->RemoveObserver(this);
     49   }
     50 
     51   void Wait() {
     52     message_loop_runner_->Run();
     53     Reset();
     54   }
     55 
     56   // ManagedModeURLFilter::Observer
     57   virtual void OnSiteListUpdated() OVERRIDE {
     58     message_loop_runner_->Quit();
     59   }
     60 
     61  private:
     62   void Reset() {
     63     message_loop_runner_ = new MessageLoopRunner;
     64   }
     65 
     66   ManagedModeURLFilter* url_filter_;
     67   scoped_refptr<MessageLoopRunner> message_loop_runner_;
     68 };
     69 
     70 class ManagedUserServiceTest : public ::testing::Test {
     71  public:
     72   ManagedUserServiceTest() {}
     73 
     74   virtual void SetUp() OVERRIDE {
     75     TestingProfile::Builder builder;
     76     builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
     77                               FakeProfileOAuth2TokenService::Build);
     78     profile_ = builder.Build();
     79     managed_user_service_ =
     80         ManagedUserServiceFactory::GetForProfile(profile_.get());
     81   }
     82 
     83   virtual void TearDown() OVERRIDE {
     84     profile_.reset();
     85   }
     86 
     87   virtual ~ManagedUserServiceTest() {}
     88 
     89  protected:
     90   content::TestBrowserThreadBundle thread_bundle_;
     91   scoped_ptr<TestingProfile> profile_;
     92   ManagedUserService* managed_user_service_;
     93 };
     94 
     95 }  // namespace
     96 
     97 TEST_F(ManagedUserServiceTest, GetManualExceptionsForHost) {
     98   GURL kExampleFooURL("http://www.example.com/foo");
     99   GURL kExampleBarURL("http://www.example.com/bar");
    100   GURL kExampleFooNoWWWURL("http://example.com/foo");
    101   GURL kBlurpURL("http://blurp.net/bla");
    102   GURL kMooseURL("http://moose.org/baz");
    103   {
    104     DictionaryPrefUpdate update(profile_->GetPrefs(),
    105                                 prefs::kManagedModeManualURLs);
    106     base::DictionaryValue* dict = update.Get();
    107     dict->SetBooleanWithoutPathExpansion(kExampleFooURL.spec(), true);
    108     dict->SetBooleanWithoutPathExpansion(kExampleBarURL.spec(), false);
    109     dict->SetBooleanWithoutPathExpansion(kExampleFooNoWWWURL.spec(), true);
    110     dict->SetBooleanWithoutPathExpansion(kBlurpURL.spec(), true);
    111   }
    112 
    113   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
    114             managed_user_service_->GetManualBehaviorForURL(kExampleFooURL));
    115   EXPECT_EQ(ManagedUserService::MANUAL_BLOCK,
    116             managed_user_service_->GetManualBehaviorForURL(kExampleBarURL));
    117   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
    118             managed_user_service_->GetManualBehaviorForURL(
    119                 kExampleFooNoWWWURL));
    120   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
    121             managed_user_service_->GetManualBehaviorForURL(kBlurpURL));
    122   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
    123             managed_user_service_->GetManualBehaviorForURL(kMooseURL));
    124   std::vector<GURL> exceptions;
    125   managed_user_service_->GetManualExceptionsForHost("www.example.com",
    126                                                     &exceptions);
    127   ASSERT_EQ(2u, exceptions.size());
    128   EXPECT_EQ(kExampleBarURL, exceptions[0]);
    129   EXPECT_EQ(kExampleFooURL, exceptions[1]);
    130 
    131   {
    132     DictionaryPrefUpdate update(profile_->GetPrefs(),
    133                                 prefs::kManagedModeManualURLs);
    134     base::DictionaryValue* dict = update.Get();
    135     for (std::vector<GURL>::iterator it = exceptions.begin();
    136          it != exceptions.end(); ++it) {
    137       dict->RemoveWithoutPathExpansion(it->spec(), NULL);
    138     }
    139   }
    140 
    141   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
    142             managed_user_service_->GetManualBehaviorForURL(kExampleFooURL));
    143   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
    144             managed_user_service_->GetManualBehaviorForURL(kExampleBarURL));
    145   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
    146             managed_user_service_->GetManualBehaviorForURL(
    147                 kExampleFooNoWWWURL));
    148   EXPECT_EQ(ManagedUserService::MANUAL_ALLOW,
    149             managed_user_service_->GetManualBehaviorForURL(kBlurpURL));
    150   EXPECT_EQ(ManagedUserService::MANUAL_NONE,
    151             managed_user_service_->GetManualBehaviorForURL(kMooseURL));
    152 }
    153 
    154 // Ensure that the CustodianProfileDownloaderService shuts down cleanly. If no
    155 // DCHECK is hit when the service is destroyed, this test passed.
    156 TEST_F(ManagedUserServiceTest, ShutDownCustodianProfileDownloader) {
    157   CustodianProfileDownloaderService* downloader_service =
    158       CustodianProfileDownloaderServiceFactory::GetForProfile(profile_.get());
    159 
    160   // Emulate being logged in, then start to download a profile so a
    161   // ProfileDownloader gets created.
    162   profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, "Logged In");
    163   downloader_service->DownloadProfile(base::Bind(&OnProfileDownloadedFail));
    164 }
    165 
    166 #if !defined(OS_ANDROID)
    167 class ManagedUserServiceExtensionTestBase : public ExtensionServiceTestBase {
    168  public:
    169   explicit ManagedUserServiceExtensionTestBase(bool is_managed)
    170       : is_managed_(is_managed),
    171         channel_(chrome::VersionInfo::CHANNEL_DEV) {}
    172   virtual ~ManagedUserServiceExtensionTestBase() {}
    173 
    174   virtual void SetUp() OVERRIDE {
    175     ExtensionServiceTestBase::SetUp();
    176     ExtensionServiceTestBase::ExtensionServiceInitParams params =
    177         CreateDefaultInitParams();
    178     params.profile_is_managed = is_managed_;
    179     InitializeExtensionService(params);
    180     ManagedUserServiceFactory::GetForProfile(profile_.get())->Init();
    181   }
    182 
    183  protected:
    184   ScopedVector<ManagedModeSiteList> GetActiveSiteLists(
    185       ManagedUserService* managed_user_service) {
    186     return managed_user_service->GetActiveSiteLists();
    187   }
    188 
    189   scoped_refptr<extensions::Extension> MakeThemeExtension() {
    190     scoped_ptr<DictionaryValue> source(new DictionaryValue());
    191     source->SetString(extensions::manifest_keys::kName, "Theme");
    192     source->Set(extensions::manifest_keys::kTheme, new DictionaryValue());
    193     source->SetString(extensions::manifest_keys::kVersion, "1.0");
    194     extensions::ExtensionBuilder builder;
    195     scoped_refptr<extensions::Extension> extension =
    196         builder.SetManifest(source.Pass()).Build();
    197     return extension;
    198   }
    199 
    200   scoped_refptr<extensions::Extension> MakeExtension() {
    201     scoped_ptr<DictionaryValue> manifest = extensions::DictionaryBuilder()
    202       .Set(extensions::manifest_keys::kName, "Extension")
    203       .Set(extensions::manifest_keys::kVersion, "1.0")
    204       .Build();
    205     extensions::ExtensionBuilder builder;
    206     scoped_refptr<extensions::Extension> extension =
    207         builder.SetManifest(manifest.Pass()).Build();
    208     return extension;
    209   }
    210 
    211   bool is_managed_;
    212   extensions::ScopedCurrentChannel channel_;
    213 };
    214 
    215 class ManagedUserServiceExtensionTestUnmanaged
    216     : public ManagedUserServiceExtensionTestBase {
    217  public:
    218   ManagedUserServiceExtensionTestUnmanaged()
    219       : ManagedUserServiceExtensionTestBase(false) {}
    220 };
    221 
    222 class ManagedUserServiceExtensionTest
    223     : public ManagedUserServiceExtensionTestBase {
    224  public:
    225   ManagedUserServiceExtensionTest()
    226       : ManagedUserServiceExtensionTestBase(true) {}
    227 };
    228 
    229 TEST_F(ManagedUserServiceExtensionTestUnmanaged,
    230        ExtensionManagementPolicyProvider) {
    231   ManagedUserService* managed_user_service =
    232       ManagedUserServiceFactory::GetForProfile(profile_.get());
    233   EXPECT_FALSE(profile_->IsManaged());
    234 
    235   scoped_refptr<extensions::Extension> extension = MakeExtension();
    236   base::string16 error_1;
    237   EXPECT_TRUE(managed_user_service->UserMayLoad(extension.get(), &error_1));
    238   EXPECT_EQ(base::string16(), error_1);
    239 
    240   base::string16 error_2;
    241   EXPECT_TRUE(
    242       managed_user_service->UserMayModifySettings(extension.get(), &error_2));
    243   EXPECT_EQ(base::string16(), error_2);
    244 }
    245 
    246 TEST_F(ManagedUserServiceExtensionTest, ExtensionManagementPolicyProvider) {
    247   ManagedUserService* managed_user_service =
    248       ManagedUserServiceFactory::GetForProfile(profile_.get());
    249   ManagedModeURLFilterObserver observer(
    250       managed_user_service->GetURLFilterForUIThread());
    251   ASSERT_TRUE(profile_->IsManaged());
    252   // Wait for the initial update to finish (otherwise we'll get leaks).
    253   observer.Wait();
    254 
    255   // Check that a supervised user can install a theme.
    256   scoped_refptr<extensions::Extension> theme = MakeThemeExtension();
    257   base::string16 error_1;
    258   EXPECT_TRUE(managed_user_service->UserMayLoad(theme.get(), &error_1));
    259   EXPECT_TRUE(error_1.empty());
    260   EXPECT_TRUE(
    261       managed_user_service->UserMayModifySettings(theme.get(), &error_1));
    262   EXPECT_TRUE(error_1.empty());
    263 
    264   // Now check a different kind of extension.
    265   scoped_refptr<extensions::Extension> extension = MakeExtension();
    266   EXPECT_FALSE(managed_user_service->UserMayLoad(extension.get(), &error_1));
    267   EXPECT_FALSE(error_1.empty());
    268 
    269   base::string16 error_2;
    270   EXPECT_FALSE(
    271       managed_user_service->UserMayModifySettings(extension.get(), &error_2));
    272   EXPECT_FALSE(error_2.empty());
    273 
    274 #ifndef NDEBUG
    275   EXPECT_FALSE(managed_user_service->GetDebugPolicyProviderName().empty());
    276 #endif
    277 }
    278 
    279 TEST_F(ManagedUserServiceExtensionTest, NoContentPacks) {
    280   ManagedUserService* managed_user_service =
    281       ManagedUserServiceFactory::GetForProfile(profile_.get());
    282   ManagedModeURLFilter* url_filter =
    283       managed_user_service->GetURLFilterForUIThread();
    284 
    285   GURL url("http://youtube.com");
    286   ScopedVector<ManagedModeSiteList> site_lists =
    287       GetActiveSiteLists(managed_user_service);
    288   ASSERT_EQ(0u, site_lists.size());
    289   EXPECT_EQ(ManagedModeURLFilter::ALLOW,
    290             url_filter->GetFilteringBehaviorForURL(url));
    291 }
    292 
    293 TEST_F(ManagedUserServiceExtensionTest, InstallContentPacks) {
    294   ManagedUserService* managed_user_service =
    295       ManagedUserServiceFactory::GetForProfile(profile_.get());
    296   ManagedModeURLFilter* url_filter =
    297       managed_user_service->GetURLFilterForUIThread();
    298   ManagedModeURLFilterObserver observer(url_filter);
    299   observer.Wait();
    300 
    301   GURL example_url("http://example.com");
    302   GURL moose_url("http://moose.org");
    303   EXPECT_EQ(ManagedModeURLFilter::ALLOW,
    304             url_filter->GetFilteringBehaviorForURL(example_url));
    305 
    306   profile_->GetPrefs()->SetInteger(prefs::kDefaultManagedModeFilteringBehavior,
    307                                    ManagedModeURLFilter::BLOCK);
    308   EXPECT_EQ(ManagedModeURLFilter::BLOCK,
    309             url_filter->GetFilteringBehaviorForURL(example_url));
    310 
    311   profile_->GetPrefs()->SetInteger(prefs::kDefaultManagedModeFilteringBehavior,
    312                                    ManagedModeURLFilter::WARN);
    313   EXPECT_EQ(ManagedModeURLFilter::WARN,
    314             url_filter->GetFilteringBehaviorForURL(example_url));
    315 
    316   managed_user_service->set_elevated_for_testing(true);
    317 
    318   // Load a content pack.
    319   scoped_refptr<extensions::UnpackedInstaller> installer(
    320       extensions::UnpackedInstaller::Create(service_));
    321   installer->set_prompt_for_plugins(false);
    322   base::FilePath test_data_dir;
    323   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
    324   base::FilePath extension_path =
    325       test_data_dir.AppendASCII("extensions/managed_mode/content_pack");
    326   content::WindowedNotificationObserver extension_load_observer(
    327       chrome::NOTIFICATION_EXTENSION_LOADED,
    328       content::Source<Profile>(profile_.get()));
    329   installer->Load(extension_path);
    330   extension_load_observer.Wait();
    331   observer.Wait();
    332   content::Details<extensions::Extension> details =
    333       extension_load_observer.details();
    334   scoped_refptr<extensions::Extension> extension =
    335       make_scoped_refptr(details.ptr());
    336   ASSERT_TRUE(extension.get());
    337 
    338   ScopedVector<ManagedModeSiteList> site_lists =
    339       GetActiveSiteLists(managed_user_service);
    340   ASSERT_EQ(1u, site_lists.size());
    341   std::vector<ManagedModeSiteList::Site> sites;
    342   site_lists[0]->GetSites(&sites);
    343   ASSERT_EQ(3u, sites.size());
    344   EXPECT_EQ(ASCIIToUTF16("YouTube"), sites[0].name);
    345   EXPECT_EQ(ASCIIToUTF16("Homestar Runner"), sites[1].name);
    346   EXPECT_EQ(base::string16(), sites[2].name);
    347 
    348   EXPECT_EQ(ManagedModeURLFilter::ALLOW,
    349             url_filter->GetFilteringBehaviorForURL(example_url));
    350   EXPECT_EQ(ManagedModeURLFilter::WARN,
    351             url_filter->GetFilteringBehaviorForURL(moose_url));
    352 
    353   // Load a second content pack.
    354   installer = extensions::UnpackedInstaller::Create(service_);
    355   extension_path =
    356       test_data_dir.AppendASCII("extensions/managed_mode/content_pack_2");
    357   installer->Load(extension_path);
    358   observer.Wait();
    359 
    360   site_lists = GetActiveSiteLists(managed_user_service);
    361   ASSERT_EQ(2u, site_lists.size());
    362   sites.clear();
    363   site_lists[0]->GetSites(&sites);
    364   site_lists[1]->GetSites(&sites);
    365   ASSERT_EQ(4u, sites.size());
    366   // The site lists might be returned in any order, so we put them into a set.
    367   std::set<std::string> site_names;
    368   for (std::vector<ManagedModeSiteList::Site>::const_iterator it =
    369       sites.begin(); it != sites.end(); ++it) {
    370     site_names.insert(UTF16ToUTF8(it->name));
    371   }
    372   EXPECT_TRUE(site_names.count("YouTube") == 1u);
    373   EXPECT_TRUE(site_names.count("Homestar Runner") == 1u);
    374   EXPECT_TRUE(site_names.count(std::string()) == 1u);
    375   EXPECT_TRUE(site_names.count("Moose") == 1u);
    376 
    377   EXPECT_EQ(ManagedModeURLFilter::ALLOW,
    378             url_filter->GetFilteringBehaviorForURL(example_url));
    379   EXPECT_EQ(ManagedModeURLFilter::ALLOW,
    380             url_filter->GetFilteringBehaviorForURL(moose_url));
    381 
    382   // Disable the first content pack.
    383   service_->DisableExtension(extension->id(),
    384                              extensions::Extension::DISABLE_USER_ACTION);
    385   observer.Wait();
    386 
    387   site_lists = GetActiveSiteLists(managed_user_service);
    388   ASSERT_EQ(1u, site_lists.size());
    389   sites.clear();
    390   site_lists[0]->GetSites(&sites);
    391   ASSERT_EQ(1u, sites.size());
    392   EXPECT_EQ(ASCIIToUTF16("Moose"), sites[0].name);
    393 
    394   EXPECT_EQ(ManagedModeURLFilter::WARN,
    395             url_filter->GetFilteringBehaviorForURL(example_url));
    396   EXPECT_EQ(ManagedModeURLFilter::ALLOW,
    397             url_filter->GetFilteringBehaviorForURL(moose_url));
    398 }
    399 #endif  // !defined(OS_ANDROID)
    400