Fast user switcher: Distinguish supervised users from child accounts
[chromium-blink-merge.git] / chrome / browser / extensions / extension_special_storage_policy_unittest.cc
blobd62eb47d3e1b38d24ca0140888e11e5843c0be70
1 // Copyright (c) 2012 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/message_loop/message_loop.h"
6 #include "base/values.h"
7 #include "chrome/browser/content_settings/cookie_settings.h"
8 #include "chrome/browser/extensions/extension_special_storage_policy.h"
9 #include "chrome/test/base/testing_profile.h"
10 #include "components/content_settings/core/common/content_settings.h"
11 #include "components/content_settings/core/common/content_settings_types.h"
12 #include "content/public/test/test_browser_thread.h"
13 #include "extensions/common/extension.h"
14 #include "extensions/common/extension_set.h"
15 #include "extensions/common/manifest.h"
16 #include "extensions/common/manifest_constants.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using content::BrowserThread;
20 using extensions::Extension;
21 using extensions::ExtensionSet;
22 using extensions::Manifest;
23 using storage::SpecialStoragePolicy;
25 typedef SpecialStoragePolicy::StoragePolicy StoragePolicy;
27 namespace keys = extensions::manifest_keys;
29 class ExtensionSpecialStoragePolicyTest : public testing::Test {
30 protected:
31 class PolicyChangeObserver : public SpecialStoragePolicy::Observer {
32 public:
33 PolicyChangeObserver()
34 : expected_type_(NOTIFICATION_TYPE_NONE),
35 expected_change_flags_(0) {
38 void OnGranted(const GURL& origin, int change_flags) override {
39 EXPECT_EQ(expected_type_, NOTIFICATION_TYPE_GRANT);
40 EXPECT_EQ(expected_origin_, origin);
41 EXPECT_EQ(expected_change_flags_, change_flags);
42 expected_type_ = NOTIFICATION_TYPE_NONE;
45 void OnRevoked(const GURL& origin, int change_flags) override {
46 EXPECT_EQ(expected_type_, NOTIFICATION_TYPE_REVOKE);
47 EXPECT_EQ(expected_origin_, origin);
48 EXPECT_EQ(expected_change_flags_, change_flags);
49 expected_type_ = NOTIFICATION_TYPE_NONE;
52 void OnCleared() override {
53 EXPECT_EQ(expected_type_, NOTIFICATION_TYPE_CLEAR);
54 expected_type_ = NOTIFICATION_TYPE_NONE;
57 void ExpectGrant(const std::string& extension_id,
58 int change_flags) {
59 expected_type_ = NOTIFICATION_TYPE_GRANT;
60 expected_origin_ = Extension::GetBaseURLFromExtensionId(extension_id);
61 expected_change_flags_ = change_flags;
64 void ExpectRevoke(const std::string& extension_id,
65 int change_flags) {
66 expected_type_ = NOTIFICATION_TYPE_REVOKE;
67 expected_origin_ = Extension::GetBaseURLFromExtensionId(extension_id);
68 expected_change_flags_ = change_flags;
71 void ExpectClear() {
72 expected_type_ = NOTIFICATION_TYPE_CLEAR;
75 bool IsCompleted() {
76 return expected_type_ == NOTIFICATION_TYPE_NONE;
79 private:
80 enum {
81 NOTIFICATION_TYPE_NONE,
82 NOTIFICATION_TYPE_GRANT,
83 NOTIFICATION_TYPE_REVOKE,
84 NOTIFICATION_TYPE_CLEAR,
85 } expected_type_;
87 GURL expected_origin_;
88 int expected_change_flags_;
90 DISALLOW_COPY_AND_ASSIGN(PolicyChangeObserver);
93 void SetUp() override { policy_ = new ExtensionSpecialStoragePolicy(NULL); }
95 scoped_refptr<Extension> CreateProtectedApp() {
96 #if defined(OS_WIN)
97 base::FilePath path(FILE_PATH_LITERAL("c:\\foo"));
98 #elif defined(OS_POSIX)
99 base::FilePath path(FILE_PATH_LITERAL("/foo"));
100 #endif
101 base::DictionaryValue manifest;
102 manifest.SetString(keys::kName, "Protected");
103 manifest.SetString(keys::kVersion, "1");
104 manifest.SetString(keys::kLaunchWebURL, "http://explicit/protected/start");
105 base::ListValue* list = new base::ListValue();
106 list->Append(new base::StringValue("http://explicit/protected"));
107 list->Append(new base::StringValue("*://*.wildcards/protected"));
108 manifest.Set(keys::kWebURLs, list);
109 std::string error;
110 scoped_refptr<Extension> protected_app = Extension::Create(
111 path, Manifest::INVALID_LOCATION, manifest,
112 Extension::NO_FLAGS, &error);
113 EXPECT_TRUE(protected_app.get()) << error;
114 return protected_app;
117 scoped_refptr<Extension> CreateUnlimitedApp() {
118 #if defined(OS_WIN)
119 base::FilePath path(FILE_PATH_LITERAL("c:\\bar"));
120 #elif defined(OS_POSIX)
121 base::FilePath path(FILE_PATH_LITERAL("/bar"));
122 #endif
123 base::DictionaryValue manifest;
124 manifest.SetString(keys::kName, "Unlimited");
125 manifest.SetString(keys::kVersion, "1");
126 manifest.SetString(keys::kLaunchWebURL, "http://explicit/unlimited/start");
127 base::ListValue* list = new base::ListValue();
128 list->Append(new base::StringValue("unlimitedStorage"));
129 manifest.Set(keys::kPermissions, list);
130 list = new base::ListValue();
131 list->Append(new base::StringValue("http://explicit/unlimited"));
132 list->Append(new base::StringValue("*://*.wildcards/unlimited"));
133 manifest.Set(keys::kWebURLs, list);
134 std::string error;
135 scoped_refptr<Extension> unlimited_app = Extension::Create(
136 path, Manifest::INVALID_LOCATION, manifest,
137 Extension::NO_FLAGS, &error);
138 EXPECT_TRUE(unlimited_app.get()) << error;
139 return unlimited_app;
142 scoped_refptr<Extension> CreateRegularApp() {
143 #if defined(OS_WIN)
144 base::FilePath path(FILE_PATH_LITERAL("c:\\app"));
145 #elif defined(OS_POSIX)
146 base::FilePath path(FILE_PATH_LITERAL("/app"));
147 #endif
148 base::DictionaryValue manifest;
149 manifest.SetString(keys::kName, "App");
150 manifest.SetString(keys::kVersion, "1");
151 manifest.SetString(keys::kPlatformAppBackgroundPage, "background.html");
152 std::string error;
153 scoped_refptr<Extension> app = Extension::Create(
154 path, Manifest::INVALID_LOCATION, manifest,
155 Extension::NO_FLAGS, &error);
156 EXPECT_TRUE(app.get()) << error;
157 return app;
160 // Verifies that the set of extensions protecting |url| is *exactly* equal to
161 // |expected_extensions|. Pass in an empty set to verify that an origin is not
162 // protected.
163 void ExpectProtectedBy(const ExtensionSet& expected_extensions,
164 const GURL& url) {
165 const ExtensionSet* extensions = policy_->ExtensionsProtectingOrigin(url);
166 EXPECT_EQ(expected_extensions.size(), extensions->size());
167 for (ExtensionSet::const_iterator it = expected_extensions.begin();
168 it != expected_extensions.end(); ++it) {
169 EXPECT_TRUE(extensions->Contains((*it)->id()))
170 << "Origin " << url << "not protected by extension ID "
171 << (*it)->id();
175 scoped_refptr<ExtensionSpecialStoragePolicy> policy_;
178 TEST_F(ExtensionSpecialStoragePolicyTest, EmptyPolicy) {
179 const GURL kHttpUrl("http://foo");
180 const GURL kExtensionUrl("chrome-extension://bar");
181 scoped_refptr<Extension> app(CreateRegularApp());
183 EXPECT_FALSE(policy_->IsStorageUnlimited(kHttpUrl));
184 EXPECT_FALSE(policy_->IsStorageUnlimited(kHttpUrl)); // test cached result
185 EXPECT_FALSE(policy_->IsStorageUnlimited(kExtensionUrl));
186 EXPECT_FALSE(policy_->IsStorageUnlimited(app->url()));
187 ExtensionSet empty_set;
188 ExpectProtectedBy(empty_set, kHttpUrl);
190 // This one is just based on the scheme.
191 EXPECT_TRUE(policy_->IsStorageProtected(kExtensionUrl));
192 EXPECT_TRUE(policy_->IsStorageProtected(app->url()));
195 TEST_F(ExtensionSpecialStoragePolicyTest, AppWithProtectedStorage) {
196 scoped_refptr<Extension> extension(CreateProtectedApp());
197 policy_->GrantRightsForExtension(extension.get(), NULL);
198 ExtensionSet protecting_extensions;
199 protecting_extensions.Insert(extension);
200 ExtensionSet empty_set;
202 EXPECT_FALSE(policy_->IsStorageUnlimited(extension->url()));
203 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://explicit/")));
204 ExpectProtectedBy(protecting_extensions, GURL("http://explicit/"));
205 ExpectProtectedBy(protecting_extensions, GURL("http://explicit:6000/"));
206 ExpectProtectedBy(protecting_extensions, GURL("http://foo.wildcards/"));
207 ExpectProtectedBy(protecting_extensions, GURL("https://bar.wildcards/"));
208 ExpectProtectedBy(empty_set, GURL("http://not_listed/"));
210 policy_->RevokeRightsForExtension(extension.get());
211 ExpectProtectedBy(empty_set, GURL("http://explicit/"));
212 ExpectProtectedBy(empty_set, GURL("http://foo.wildcards/"));
213 ExpectProtectedBy(empty_set, GURL("https://bar.wildcards/"));
216 TEST_F(ExtensionSpecialStoragePolicyTest, AppWithUnlimitedStorage) {
217 scoped_refptr<Extension> extension(CreateUnlimitedApp());
218 policy_->GrantRightsForExtension(extension.get(), NULL);
219 ExtensionSet protecting_extensions;
220 protecting_extensions.Insert(extension);
221 ExtensionSet empty_set;
223 ExpectProtectedBy(protecting_extensions, GURL("http://explicit/"));
224 ExpectProtectedBy(protecting_extensions, GURL("http://explicit:6000/"));
225 ExpectProtectedBy(protecting_extensions, GURL("https://foo.wildcards/"));
226 ExpectProtectedBy(protecting_extensions, GURL("https://foo.wildcards/"));
227 ExpectProtectedBy(protecting_extensions, GURL("http://bar.wildcards/"));
228 ExpectProtectedBy(empty_set, GURL("http://not_listed/"));
229 EXPECT_TRUE(policy_->IsStorageUnlimited(extension->url()));
230 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("http://explicit/")));
231 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("http://explicit:6000/")));
232 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("https://foo.wildcards/")));
233 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("https://bar.wildcards/")));
234 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://not_listed/")));
236 policy_->RevokeRightsForExtension(extension.get());
237 ExpectProtectedBy(empty_set, GURL("http://explicit/"));
238 ExpectProtectedBy(empty_set, GURL("https://foo.wildcards/"));
239 ExpectProtectedBy(empty_set, GURL("https://foo.wildcards/"));
240 ExpectProtectedBy(empty_set, GURL("http://bar.wildcards/"));
241 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://explicit/")));
242 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("https://foo.wildcards/")));
243 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("https://bar.wildcards/")));
246 TEST_F(ExtensionSpecialStoragePolicyTest, CanQueryDiskSize) {
247 const GURL kHttpUrl("http://foo");
248 const GURL kExtensionUrl("chrome-extension://bar");
249 scoped_refptr<Extension> regular_app(CreateRegularApp());
250 scoped_refptr<Extension> protected_app(CreateProtectedApp());
251 scoped_refptr<Extension> unlimited_app(CreateUnlimitedApp());
252 policy_->GrantRightsForExtension(regular_app.get(), NULL);
253 policy_->GrantRightsForExtension(protected_app.get(), NULL);
254 policy_->GrantRightsForExtension(unlimited_app.get(), NULL);
256 EXPECT_FALSE(policy_->CanQueryDiskSize(kHttpUrl));
257 EXPECT_FALSE(policy_->CanQueryDiskSize(kExtensionUrl));
258 EXPECT_TRUE(policy_->CanQueryDiskSize(regular_app->url()));
259 EXPECT_TRUE(policy_->CanQueryDiskSize(protected_app->url()));
260 EXPECT_TRUE(policy_->CanQueryDiskSize(unlimited_app->url()));
263 TEST_F(ExtensionSpecialStoragePolicyTest, HasIsolatedStorage) {
264 const GURL kHttpUrl("http://foo");
265 const GURL kExtensionUrl("chrome-extension://bar");
266 scoped_refptr<Extension> app(CreateRegularApp());
267 policy_->GrantRightsForExtension(app.get(), NULL);
269 EXPECT_FALSE(policy_->HasIsolatedStorage(kHttpUrl));
270 EXPECT_FALSE(policy_->HasIsolatedStorage(kExtensionUrl));
271 EXPECT_TRUE(policy_->HasIsolatedStorage(app->url()));
274 TEST_F(ExtensionSpecialStoragePolicyTest, OverlappingApps) {
275 scoped_refptr<Extension> protected_app(CreateProtectedApp());
276 scoped_refptr<Extension> unlimited_app(CreateUnlimitedApp());
277 policy_->GrantRightsForExtension(protected_app.get(), NULL);
278 policy_->GrantRightsForExtension(unlimited_app.get(), NULL);
279 ExtensionSet protecting_extensions;
280 ExtensionSet empty_set;
281 protecting_extensions.Insert(protected_app);
282 protecting_extensions.Insert(unlimited_app);
284 ExpectProtectedBy(protecting_extensions, GURL("http://explicit/"));
285 ExpectProtectedBy(protecting_extensions, GURL("http://explicit:6000/"));
286 ExpectProtectedBy(protecting_extensions, GURL("https://foo.wildcards/"));
287 ExpectProtectedBy(protecting_extensions, GURL("https://foo.wildcards/"));
288 ExpectProtectedBy(protecting_extensions, GURL("http://bar.wildcards/"));
289 ExpectProtectedBy(empty_set, GURL("http://not_listed/"));
290 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("http://explicit/")));
291 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("http://explicit:6000/")));
292 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("https://foo.wildcards/")));
293 EXPECT_TRUE(policy_->IsStorageUnlimited(GURL("https://bar.wildcards/")));
294 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://not_listed/")));
296 policy_->RevokeRightsForExtension(unlimited_app.get());
297 protecting_extensions.Remove(unlimited_app->id());
298 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("http://explicit/")));
299 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("https://foo.wildcards/")));
300 EXPECT_FALSE(policy_->IsStorageUnlimited(GURL("https://bar.wildcards/")));
301 ExpectProtectedBy(protecting_extensions, GURL("http://explicit/"));
302 ExpectProtectedBy(protecting_extensions, GURL("http://foo.wildcards/"));
303 ExpectProtectedBy(protecting_extensions, GURL("https://bar.wildcards/"));
305 policy_->RevokeRightsForExtension(protected_app.get());
306 ExpectProtectedBy(empty_set, GURL("http://explicit/"));
307 ExpectProtectedBy(empty_set, GURL("http://foo.wildcards/"));
308 ExpectProtectedBy(empty_set, GURL("https://bar.wildcards/"));
311 TEST_F(ExtensionSpecialStoragePolicyTest, HasSessionOnlyOrigins) {
312 base::MessageLoop message_loop;
313 content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
315 TestingProfile profile;
316 CookieSettings* cookie_settings =
317 CookieSettings::Factory::GetForProfile(&profile).get();
318 policy_ = new ExtensionSpecialStoragePolicy(cookie_settings);
320 EXPECT_FALSE(policy_->HasSessionOnlyOrigins());
322 // The default setting can be session-only.
323 cookie_settings->SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
324 EXPECT_TRUE(policy_->HasSessionOnlyOrigins());
326 cookie_settings->SetDefaultCookieSetting(CONTENT_SETTING_ALLOW);
327 EXPECT_FALSE(policy_->HasSessionOnlyOrigins());
329 // Or the session-onlyness can affect individual origins.
330 ContentSettingsPattern pattern =
331 ContentSettingsPattern::FromString("pattern.com");
333 cookie_settings->SetCookieSetting(pattern,
334 ContentSettingsPattern::Wildcard(),
335 CONTENT_SETTING_SESSION_ONLY);
337 EXPECT_TRUE(policy_->HasSessionOnlyOrigins());
339 // Clearing an origin-specific rule.
340 cookie_settings->ResetCookieSetting(pattern,
341 ContentSettingsPattern::Wildcard());
343 EXPECT_FALSE(policy_->HasSessionOnlyOrigins());
346 TEST_F(ExtensionSpecialStoragePolicyTest, NotificationTest) {
347 base::MessageLoop message_loop;
348 content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
349 content::TestBrowserThread io_thread(BrowserThread::IO, &message_loop);
351 PolicyChangeObserver observer;
352 policy_->AddObserver(&observer);
354 scoped_refptr<Extension> apps[] = {
355 CreateProtectedApp(),
356 CreateUnlimitedApp(),
359 int change_flags[] = {
360 SpecialStoragePolicy::STORAGE_PROTECTED,
362 SpecialStoragePolicy::STORAGE_PROTECTED |
363 SpecialStoragePolicy::STORAGE_UNLIMITED,
366 ASSERT_EQ(arraysize(apps), arraysize(change_flags));
367 for (size_t i = 0; i < arraysize(apps); ++i) {
368 SCOPED_TRACE(testing::Message() << "i: " << i);
369 observer.ExpectGrant(apps[i]->id(), change_flags[i]);
370 policy_->GrantRightsForExtension(apps[i].get(), NULL);
371 message_loop.RunUntilIdle();
372 EXPECT_TRUE(observer.IsCompleted());
375 for (size_t i = 0; i < arraysize(apps); ++i) {
376 SCOPED_TRACE(testing::Message() << "i: " << i);
377 policy_->GrantRightsForExtension(apps[i].get(), NULL);
378 message_loop.RunUntilIdle();
379 EXPECT_TRUE(observer.IsCompleted());
382 for (size_t i = 0; i < arraysize(apps); ++i) {
383 SCOPED_TRACE(testing::Message() << "i: " << i);
384 observer.ExpectRevoke(apps[i]->id(), change_flags[i]);
385 policy_->RevokeRightsForExtension(apps[i].get());
386 message_loop.RunUntilIdle();
387 EXPECT_TRUE(observer.IsCompleted());
390 for (size_t i = 0; i < arraysize(apps); ++i) {
391 SCOPED_TRACE(testing::Message() << "i: " << i);
392 policy_->RevokeRightsForExtension(apps[i].get());
393 message_loop.RunUntilIdle();
394 EXPECT_TRUE(observer.IsCompleted());
397 observer.ExpectClear();
398 policy_->RevokeRightsForAllExtensions();
399 message_loop.RunUntilIdle();
400 EXPECT_TRUE(observer.IsCompleted());
402 policy_->RemoveObserver(&observer);