summaryrefslogtreecommitdiffstats
path: root/extensions/common/permissions/permission_set.cc
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/common/permissions/permission_set.cc')
-rw-r--r--extensions/common/permissions/permission_set.cc251
1 files changed, 251 insertions, 0 deletions
diff --git a/extensions/common/permissions/permission_set.cc b/extensions/common/permissions/permission_set.cc
new file mode 100644
index 0000000..d3f46fc
--- /dev/null
+++ b/extensions/common/permissions/permission_set.cc
@@ -0,0 +1,251 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/common/permissions/permission_set.h"
+
+#include <algorithm>
+#include <iterator>
+#include <string>
+
+#include "extensions/common/permissions/permissions_info.h"
+#include "extensions/common/url_pattern.h"
+#include "extensions/common/url_pattern_set.h"
+#include "url/gurl.h"
+
+using extensions::URLPatternSet;
+
+namespace {
+
+void AddPatternsAndRemovePaths(const URLPatternSet& set, URLPatternSet* out) {
+ DCHECK(out);
+ for (URLPatternSet::const_iterator i = set.begin(); i != set.end(); ++i) {
+ URLPattern p = *i;
+ p.SetPath("/*");
+ out->AddPattern(p);
+ }
+}
+
+} // namespace
+
+namespace extensions {
+
+//
+// PermissionSet
+//
+
+PermissionSet::PermissionSet() {}
+
+PermissionSet::PermissionSet(
+ const APIPermissionSet& apis,
+ const URLPatternSet& explicit_hosts,
+ const URLPatternSet& scriptable_hosts)
+ : apis_(apis),
+ scriptable_hosts_(scriptable_hosts) {
+ AddPatternsAndRemovePaths(explicit_hosts, &explicit_hosts_);
+ InitImplicitPermissions();
+ InitEffectiveHosts();
+}
+
+// static
+PermissionSet* PermissionSet::CreateDifference(
+ const PermissionSet* set1,
+ const PermissionSet* set2) {
+ scoped_refptr<PermissionSet> empty = new PermissionSet();
+ const PermissionSet* set1_safe = (set1 == NULL) ? empty.get() : set1;
+ const PermissionSet* set2_safe = (set2 == NULL) ? empty.get() : set2;
+
+ APIPermissionSet apis;
+ APIPermissionSet::Difference(set1_safe->apis(), set2_safe->apis(), &apis);
+
+ URLPatternSet explicit_hosts;
+ URLPatternSet::CreateDifference(set1_safe->explicit_hosts(),
+ set2_safe->explicit_hosts(),
+ &explicit_hosts);
+
+ URLPatternSet scriptable_hosts;
+ URLPatternSet::CreateDifference(set1_safe->scriptable_hosts(),
+ set2_safe->scriptable_hosts(),
+ &scriptable_hosts);
+
+ return new PermissionSet(apis, explicit_hosts, scriptable_hosts);
+}
+
+// static
+PermissionSet* PermissionSet::CreateIntersection(
+ const PermissionSet* set1,
+ const PermissionSet* set2) {
+ scoped_refptr<PermissionSet> empty = new PermissionSet();
+ const PermissionSet* set1_safe = (set1 == NULL) ? empty.get() : set1;
+ const PermissionSet* set2_safe = (set2 == NULL) ? empty.get() : set2;
+
+ APIPermissionSet apis;
+ APIPermissionSet::Intersection(set1_safe->apis(), set2_safe->apis(), &apis);
+
+ URLPatternSet explicit_hosts;
+ URLPatternSet::CreateIntersection(set1_safe->explicit_hosts(),
+ set2_safe->explicit_hosts(),
+ &explicit_hosts);
+
+ URLPatternSet scriptable_hosts;
+ URLPatternSet::CreateIntersection(set1_safe->scriptable_hosts(),
+ set2_safe->scriptable_hosts(),
+ &scriptable_hosts);
+
+ return new PermissionSet(apis, explicit_hosts, scriptable_hosts);
+}
+
+// static
+PermissionSet* PermissionSet::CreateUnion(
+ const PermissionSet* set1,
+ const PermissionSet* set2) {
+ scoped_refptr<PermissionSet> empty = new PermissionSet();
+ const PermissionSet* set1_safe = (set1 == NULL) ? empty.get() : set1;
+ const PermissionSet* set2_safe = (set2 == NULL) ? empty.get() : set2;
+
+ APIPermissionSet apis;
+ APIPermissionSet::Union(set1_safe->apis(), set2_safe->apis(), &apis);
+
+ URLPatternSet explicit_hosts;
+ URLPatternSet::CreateUnion(set1_safe->explicit_hosts(),
+ set2_safe->explicit_hosts(),
+ &explicit_hosts);
+
+ URLPatternSet scriptable_hosts;
+ URLPatternSet::CreateUnion(set1_safe->scriptable_hosts(),
+ set2_safe->scriptable_hosts(),
+ &scriptable_hosts);
+
+ return new PermissionSet(apis, explicit_hosts, scriptable_hosts);
+}
+
+bool PermissionSet::operator==(
+ const PermissionSet& rhs) const {
+ return apis_ == rhs.apis_ &&
+ scriptable_hosts_ == rhs.scriptable_hosts_ &&
+ explicit_hosts_ == rhs.explicit_hosts_;
+}
+
+bool PermissionSet::Contains(const PermissionSet& set) const {
+ return apis_.Contains(set.apis()) &&
+ explicit_hosts().Contains(set.explicit_hosts()) &&
+ scriptable_hosts().Contains(set.scriptable_hosts());
+}
+
+std::set<std::string> PermissionSet::GetAPIsAsStrings() const {
+ std::set<std::string> apis_str;
+ for (APIPermissionSet::const_iterator i = apis_.begin();
+ i != apis_.end(); ++i) {
+ apis_str.insert(i->name());
+ }
+ return apis_str;
+}
+
+bool PermissionSet::IsEmpty() const {
+ // Not default if any host permissions are present.
+ if (!(explicit_hosts().is_empty() && scriptable_hosts().is_empty()))
+ return false;
+
+ // Or if it has no api permissions.
+ return apis().empty();
+}
+
+bool PermissionSet::HasAPIPermission(
+ APIPermission::ID id) const {
+ return apis().find(id) != apis().end();
+}
+
+bool PermissionSet::HasAPIPermission(const std::string& permission_name) const {
+ const APIPermissionInfo* permission =
+ PermissionsInfo::GetInstance()->GetByName(permission_name);
+ CHECK(permission) << permission_name;
+ return (permission && apis_.count(permission->id()));
+}
+
+bool PermissionSet::CheckAPIPermission(APIPermission::ID permission) const {
+ return CheckAPIPermissionWithParam(permission, NULL);
+}
+
+bool PermissionSet::CheckAPIPermissionWithParam(
+ APIPermission::ID permission,
+ const APIPermission::CheckParam* param) const {
+ APIPermissionSet::const_iterator iter = apis().find(permission);
+ if (iter == apis().end())
+ return false;
+ return iter->Check(param);
+}
+
+bool PermissionSet::HasExplicitAccessToOrigin(
+ const GURL& origin) const {
+ return explicit_hosts().MatchesURL(origin);
+}
+
+bool PermissionSet::HasScriptableAccessToURL(
+ const GURL& origin) const {
+ // We only need to check our host list to verify access. The host list should
+ // already reflect any special rules (such as chrome://favicon, all hosts
+ // access, etc.).
+ return scriptable_hosts().MatchesURL(origin);
+}
+
+bool PermissionSet::HasEffectiveAccessToAllHosts() const {
+ // There are two ways this set can have effective access to all hosts:
+ // 1) it has an <all_urls> URL pattern.
+ // 2) it has a named permission with implied full URL access.
+ for (URLPatternSet::const_iterator host = effective_hosts().begin();
+ host != effective_hosts().end(); ++host) {
+ if (host->match_all_urls() ||
+ (host->match_subdomains() && host->host().empty()))
+ return true;
+ }
+
+ for (APIPermissionSet::const_iterator i = apis().begin();
+ i != apis().end(); ++i) {
+ if (i->info()->implies_full_url_access())
+ return true;
+ }
+ return false;
+}
+
+bool PermissionSet::HasEffectiveAccessToURL(const GURL& url) const {
+ return effective_hosts().MatchesURL(url);
+}
+
+bool PermissionSet::HasEffectiveFullAccess() const {
+ for (APIPermissionSet::const_iterator i = apis().begin();
+ i != apis().end(); ++i) {
+ if (i->info()->implies_full_access())
+ return true;
+ }
+ return false;
+}
+
+PermissionSet::~PermissionSet() {}
+
+void PermissionSet::InitImplicitPermissions() {
+ // The downloads permission implies the internal version as well.
+ if (apis_.find(APIPermission::kDownloads) != apis_.end())
+ apis_.insert(APIPermission::kDownloadsInternal);
+
+ // TODO(fsamuel): Is there a better way to request access to the WebRequest
+ // API without exposing it to the Chrome App?
+ if (apis_.find(APIPermission::kWebView) != apis_.end())
+ apis_.insert(APIPermission::kWebRequestInternal);
+
+ // The webRequest permission implies the internal version as well.
+ if (apis_.find(APIPermission::kWebRequest) != apis_.end())
+ apis_.insert(APIPermission::kWebRequestInternal);
+
+ // The fileBrowserHandler permission implies the internal version as well.
+ if (apis_.find(APIPermission::kFileBrowserHandler) != apis_.end())
+ apis_.insert(APIPermission::kFileBrowserHandlerInternal);
+}
+
+void PermissionSet::InitEffectiveHosts() {
+ effective_hosts_.ClearPatterns();
+
+ URLPatternSet::CreateUnion(
+ explicit_hosts(), scriptable_hosts(), &effective_hosts_);
+}
+
+} // namespace extensions