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 "extensions/common/permissions/permissions_info.h"
8 #include "extensions/common/url_pattern.h"
11 namespace extensions
{
15 void AddPatternsAndRemovePaths(const URLPatternSet
& set
, URLPatternSet
* out
) {
17 for (URLPatternSet::const_iterator i
= set
.begin(); i
!= set
.end(); ++i
) {
30 PermissionSet::PermissionSet() : should_warn_all_hosts_(UNINITIALIZED
) {}
32 PermissionSet::PermissionSet(
33 const APIPermissionSet
& apis
,
34 const ManifestPermissionSet
& manifest_permissions
,
35 const URLPatternSet
& explicit_hosts
,
36 const URLPatternSet
& scriptable_hosts
)
38 manifest_permissions_(manifest_permissions
),
39 scriptable_hosts_(scriptable_hosts
),
40 should_warn_all_hosts_(UNINITIALIZED
) {
41 AddPatternsAndRemovePaths(explicit_hosts
, &explicit_hosts_
);
42 InitImplicitPermissions();
47 scoped_refptr
<const PermissionSet
> PermissionSet::CreateDifference(
48 const PermissionSet
& set1
,
49 const PermissionSet
& set2
) {
50 APIPermissionSet apis
;
51 APIPermissionSet::Difference(set1
.apis(), set2
.apis(), &apis
);
53 ManifestPermissionSet manifest_permissions
;
54 ManifestPermissionSet::Difference(set1
.manifest_permissions(),
55 set2
.manifest_permissions(),
56 &manifest_permissions
);
58 URLPatternSet explicit_hosts
= URLPatternSet::CreateDifference(
59 set1
.explicit_hosts(), set2
.explicit_hosts());
61 URLPatternSet scriptable_hosts
= URLPatternSet::CreateDifference(
62 set1
.scriptable_hosts(), set2
.scriptable_hosts());
64 return make_scoped_refptr(new PermissionSet(
65 apis
, manifest_permissions
, explicit_hosts
, scriptable_hosts
));
69 scoped_refptr
<const PermissionSet
> PermissionSet::CreateIntersection(
70 const PermissionSet
& set1
,
71 const PermissionSet
& set2
) {
72 APIPermissionSet apis
;
73 APIPermissionSet::Intersection(set1
.apis(), set2
.apis(), &apis
);
75 ManifestPermissionSet manifest_permissions
;
76 ManifestPermissionSet::Intersection(set1
.manifest_permissions(),
77 set2
.manifest_permissions(),
78 &manifest_permissions
);
80 URLPatternSet explicit_hosts
= URLPatternSet::CreateSemanticIntersection(
81 set1
.explicit_hosts(), set2
.explicit_hosts());
82 URLPatternSet scriptable_hosts
= URLPatternSet::CreateSemanticIntersection(
83 set1
.scriptable_hosts(), set2
.scriptable_hosts());
85 return new PermissionSet(apis
, manifest_permissions
,
86 explicit_hosts
, scriptable_hosts
);
90 scoped_refptr
<const PermissionSet
> PermissionSet::CreateUnion(
91 const PermissionSet
& set1
,
92 const PermissionSet
& set2
) {
93 APIPermissionSet apis
;
94 APIPermissionSet::Union(set1
.apis(), set2
.apis(), &apis
);
96 ManifestPermissionSet manifest_permissions
;
97 ManifestPermissionSet::Union(set1
.manifest_permissions(),
98 set2
.manifest_permissions(),
99 &manifest_permissions
);
101 URLPatternSet explicit_hosts
=
102 URLPatternSet::CreateUnion(set1
.explicit_hosts(), set2
.explicit_hosts());
104 URLPatternSet scriptable_hosts
= URLPatternSet::CreateUnion(
105 set1
.scriptable_hosts(), set2
.scriptable_hosts());
107 return new PermissionSet(apis
, manifest_permissions
,
108 explicit_hosts
, scriptable_hosts
);
111 bool PermissionSet::operator==(
112 const PermissionSet
& rhs
) const {
113 return apis_
== rhs
.apis_
&&
114 manifest_permissions_
== rhs
.manifest_permissions_
&&
115 scriptable_hosts_
== rhs
.scriptable_hosts_
&&
116 explicit_hosts_
== rhs
.explicit_hosts_
;
119 bool PermissionSet::operator!=(const PermissionSet
& rhs
) const {
120 return !(*this == rhs
);
123 bool PermissionSet::Contains(const PermissionSet
& set
) const {
124 return apis_
.Contains(set
.apis()) &&
125 manifest_permissions_
.Contains(set
.manifest_permissions()) &&
126 explicit_hosts().Contains(set
.explicit_hosts()) &&
127 scriptable_hosts().Contains(set
.scriptable_hosts());
130 std::set
<std::string
> PermissionSet::GetAPIsAsStrings() const {
131 std::set
<std::string
> apis_str
;
132 for (APIPermissionSet::const_iterator i
= apis_
.begin();
133 i
!= apis_
.end(); ++i
) {
134 apis_str
.insert(i
->name());
139 bool PermissionSet::IsEmpty() const {
140 // Not default if any host permissions are present.
141 if (!(explicit_hosts().is_empty() && scriptable_hosts().is_empty()))
144 // Or if it has no api permissions.
145 return apis().empty() && manifest_permissions().empty();
148 bool PermissionSet::HasAPIPermission(
149 APIPermission::ID id
) const {
150 return apis().find(id
) != apis().end();
153 bool PermissionSet::HasAPIPermission(const std::string
& permission_name
) const {
154 const APIPermissionInfo
* permission
=
155 PermissionsInfo::GetInstance()->GetByName(permission_name
);
156 // Ensure our PermissionsProvider is aware of this permission.
157 CHECK(permission
) << permission_name
;
158 return (permission
&& apis_
.count(permission
->id()));
161 bool PermissionSet::CheckAPIPermission(APIPermission::ID permission
) const {
162 return CheckAPIPermissionWithParam(permission
, NULL
);
165 bool PermissionSet::CheckAPIPermissionWithParam(
166 APIPermission::ID permission
,
167 const APIPermission::CheckParam
* param
) const {
168 APIPermissionSet::const_iterator iter
= apis().find(permission
);
169 if (iter
== apis().end())
171 return iter
->Check(param
);
174 bool PermissionSet::HasExplicitAccessToOrigin(
175 const GURL
& origin
) const {
176 return explicit_hosts().MatchesURL(origin
);
179 bool PermissionSet::HasScriptableAccessToURL(
180 const GURL
& origin
) const {
181 // We only need to check our host list to verify access. The host list should
182 // already reflect any special rules (such as chrome://favicon, all hosts
184 return scriptable_hosts().MatchesURL(origin
);
187 bool PermissionSet::HasEffectiveAccessToAllHosts() const {
188 // There are two ways this set can have effective access to all hosts:
189 // 1) it has an <all_urls> URL pattern.
190 // 2) it has a named permission with implied full URL access.
191 if (effective_hosts().MatchesAllURLs())
194 for (APIPermissionSet::const_iterator i
= apis().begin();
195 i
!= apis().end(); ++i
) {
196 if (i
->info()->implies_full_url_access())
202 bool PermissionSet::ShouldWarnAllHosts() const {
203 if (should_warn_all_hosts_
== UNINITIALIZED
)
204 InitShouldWarnAllHosts();
205 return should_warn_all_hosts_
== WARN_ALL_HOSTS
;
208 bool PermissionSet::HasEffectiveAccessToURL(const GURL
& url
) const {
209 return effective_hosts().MatchesURL(url
);
212 bool PermissionSet::HasEffectiveFullAccess() const {
213 for (APIPermissionSet::const_iterator i
= apis().begin();
214 i
!= apis().end(); ++i
) {
215 if (i
->info()->implies_full_access())
221 PermissionSet::~PermissionSet() {}
223 void PermissionSet::InitImplicitPermissions() {
224 // The downloads permission implies the internal version as well.
225 if (apis_
.find(APIPermission::kDownloads
) != apis_
.end())
226 apis_
.insert(APIPermission::kDownloadsInternal
);
228 // The fileBrowserHandler permission implies the internal version as well.
229 if (apis_
.find(APIPermission::kFileBrowserHandler
) != apis_
.end())
230 apis_
.insert(APIPermission::kFileBrowserHandlerInternal
);
233 void PermissionSet::InitEffectiveHosts() {
235 URLPatternSet::CreateUnion(explicit_hosts(), scriptable_hosts());
238 void PermissionSet::InitShouldWarnAllHosts() const {
239 if (HasEffectiveAccessToAllHosts()) {
240 should_warn_all_hosts_
= WARN_ALL_HOSTS
;
244 for (URLPatternSet::const_iterator iter
= effective_hosts_
.begin();
245 iter
!= effective_hosts_
.end();
247 if (iter
->ImpliesAllHosts()) {
248 should_warn_all_hosts_
= WARN_ALL_HOSTS
;
253 should_warn_all_hosts_
= DONT_WARN_ALL_HOSTS
;
256 } // namespace extensions