summaryrefslogtreecommitdiffstats
path: root/chrome/common/extensions/permissions/permission_set.h
blob: b77ff4af5f267e50bcfbe115c3170eee9a41f6a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright (c) 2012 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.

#ifndef CHROME_COMMON_EXTENSIONS_PERMISSIONS_PERMISSION_SET_H_
#define CHROME_COMMON_EXTENSIONS_PERMISSIONS_PERMISSION_SET_H_

#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/string16.h"
#include "chrome/common/extensions/permissions/api_permission.h"
#include "chrome/common/extensions/permissions/permission_message.h"
#include "chrome/common/extensions/url_pattern_set.h"

namespace extensions {

class Extension;

// The PermissionSet is an immutable class that encapsulates an
// extension's permissions. The class exposes set operations for combining and
// manipulating the permissions.
class PermissionSet
    : public base::RefCountedThreadSafe<PermissionSet> {
 public:
  // Creates an empty permission set (e.g. default permissions).
  PermissionSet();

  // Creates a new permission set based on the |extension| manifest data, and
  // the api and host permissions (|apis| and |hosts|). The effective hosts
  // of the newly created permission set will be inferred from the |extension|
  // manifest, |apis| and |hosts|.
  PermissionSet(const extensions::Extension* extension,
                const APIPermissionSet& apis,
                const URLPatternSet& explicit_hosts);

  // Creates a new permission set based on the specified data.
  PermissionSet(const APIPermissionSet& apis,
                const URLPatternSet& explicit_hosts,
                const URLPatternSet& scriptable_hosts);

  // Creates a new permission set equal to |set1| - |set2|, passing ownership of
  // the new set to the caller.
  static PermissionSet* CreateDifference(
      const PermissionSet* set1, const PermissionSet* set2);

  // Creates a new permission set equal to the intersection of |set1| and
  // |set2|, passing ownership of the new set to the caller.
  static PermissionSet* CreateIntersection(
      const PermissionSet* set1, const PermissionSet* set2);

  // Creates a new permission set equal to the union of |set1| and |set2|.
  // Passes ownership of the new set to the caller.
  static PermissionSet* CreateUnion(
      const PermissionSet* set1, const PermissionSet* set2);

  bool operator==(const PermissionSet& rhs) const;

  // Returns true if |set| is a subset of this.
  bool Contains(const PermissionSet& set) const;

  // Gets the API permissions in this set as a set of strings.
  std::set<std::string> GetAPIsAsStrings() const;

  // Gets the API permissions in this set, plus any that have implicit access
  // (such as APIs that require no permissions, or APIs with functions that
  // require no permissions).
  // TODO(kalman): return scoped_ptr to avoid copying.
  std::set<std::string> GetAPIsWithAnyAccessAsStrings() const;

  // Returns whether this namespace has any functions which the extension has
  // permission to use.  For example, even though the extension may not have
  // the "tabs" permission, "tabs.create" requires no permissions so
  // HasAnyAPIPermission("tabs") will return true.
  bool HasAnyAccessToAPI(const std::string& api_name) const;

  // Gets a list of the distinct hosts for displaying to the user.
  // NOTE: do not use this for comparing permissions, since this disgards some
  // information.
  std::set<std::string> GetDistinctHostsForDisplay() const;

  // Gets the localized permission messages that represent this set.
  PermissionMessages GetPermissionMessages() const;

  // Gets the localized permission messages that represent this set (represented
  // as strings).
  std::vector<string16> GetWarningMessages() const;

  // Returns true if this is an empty set (e.g., the default permission set).
  bool IsEmpty() const;

  // Returns true if the set has the specified API permission.
  bool HasAPIPermission(APIPermission::ID permission) const;

  // Returns true if the permissions in this set grant access to the specified
  // |function_name|.
  bool HasAccessToFunction(const std::string& function_name) const;

  // Returns true if this includes permission to access |origin|.
  bool HasExplicitAccessToOrigin(const GURL& origin) const;

  // Returns true if this permission set includes access to script |url|.
  bool HasScriptableAccessToURL(const GURL& url) const;

  // Returns true if this permission set includes effective access to all
  // origins.
  bool HasEffectiveAccessToAllHosts() const;

  // Returns true if this permission set includes effective access to |url|.
  bool HasEffectiveAccessToURL(const GURL& url) const;

  // Returns ture if this permission set effectively represents full access
  // (e.g. native code).
  bool HasEffectiveFullAccess() const;

  // Returns true if |permissions| has a greater privilege level than this
  // permission set (e.g., this permission set has less permissions).
  bool HasLessPrivilegesThan(const PermissionSet* permissions) const;

  const APIPermissionSet& apis() const { return apis_; }

  const URLPatternSet& effective_hosts() const { return effective_hosts_; }

  const URLPatternSet& explicit_hosts() const { return explicit_hosts_; }

  const URLPatternSet& scriptable_hosts() const { return scriptable_hosts_; }

 private:
  FRIEND_TEST_ALL_PREFIXES(PermissionsTest, HasLessHostPrivilegesThan);
  FRIEND_TEST_ALL_PREFIXES(PermissionsTest, GetWarningMessages_AudioVideo);
  friend class base::RefCountedThreadSafe<PermissionSet>;

  ~PermissionSet();

  static std::set<std::string> GetDistinctHosts(
      const URLPatternSet& host_patterns,
      bool include_rcd,
      bool exclude_file_scheme);

  // Initializes the set based on |extension|'s manifest data.
  void InitImplicitExtensionPermissions(const extensions::Extension* extension);

  // Initializes the effective host permission based on the data in this set.
  void InitEffectiveHosts();

  // Gets the permission messages for the API permissions.
  std::set<PermissionMessage> GetSimplePermissionMessages() const;

  // Returns true if |permissions| has an elevated API privilege level than
  // this set.
  bool HasLessAPIPrivilegesThan(
      const PermissionSet* permissions) const;

  // Returns true if |permissions| has more host permissions compared to this
  // set.
  bool HasLessHostPrivilegesThan(
      const PermissionSet* permissions) const;

  // The api list is used when deciding if an extension can access certain
  // extension APIs and features.
  APIPermissionSet apis_;

  // The list of hosts that can be accessed directly from the extension.
  // TODO(jstritar): Rename to "hosts_"?
  URLPatternSet explicit_hosts_;

  // The list of hosts that can be scripted by content scripts.
  // TODO(jstritar): Rename to "user_script_hosts_"?
  URLPatternSet scriptable_hosts_;

  // The list of hosts this effectively grants access to.
  URLPatternSet effective_hosts_;
};

}  // namespace extensions

#endif  // CHROME_COMMON_EXTENSIONS_PERMISSIONS_PERMISSION_SET_H_