Connect PPAPI IPC channels for non-SFI mode.
[chromium-blink-merge.git] / extensions / common / permissions / permission_set.cc
blobfd32d4e83d64adcd6c29405b0f826ef5a6013072
1 // Copyright 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.
5 #include "extensions/common/permissions/permission_set.h"
7 #include <algorithm>
8 #include <iterator>
9 #include <string>
11 #include "extensions/common/permissions/permissions_info.h"
12 #include "extensions/common/url_pattern.h"
13 #include "extensions/common/url_pattern_set.h"
14 #include "url/gurl.h"
16 using extensions::URLPatternSet;
18 namespace {
20 void AddPatternsAndRemovePaths(const URLPatternSet& set, URLPatternSet* out) {
21 DCHECK(out);
22 for (URLPatternSet::const_iterator i = set.begin(); i != set.end(); ++i) {
23 URLPattern p = *i;
24 p.SetPath("/*");
25 out->AddPattern(p);
29 } // namespace
31 namespace extensions {
34 // PermissionSet
37 PermissionSet::PermissionSet() {}
39 PermissionSet::PermissionSet(
40 const APIPermissionSet& apis,
41 const ManifestPermissionSet& manifest_permissions,
42 const URLPatternSet& explicit_hosts,
43 const URLPatternSet& scriptable_hosts)
44 : apis_(apis),
45 manifest_permissions_(manifest_permissions),
46 scriptable_hosts_(scriptable_hosts) {
47 AddPatternsAndRemovePaths(explicit_hosts, &explicit_hosts_);
48 InitImplicitPermissions();
49 InitEffectiveHosts();
52 // static
53 PermissionSet* PermissionSet::CreateDifference(
54 const PermissionSet* set1,
55 const PermissionSet* set2) {
56 scoped_refptr<PermissionSet> empty = new PermissionSet();
57 const PermissionSet* set1_safe = (set1 == NULL) ? empty.get() : set1;
58 const PermissionSet* set2_safe = (set2 == NULL) ? empty.get() : set2;
60 APIPermissionSet apis;
61 APIPermissionSet::Difference(set1_safe->apis(), set2_safe->apis(), &apis);
63 ManifestPermissionSet manifest_permissions;
64 ManifestPermissionSet::Difference(set1_safe->manifest_permissions(),
65 set2_safe->manifest_permissions(),
66 &manifest_permissions);
68 URLPatternSet explicit_hosts;
69 URLPatternSet::CreateDifference(set1_safe->explicit_hosts(),
70 set2_safe->explicit_hosts(),
71 &explicit_hosts);
73 URLPatternSet scriptable_hosts;
74 URLPatternSet::CreateDifference(set1_safe->scriptable_hosts(),
75 set2_safe->scriptable_hosts(),
76 &scriptable_hosts);
78 return new PermissionSet(apis, manifest_permissions,
79 explicit_hosts, scriptable_hosts);
82 // static
83 PermissionSet* PermissionSet::CreateIntersection(
84 const PermissionSet* set1,
85 const PermissionSet* set2) {
86 scoped_refptr<PermissionSet> empty = new PermissionSet();
87 const PermissionSet* set1_safe = (set1 == NULL) ? empty.get() : set1;
88 const PermissionSet* set2_safe = (set2 == NULL) ? empty.get() : set2;
90 APIPermissionSet apis;
91 APIPermissionSet::Intersection(set1_safe->apis(), set2_safe->apis(), &apis);
93 ManifestPermissionSet manifest_permissions;
94 ManifestPermissionSet::Intersection(set1_safe->manifest_permissions(),
95 set2_safe->manifest_permissions(),
96 &manifest_permissions);
98 URLPatternSet explicit_hosts;
99 URLPatternSet::CreateIntersection(set1_safe->explicit_hosts(),
100 set2_safe->explicit_hosts(),
101 &explicit_hosts);
103 URLPatternSet scriptable_hosts;
104 URLPatternSet::CreateIntersection(set1_safe->scriptable_hosts(),
105 set2_safe->scriptable_hosts(),
106 &scriptable_hosts);
108 return new PermissionSet(apis, manifest_permissions,
109 explicit_hosts, scriptable_hosts);
112 // static
113 PermissionSet* PermissionSet::CreateUnion(
114 const PermissionSet* set1,
115 const PermissionSet* set2) {
116 scoped_refptr<PermissionSet> empty = new PermissionSet();
117 const PermissionSet* set1_safe = (set1 == NULL) ? empty.get() : set1;
118 const PermissionSet* set2_safe = (set2 == NULL) ? empty.get() : set2;
120 APIPermissionSet apis;
121 APIPermissionSet::Union(set1_safe->apis(), set2_safe->apis(), &apis);
123 ManifestPermissionSet manifest_permissions;
124 ManifestPermissionSet::Union(set1_safe->manifest_permissions(),
125 set2_safe->manifest_permissions(),
126 &manifest_permissions);
128 URLPatternSet explicit_hosts;
129 URLPatternSet::CreateUnion(set1_safe->explicit_hosts(),
130 set2_safe->explicit_hosts(),
131 &explicit_hosts);
133 URLPatternSet scriptable_hosts;
134 URLPatternSet::CreateUnion(set1_safe->scriptable_hosts(),
135 set2_safe->scriptable_hosts(),
136 &scriptable_hosts);
138 return new PermissionSet(apis, manifest_permissions,
139 explicit_hosts, scriptable_hosts);
142 bool PermissionSet::operator==(
143 const PermissionSet& rhs) const {
144 return apis_ == rhs.apis_ &&
145 manifest_permissions_ == rhs.manifest_permissions_ &&
146 scriptable_hosts_ == rhs.scriptable_hosts_ &&
147 explicit_hosts_ == rhs.explicit_hosts_;
150 bool PermissionSet::Contains(const PermissionSet& set) const {
151 return apis_.Contains(set.apis()) &&
152 manifest_permissions_.Contains(set.manifest_permissions()) &&
153 explicit_hosts().Contains(set.explicit_hosts()) &&
154 scriptable_hosts().Contains(set.scriptable_hosts());
157 std::set<std::string> PermissionSet::GetAPIsAsStrings() const {
158 std::set<std::string> apis_str;
159 for (APIPermissionSet::const_iterator i = apis_.begin();
160 i != apis_.end(); ++i) {
161 apis_str.insert(i->name());
163 return apis_str;
166 bool PermissionSet::IsEmpty() const {
167 // Not default if any host permissions are present.
168 if (!(explicit_hosts().is_empty() && scriptable_hosts().is_empty()))
169 return false;
171 // Or if it has no api permissions.
172 return apis().empty() && manifest_permissions().empty();
175 bool PermissionSet::HasAPIPermission(
176 APIPermission::ID id) const {
177 return apis().find(id) != apis().end();
180 bool PermissionSet::HasAPIPermission(const std::string& permission_name) const {
181 const APIPermissionInfo* permission =
182 PermissionsInfo::GetInstance()->GetByName(permission_name);
183 // Ensure our PermissionsProvider is aware of this permission.
184 CHECK(permission) << permission_name;
185 return (permission && apis_.count(permission->id()));
188 bool PermissionSet::CheckAPIPermission(APIPermission::ID permission) const {
189 return CheckAPIPermissionWithParam(permission, NULL);
192 bool PermissionSet::CheckAPIPermissionWithParam(
193 APIPermission::ID permission,
194 const APIPermission::CheckParam* param) const {
195 APIPermissionSet::const_iterator iter = apis().find(permission);
196 if (iter == apis().end())
197 return false;
198 return iter->Check(param);
201 bool PermissionSet::HasExplicitAccessToOrigin(
202 const GURL& origin) const {
203 return explicit_hosts().MatchesURL(origin);
206 bool PermissionSet::HasScriptableAccessToURL(
207 const GURL& origin) const {
208 // We only need to check our host list to verify access. The host list should
209 // already reflect any special rules (such as chrome://favicon, all hosts
210 // access, etc.).
211 return scriptable_hosts().MatchesURL(origin);
214 bool PermissionSet::HasEffectiveAccessToAllHosts() const {
215 // There are two ways this set can have effective access to all hosts:
216 // 1) it has an <all_urls> URL pattern.
217 // 2) it has a named permission with implied full URL access.
218 for (URLPatternSet::const_iterator host = effective_hosts().begin();
219 host != effective_hosts().end(); ++host) {
220 if (host->match_all_urls() ||
221 (host->match_subdomains() && host->host().empty()))
222 return true;
225 for (APIPermissionSet::const_iterator i = apis().begin();
226 i != apis().end(); ++i) {
227 if (i->info()->implies_full_url_access())
228 return true;
230 return false;
233 bool PermissionSet::HasEffectiveAccessToURL(const GURL& url) const {
234 return effective_hosts().MatchesURL(url);
237 bool PermissionSet::HasEffectiveFullAccess() const {
238 for (APIPermissionSet::const_iterator i = apis().begin();
239 i != apis().end(); ++i) {
240 if (i->info()->implies_full_access())
241 return true;
243 return false;
246 PermissionSet::~PermissionSet() {}
248 void PermissionSet::InitImplicitPermissions() {
249 // The downloads permission implies the internal version as well.
250 if (apis_.find(APIPermission::kDownloads) != apis_.end())
251 apis_.insert(APIPermission::kDownloadsInternal);
253 // TODO(fsamuel): Is there a better way to request access to the WebRequest
254 // API without exposing it to the Chrome App?
255 if (apis_.find(APIPermission::kWebView) != apis_.end())
256 apis_.insert(APIPermission::kWebRequestInternal);
258 // The webRequest permission implies the internal version as well.
259 if (apis_.find(APIPermission::kWebRequest) != apis_.end())
260 apis_.insert(APIPermission::kWebRequestInternal);
262 // The fileBrowserHandler permission implies the internal version as well.
263 if (apis_.find(APIPermission::kFileBrowserHandler) != apis_.end())
264 apis_.insert(APIPermission::kFileBrowserHandlerInternal);
267 void PermissionSet::InitEffectiveHosts() {
268 effective_hosts_.ClearPatterns();
270 URLPatternSet::CreateUnion(
271 explicit_hosts(), scriptable_hosts(), &effective_hosts_);
274 } // namespace extensions