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 "chrome/browser/extensions/extension_special_storage_policy.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/content_settings/cookie_settings.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/common/content_settings.h"
15 #include "chrome/common/content_settings_types.h"
16 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
17 #include "chrome/common/url_constants.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/common/url_constants.h"
20 #include "extensions/common/constants.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_set.h"
24 using content::BrowserThread
;
25 using extensions::APIPermission
;
26 using extensions::Extension
;
27 using quota::SpecialStoragePolicy
;
29 ExtensionSpecialStoragePolicy::ExtensionSpecialStoragePolicy(
30 CookieSettings
* cookie_settings
)
31 : cookie_settings_(cookie_settings
) {}
33 ExtensionSpecialStoragePolicy::~ExtensionSpecialStoragePolicy() {}
35 bool ExtensionSpecialStoragePolicy::IsStorageProtected(const GURL
& origin
) {
36 if (origin
.SchemeIs(extensions::kExtensionScheme
))
38 base::AutoLock
locker(lock_
);
39 return protected_apps_
.Contains(origin
);
42 bool ExtensionSpecialStoragePolicy::IsStorageUnlimited(const GURL
& origin
) {
43 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUnlimitedStorage
))
46 if (origin
.SchemeIs(chrome::kChromeDevToolsScheme
) &&
47 origin
.host() == chrome::kChromeUIDevToolsHost
)
50 base::AutoLock
locker(lock_
);
51 return unlimited_extensions_
.Contains(origin
);
54 bool ExtensionSpecialStoragePolicy::IsStorageSessionOnly(const GURL
& origin
) {
55 if (cookie_settings_
.get() == NULL
)
57 return cookie_settings_
->IsCookieSessionOnly(origin
);
60 bool ExtensionSpecialStoragePolicy::CanQueryDiskSize(const GURL
& origin
) {
61 return installed_apps_
.Contains(origin
);
64 bool ExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
65 if (cookie_settings_
.get() == NULL
)
67 if (cookie_settings_
->GetDefaultCookieSetting(NULL
) ==
68 CONTENT_SETTING_SESSION_ONLY
)
70 ContentSettingsForOneType entries
;
71 cookie_settings_
->GetCookieSettings(&entries
);
72 for (size_t i
= 0; i
< entries
.size(); ++i
) {
73 if (entries
[i
].setting
== CONTENT_SETTING_SESSION_ONLY
)
79 bool ExtensionSpecialStoragePolicy::IsFileHandler(
80 const std::string
& extension_id
) {
81 base::AutoLock
locker(lock_
);
82 return file_handler_extensions_
.ContainsExtension(extension_id
);
85 bool ExtensionSpecialStoragePolicy::HasIsolatedStorage(const GURL
& origin
) {
86 base::AutoLock
locker(lock_
);
87 return isolated_extensions_
.Contains(origin
);
90 bool ExtensionSpecialStoragePolicy::NeedsProtection(
91 const extensions::Extension
* extension
) {
92 return extension
->is_hosted_app() && !extension
->from_bookmark();
95 const extensions::ExtensionSet
*
96 ExtensionSpecialStoragePolicy::ExtensionsProtectingOrigin(
98 base::AutoLock
locker(lock_
);
99 return protected_apps_
.ExtensionsContaining(origin
);
102 void ExtensionSpecialStoragePolicy::GrantRightsForExtension(
103 const extensions::Extension
* extension
) {
105 if (!(NeedsProtection(extension
) ||
106 extension
->HasAPIPermission(APIPermission::kUnlimitedStorage
) ||
107 extension
->HasAPIPermission(APIPermission::kFileBrowserHandler
) ||
108 extensions::AppIsolationInfo::HasIsolatedStorage(extension
) ||
109 extension
->is_app())) {
113 int change_flags
= 0;
115 base::AutoLock
locker(lock_
);
116 if (NeedsProtection(extension
) && protected_apps_
.Add(extension
))
117 change_flags
|= SpecialStoragePolicy::STORAGE_PROTECTED
;
118 // FIXME: Does GrantRightsForExtension imply |extension| is installed?
119 if (extension
->is_app())
120 installed_apps_
.Add(extension
);
122 if (extension
->HasAPIPermission(APIPermission::kUnlimitedStorage
) &&
123 unlimited_extensions_
.Add(extension
))
124 change_flags
|= SpecialStoragePolicy::STORAGE_UNLIMITED
;
126 if (extension
->HasAPIPermission(APIPermission::kFileBrowserHandler
))
127 file_handler_extensions_
.Add(extension
);
129 if (extensions::AppIsolationInfo::HasIsolatedStorage(extension
))
130 isolated_extensions_
.Add(extension
);
134 NotifyGranted(Extension::GetBaseURLFromExtensionId(extension
->id()),
139 void ExtensionSpecialStoragePolicy::RevokeRightsForExtension(
140 const extensions::Extension
* extension
) {
142 if (!(NeedsProtection(extension
) ||
143 extension
->HasAPIPermission(APIPermission::kUnlimitedStorage
) ||
144 extension
->HasAPIPermission(APIPermission::kFileBrowserHandler
) ||
145 extensions::AppIsolationInfo::HasIsolatedStorage(extension
) ||
146 extension
->is_app())) {
149 int change_flags
= 0;
151 base::AutoLock
locker(lock_
);
152 if (NeedsProtection(extension
) && protected_apps_
.Remove(extension
))
153 change_flags
|= SpecialStoragePolicy::STORAGE_PROTECTED
;
155 if (extension
->is_app())
156 installed_apps_
.Remove(extension
);
158 if (extension
->HasAPIPermission(APIPermission::kUnlimitedStorage
) &&
159 unlimited_extensions_
.Remove(extension
))
160 change_flags
|= SpecialStoragePolicy::STORAGE_UNLIMITED
;
162 if (extension
->HasAPIPermission(APIPermission::kFileBrowserHandler
))
163 file_handler_extensions_
.Remove(extension
);
165 if (extensions::AppIsolationInfo::HasIsolatedStorage(extension
))
166 isolated_extensions_
.Remove(extension
);
170 NotifyRevoked(Extension::GetBaseURLFromExtensionId(extension
->id()),
175 void ExtensionSpecialStoragePolicy::RevokeRightsForAllExtensions() {
177 base::AutoLock
locker(lock_
);
178 protected_apps_
.Clear();
179 installed_apps_
.Clear();
180 unlimited_extensions_
.Clear();
181 file_handler_extensions_
.Clear();
182 isolated_extensions_
.Clear();
188 void ExtensionSpecialStoragePolicy::NotifyGranted(
191 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
192 BrowserThread::PostTask(
193 BrowserThread::IO
, FROM_HERE
,
194 base::Bind(&ExtensionSpecialStoragePolicy::NotifyGranted
, this,
195 origin
, change_flags
));
198 SpecialStoragePolicy::NotifyGranted(origin
, change_flags
);
201 void ExtensionSpecialStoragePolicy::NotifyRevoked(
204 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
205 BrowserThread::PostTask(
206 BrowserThread::IO
, FROM_HERE
,
207 base::Bind(&ExtensionSpecialStoragePolicy::NotifyRevoked
, this,
208 origin
, change_flags
));
211 SpecialStoragePolicy::NotifyRevoked(origin
, change_flags
);
214 void ExtensionSpecialStoragePolicy::NotifyCleared() {
215 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
216 BrowserThread::PostTask(
217 BrowserThread::IO
, FROM_HERE
,
218 base::Bind(&ExtensionSpecialStoragePolicy::NotifyCleared
, this));
221 SpecialStoragePolicy::NotifyCleared();
224 //-----------------------------------------------------------------------------
225 // SpecialCollection helper class
226 //-----------------------------------------------------------------------------
228 ExtensionSpecialStoragePolicy::SpecialCollection::SpecialCollection() {}
230 ExtensionSpecialStoragePolicy::SpecialCollection::~SpecialCollection() {
231 STLDeleteValues(&cached_results_
);
234 bool ExtensionSpecialStoragePolicy::SpecialCollection::Contains(
235 const GURL
& origin
) {
236 return !ExtensionsContaining(origin
)->is_empty();
239 const extensions::ExtensionSet
*
240 ExtensionSpecialStoragePolicy::SpecialCollection::ExtensionsContaining(
241 const GURL
& origin
) {
242 CachedResults::const_iterator found
= cached_results_
.find(origin
);
243 if (found
!= cached_results_
.end())
244 return found
->second
;
246 extensions::ExtensionSet
* result
= new extensions::ExtensionSet();
247 for (extensions::ExtensionSet::const_iterator iter
= extensions_
.begin();
248 iter
!= extensions_
.end(); ++iter
) {
249 if ((*iter
)->OverlapsWithOrigin(origin
))
250 result
->Insert(*iter
);
252 cached_results_
[origin
] = result
;
256 bool ExtensionSpecialStoragePolicy::SpecialCollection::ContainsExtension(
257 const std::string
& extension_id
) {
258 return extensions_
.Contains(extension_id
);
261 bool ExtensionSpecialStoragePolicy::SpecialCollection::Add(
262 const extensions::Extension
* extension
) {
264 return extensions_
.Insert(extension
);
267 bool ExtensionSpecialStoragePolicy::SpecialCollection::Remove(
268 const extensions::Extension
* extension
) {
270 return extensions_
.Remove(extension
->id());
273 void ExtensionSpecialStoragePolicy::SpecialCollection::Clear() {
278 void ExtensionSpecialStoragePolicy::SpecialCollection::ClearCache() {
279 STLDeleteValues(&cached_results_
);
280 cached_results_
.clear();