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.
4
5#ifndef EXTENSIONS_COMMON_PERMISSIONS_PERMISSION_SET_H_
6#define EXTENSIONS_COMMON_PERMISSIONS_PERMISSION_SET_H_
7
8#include <map>
9#include <set>
10#include <string>
11#include <vector>
12
13#include "base/gtest_prod_util.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/singleton.h"
16#include "base/strings/string16.h"
17#include "extensions/common/manifest.h"
18#include "extensions/common/permissions/api_permission.h"
19#include "extensions/common/permissions/api_permission_set.h"
20#include "extensions/common/permissions/manifest_permission.h"
21#include "extensions/common/permissions/manifest_permission_set.h"
22#include "extensions/common/url_pattern_set.h"
23
24namespace extensions {
25class Extension;
26
27// The PermissionSet is an immutable class that encapsulates an
28// extension's permissions. The class exposes set operations for combining and
29// manipulating the permissions.
30class PermissionSet
31    : public base::RefCountedThreadSafe<PermissionSet> {
32 public:
33  // Creates an empty permission set (e.g. default permissions).
34  PermissionSet();
35
36  // Creates a new permission set based on the specified data: the API
37  // permissions, manifest key permissions, host permissions, and scriptable
38  // hosts. The effective hosts of the newly created permission set will be
39  // inferred from the given host permissions.
40  PermissionSet(const APIPermissionSet& apis,
41                const ManifestPermissionSet& manifest_permissions,
42                const URLPatternSet& explicit_hosts,
43                const URLPatternSet& scriptable_hosts);
44
45  // Creates a new permission set equal to |set1| - |set2|, passing ownership of
46  // the new set to the caller.
47  static PermissionSet* CreateDifference(
48      const PermissionSet* set1, const PermissionSet* set2);
49
50  // Creates a new permission set equal to the intersection of |set1| and
51  // |set2|, passing ownership of the new set to the caller.
52  static PermissionSet* CreateIntersection(
53      const PermissionSet* set1, const PermissionSet* set2);
54
55  // Creates a new permission set equal to the union of |set1| and |set2|.
56  // Passes ownership of the new set to the caller.
57  static PermissionSet* CreateUnion(
58      const PermissionSet* set1, const PermissionSet* set2);
59
60  bool operator==(const PermissionSet& rhs) const;
61
62  // Returns true if every API or host permission available to |set| is also
63  // available to this. In other words, if the API permissions of |set| are a
64  // subset of this, and the host permissions in this encompass those in |set|.
65  bool Contains(const PermissionSet& set) const;
66
67  // Gets the API permissions in this set as a set of strings.
68  std::set<std::string> GetAPIsAsStrings() const;
69
70  // Returns true if this is an empty set (e.g., the default permission set).
71  bool IsEmpty() const;
72
73  // Returns true if the set has the specified API permission.
74  bool HasAPIPermission(APIPermission::ID permission) const;
75
76  // Returns true if the |extension| explicitly requests access to the given
77  // |permission_name|. Note this does not include APIs without no corresponding
78  // permission, like "runtime" or "browserAction".
79  bool HasAPIPermission(const std::string& permission_name) const;
80
81  // Returns true if the set allows the given permission with the default
82  // permission detal.
83  bool CheckAPIPermission(APIPermission::ID permission) const;
84
85  // Returns true if the set allows the given permission and permission param.
86  bool CheckAPIPermissionWithParam(APIPermission::ID permission,
87      const APIPermission::CheckParam* param) const;
88
89  // Returns true if this includes permission to access |origin|.
90  bool HasExplicitAccessToOrigin(const GURL& origin) const;
91
92  // Returns true if this permission set includes access to script |url|.
93  bool HasScriptableAccessToURL(const GURL& url) const;
94
95  // Returns true if this permission set includes effective access to all
96  // origins.
97  bool HasEffectiveAccessToAllHosts() const;
98
99  // Returns true if this permission set has access to so many hosts, that we
100  // should treat it as all hosts for warning purposes.
101  // For example, '*://*.com/*'.
102  bool ShouldWarnAllHosts() const;
103
104  // Returns true if this permission set includes effective access to |url|.
105  bool HasEffectiveAccessToURL(const GURL& url) const;
106
107  // Returns true if this permission set effectively represents full access
108  // (e.g. native code).
109  bool HasEffectiveFullAccess() const;
110
111  const APIPermissionSet& apis() const { return apis_; }
112
113  const ManifestPermissionSet& manifest_permissions() const {
114      return manifest_permissions_;
115  }
116
117  const URLPatternSet& effective_hosts() const { return effective_hosts_; }
118
119  const URLPatternSet& explicit_hosts() const { return explicit_hosts_; }
120
121  const URLPatternSet& scriptable_hosts() const { return scriptable_hosts_; }
122
123 private:
124  FRIEND_TEST_ALL_PREFIXES(PermissionsTest, GetWarningMessages_AudioVideo);
125  FRIEND_TEST_ALL_PREFIXES(PermissionsTest, AccessToDevicesMessages);
126  friend class base::RefCountedThreadSafe<PermissionSet>;
127
128  ~PermissionSet();
129
130  // Adds permissions implied independently of other context.
131  void InitImplicitPermissions();
132
133  // Initializes the effective host permission based on the data in this set.
134  void InitEffectiveHosts();
135
136  // Initializes |has_access_to_most_hosts_|.
137  void InitShouldWarnAllHosts() const;
138
139  // The api list is used when deciding if an extension can access certain
140  // extension APIs and features.
141  APIPermissionSet apis_;
142
143  // The manifest key permission list is used when deciding if an extension
144  // can access certain extension APIs and features.
145  ManifestPermissionSet manifest_permissions_;
146
147  // The list of hosts that can be accessed directly from the extension.
148  // TODO(jstritar): Rename to "hosts_"?
149  URLPatternSet explicit_hosts_;
150
151  // The list of hosts that can be scripted by content scripts.
152  // TODO(jstritar): Rename to "user_script_hosts_"?
153  URLPatternSet scriptable_hosts_;
154
155  // The list of hosts this effectively grants access to.
156  URLPatternSet effective_hosts_;
157
158  enum ShouldWarnAllHostsType {
159    UNINITIALIZED = 0,
160    WARN_ALL_HOSTS,
161    DONT_WARN_ALL_HOSTS
162  };
163  // Whether or not this permission set includes access to so many origins, we
164  // should treat it as all_hosts for warning purposes.
165  // Lazily initialized (and therefore mutable).
166  mutable ShouldWarnAllHostsType should_warn_all_hosts_;
167};
168
169}  // namespace extensions
170
171#endif  // EXTENSIONS_COMMON_PERMISSIONS_PERMISSION_SET_H_
172