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