[WRTjs] Enable WRTjs
[platform/framework/web/chromium-efl.git] / wrt / src / browser / wrt_special_storage_policy.cc
1 // Copyright 2021 Samsung Electronics. 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 "wrt_special_storage_policy.h"
6
7 #include "base/containers/contains.h"
8 #include "base/logging.h"
9 #include "content/public/browser/browser_task_traits.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "url/origin.h"
12
13 #if ENABLE_CHROME_EXTENSIONS
14 #include "extensions/common/constants.h"
15 #include "extensions/common/extension.h"
16 #include "extensions/common/extension_set.h"
17 #include "extensions/common/manifest_handlers/content_capabilities_handler.h"
18 #include "extensions/common/permissions/api_permission.h"
19 #include "extensions/common/permissions/permissions_data.h"
20 #endif
21
22 using content::BrowserThread;
23
24 #if ENABLE_CHROME_EXTENSIONS
25 using extensions::APIPermission;
26 using extensions::Extension;
27 #endif
28
29 namespace wrt {
30
31 WRTSpecialStoragePolicy::WRTSpecialStoragePolicy() {}
32
33 WRTSpecialStoragePolicy::~WRTSpecialStoragePolicy() {
34   quota_exceeded_callback_.Reset();
35 }
36
37 bool WRTSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) {
38   base::AutoLock locker(lock_);
39   if (base::Contains(unlimited_, origin))
40     return unlimited_.find(origin)->second;
41
42 #if ENABLE_CHROME_EXTENSIONS
43   if (unlimited_extensions_.Contains(origin) ||
44       content_capabilities_unlimited_extensions_.GrantsCapabilitiesTo(origin)) {
45     return true;
46   }
47 #endif
48
49   return false;
50 }
51
52 void WRTSpecialStoragePolicy::RequestUnlimitedStoragePolicy(
53     const GURL& origin,
54     int64_t quota,
55     QuotaExceededReplyCallback callback) {
56   {
57     base::AutoLock locker(lock_);
58     if (base::Contains(unlimited_, origin) ||
59         quota_exceeded_callback_.is_null()) {
60       LOG(INFO) << __func__ << " unlimited.";
61       std::move(callback).Run(false /* policy_changed */);
62       return;
63     }
64   }
65   LOG(INFO) << __func__ << " quota exceeded callback run.";
66   quota_exceeded_callback_.Run(origin, quota);
67   quota_exceeded_reply_callback_ = std::move(callback);
68 }
69
70 void WRTSpecialStoragePolicy::SetQuotaExceededCallback(
71     QuotaExceededCallback callback) {
72   quota_exceeded_callback_ = callback;
73 }
74
75 void WRTSpecialStoragePolicy::SetUnlimitedStoragePolicy(const GURL& origin,
76                                                         bool allow) {
77   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
78     content::GetIOThreadTaskRunner({})->PostTask(
79         FROM_HERE,
80         base::BindOnce(&WRTSpecialStoragePolicy::SetUnlimitedStoragePolicy,
81                        base::Unretained(this), origin, allow));
82
83     return;
84   }
85   bool policy_changed = IsStorageUnlimited(origin) != allow;
86   LOG(INFO) << __func__ << "() allow:" << allow
87             << ", changed:" << policy_changed;
88   {
89     base::AutoLock locker(lock_);
90     unlimited_[origin] = allow;
91   }
92   if (policy_changed) {
93     if (allow) {
94       NotifyGranted(url::Origin::Create(origin),
95                     SpecialStoragePolicy::STORAGE_UNLIMITED);
96     } else {
97       NotifyRevoked(url::Origin::Create(origin),
98                     SpecialStoragePolicy::STORAGE_UNLIMITED);
99     }
100   }
101   if (!quota_exceeded_reply_callback_.is_null()) {
102     LOG(INFO) << __func__ << " quota exceeded reply callback run.";
103     std::move(quota_exceeded_reply_callback_).Run(policy_changed);
104   }
105 }
106
107 #if ENABLE_CHROME_EXTENSIONS
108 void WRTSpecialStoragePolicy::GrantRightsForExtension(
109     const extensions::Extension* extension) {
110   base::AutoLock locker(lock_);
111   DCHECK(extension);
112
113   int change_flags = 0;
114   if (extensions::ContentCapabilitiesInfo::Get(extension).permissions.count(
115           extensions::mojom::APIPermissionID::kUnlimitedStorage) > 0) {
116     content_capabilities_unlimited_extensions_.Add(extension);
117     change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
118   }
119
120   if (extension->permissions_data()->HasAPIPermission(
121           extensions::mojom::APIPermissionID::kUnlimitedStorage) &&
122       unlimited_extensions_.Add(extension)) {
123     change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
124   }
125
126   if (change_flags) {
127     const GURL origin = Extension::GetBaseURLFromExtensionId(extension->id());
128     NotifyGranted(url::Origin::Create(origin), change_flags);
129   }
130 }
131
132 void WRTSpecialStoragePolicy::RevokeRightsForExtension(
133     const extensions::Extension* extension) {
134   base::AutoLock locker(lock_);
135   DCHECK(extension);
136
137   int change_flags = 0;
138   if (extensions::ContentCapabilitiesInfo::Get(extension).permissions.count(
139           extensions::mojom::APIPermissionID::kUnlimitedStorage) > 0) {
140     content_capabilities_unlimited_extensions_.Remove(extension);
141     change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
142   }
143
144   if (extension->permissions_data()->HasAPIPermission(
145           extensions::mojom::APIPermissionID::kUnlimitedStorage) &&
146       unlimited_extensions_.Remove(extension)) {
147     change_flags |= SpecialStoragePolicy::STORAGE_UNLIMITED;
148   }
149
150   if (change_flags) {
151     const GURL origin = Extension::GetBaseURLFromExtensionId(extension->id());
152     NotifyRevoked(url::Origin::Create(origin), change_flags);
153   }
154 }
155
156 //-----------------------------------------------------------------------------
157 // SpecialCollection helper class
158 //-----------------------------------------------------------------------------
159
160 WRTSpecialStoragePolicy::SpecialCollection::SpecialCollection() {}
161
162 WRTSpecialStoragePolicy::SpecialCollection::~SpecialCollection() {}
163
164 bool WRTSpecialStoragePolicy::SpecialCollection::Contains(const GURL& origin) {
165   return !ExtensionsContaining(origin)->is_empty();
166 }
167
168 bool WRTSpecialStoragePolicy::SpecialCollection::GrantsCapabilitiesTo(
169     const GURL& origin) {
170   for (const auto& extension : extensions_) {
171     if (extensions::ContentCapabilitiesInfo::Get(extension.get())
172             .url_patterns.MatchesURL(origin)) {
173       return true;
174     }
175   }
176   return false;
177 }
178
179 const extensions::ExtensionSet*
180 WRTSpecialStoragePolicy::SpecialCollection::ExtensionsContaining(
181     const GURL& origin) {
182   std::unique_ptr<extensions::ExtensionSet>& result = cached_results_[origin];
183   if (result)
184     return result.get();
185
186   result = std::make_unique<extensions::ExtensionSet>();
187   for (auto& extension : extensions_) {
188     if (extension->OverlapsWithOrigin(origin))
189       result->Insert(extension);
190   }
191
192   return result.get();
193 }
194
195 bool WRTSpecialStoragePolicy::SpecialCollection::ContainsExtension(
196     const std::string& extension_id) {
197   return extensions_.Contains(extension_id);
198 }
199
200 bool WRTSpecialStoragePolicy::SpecialCollection::Add(
201     const extensions::Extension* extension) {
202   ClearCache();
203   return extensions_.Insert(extension);
204 }
205
206 bool WRTSpecialStoragePolicy::SpecialCollection::Remove(
207     const extensions::Extension* extension) {
208   ClearCache();
209   return extensions_.Remove(extension->id());
210 }
211
212 void WRTSpecialStoragePolicy::SpecialCollection::Clear() {
213   ClearCache();
214   extensions_.Clear();
215 }
216
217 void WRTSpecialStoragePolicy::SpecialCollection::ClearCache() {
218   cached_results_.clear();
219 }
220 #endif  // ENABLE_CHROME_EXTENSIONS
221
222 }  // namespace wrt