Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_special_storage_policy_unittest.cc
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.
4
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"
18
19 using content::BrowserThread;
20 using extensions::Extension;
21 using extensions::ExtensionSet;
22 using extensions::Manifest;
23 using storage::SpecialStoragePolicy;
24
25 typedef SpecialStoragePolicy::StoragePolicy StoragePolicy;
26
27 namespace keys = extensions::manifest_keys;
28
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) {
36     }
37
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;
43     }
44
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;
50     }
51
52     void OnCleared() override {
53       EXPECT_EQ(expected_type_, NOTIFICATION_TYPE_CLEAR);
54       expected_type_ = NOTIFICATION_TYPE_NONE;
55     }
56
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;
62     }
63
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;
69     }
70
71     void ExpectClear() {
72       expected_type_ = NOTIFICATION_TYPE_CLEAR;
73     }
74
75     bool IsCompleted() {
76       return expected_type_ == NOTIFICATION_TYPE_NONE;
77     }
78
79    private:
80     enum {
81       NOTIFICATION_TYPE_NONE,
82       NOTIFICATION_TYPE_GRANT,
83       NOTIFICATION_TYPE_REVOKE,
84       NOTIFICATION_TYPE_CLEAR,
85     } expected_type_;
86
87     GURL expected_origin_;
88     int expected_change_flags_;
89
90     DISALLOW_COPY_AND_ASSIGN(PolicyChangeObserver);
91   };
92
93   void SetUp() override { policy_ = new ExtensionSpecialStoragePolicy(NULL); }
94
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;
115   }
116
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;
140   }
141
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;
158   }
159
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();
172     }
173   }
174
175   scoped_refptr<ExtensionSpecialStoragePolicy> policy_;
176 };
177
178 TEST_F(ExtensionSpecialStoragePolicyTest, EmptyPolicy) {
179   const GURL kHttpUrl("http://foo");
180   const GURL kExtensionUrl("chrome-extension://bar");
181   scoped_refptr<Extension> app(CreateRegularApp());
182
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);
189
190   // This one is just based on the scheme.
191   EXPECT_TRUE(policy_->IsStorageProtected(kExtensionUrl));
192   EXPECT_TRUE(policy_->IsStorageProtected(app->url()));
193 }
194
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;
201
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/"));
209
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/"));
214 }
215
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;
222
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/")));
235
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/")));
244 }
245
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);
255
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()));
261 }
262
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);
268
269   EXPECT_FALSE(policy_->HasIsolatedStorage(kHttpUrl));
270   EXPECT_FALSE(policy_->HasIsolatedStorage(kExtensionUrl));
271   EXPECT_TRUE(policy_->HasIsolatedStorage(app->url()));
272 }
273
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);
283
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/")));
295
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/"));
304
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/"));
309 }
310
311 TEST_F(ExtensionSpecialStoragePolicyTest, HasSessionOnlyOrigins) {
312   base::MessageLoop message_loop;
313   content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
314
315   TestingProfile profile;
316   CookieSettings* cookie_settings =
317       CookieSettings::Factory::GetForProfile(&profile).get();
318   policy_ = new ExtensionSpecialStoragePolicy(cookie_settings);
319
320   EXPECT_FALSE(policy_->HasSessionOnlyOrigins());
321
322   // The default setting can be session-only.
323   cookie_settings->SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
324   EXPECT_TRUE(policy_->HasSessionOnlyOrigins());
325
326   cookie_settings->SetDefaultCookieSetting(CONTENT_SETTING_ALLOW);
327   EXPECT_FALSE(policy_->HasSessionOnlyOrigins());
328
329   // Or the session-onlyness can affect individual origins.
330   ContentSettingsPattern pattern =
331       ContentSettingsPattern::FromString("pattern.com");
332
333   cookie_settings->SetCookieSetting(pattern,
334                                     ContentSettingsPattern::Wildcard(),
335                                     CONTENT_SETTING_SESSION_ONLY);
336
337   EXPECT_TRUE(policy_->HasSessionOnlyOrigins());
338
339   // Clearing an origin-specific rule.
340   cookie_settings->ResetCookieSetting(pattern,
341                                       ContentSettingsPattern::Wildcard());
342
343   EXPECT_FALSE(policy_->HasSessionOnlyOrigins());
344 }
345
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);
350
351   PolicyChangeObserver observer;
352   policy_->AddObserver(&observer);
353
354   scoped_refptr<Extension> apps[] = {
355     CreateProtectedApp(),
356     CreateUnlimitedApp(),
357   };
358
359   int change_flags[] = {
360     SpecialStoragePolicy::STORAGE_PROTECTED,
361
362     SpecialStoragePolicy::STORAGE_PROTECTED |
363     SpecialStoragePolicy::STORAGE_UNLIMITED,
364   };
365
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());
373   }
374
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());
380   }
381
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());
388   }
389
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());
395   }
396
397   observer.ExpectClear();
398   policy_->RevokeRightsForAllExtensions();
399   message_loop.RunUntilIdle();
400   EXPECT_TRUE(observer.IsCompleted());
401
402   policy_->RemoveObserver(&observer);
403 }