Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / extensions / common / permissions / permission_set.cc
blob5cd8d05ec77962cb99fd9bfa7d215163cd2c474d
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"
9 #include "url/gurl.h"
11 namespace extensions {
13 namespace {
15 void AddPatternsAndRemovePaths(const URLPatternSet& set, URLPatternSet* out) {
16 DCHECK(out);
17 for (URLPatternSet::const_iterator i = set.begin(); i != set.end(); ++i) {
18 URLPattern p = *i;
19 p.SetPath("/*");
20 out->AddPattern(p);
24 } // namespace
27 // PermissionSet
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)
37 : apis_(apis),
38 manifest_permissions_(manifest_permissions),
39 scriptable_hosts_(scriptable_hosts),
40 should_warn_all_hosts_(UNINITIALIZED) {
41 AddPatternsAndRemovePaths(explicit_hosts, &explicit_hosts_);
42 InitImplicitPermissions();
43 InitEffectiveHosts();
46 // static
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));
68 // static
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);
89 // static
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());
136 return apis_str;
139 bool PermissionSet::IsEmpty() const {
140 // Not default if any host permissions are present.
141 if (!(explicit_hosts().is_empty() && scriptable_hosts().is_empty()))
142 return false;
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())
170 return false;
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
183 // access, etc.).
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())
192 return true;
194 for (APIPermissionSet::const_iterator i = apis().begin();
195 i != apis().end(); ++i) {
196 if (i->info()->implies_full_url_access())
197 return true;
199 return false;
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())
216 return true;
218 return false;
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() {
234 effective_hosts_ =
235 URLPatternSet::CreateUnion(explicit_hosts(), scriptable_hosts());
238 void PermissionSet::InitShouldWarnAllHosts() const {
239 if (HasEffectiveAccessToAllHosts()) {
240 should_warn_all_hosts_ = WARN_ALL_HOSTS;
241 return;
244 for (URLPatternSet::const_iterator iter = effective_hosts_.begin();
245 iter != effective_hosts_.end();
246 ++iter) {
247 if (iter->ImpliesAllHosts()) {
248 should_warn_all_hosts_ = WARN_ALL_HOSTS;
249 return;
253 should_warn_all_hosts_ = DONT_WARN_ALL_HOSTS;
256 } // namespace extensions