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 |