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 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
|
// 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_BROWSER_EXTENSIONS_PERMISSIONS_UPDATER_H__
#define CHROME_BROWSER_EXTENSIONS_PERMISSIONS_UPDATER_H__
#include <memory>
#include <string>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "extensions/browser/extension_event_histogram_value.h"
namespace content {
class BrowserContext;
}
namespace extensions {
class Extension;
class PermissionSet;
class URLPatternSet;
// Updates an Extension's active and granted permissions in persistent storage
// and notifies interested parties of the changes.
class PermissionsUpdater {
public:
// Platform specific delegate.
class Delegate {
public:
virtual ~Delegate() {}
// Platform specific initialization of |extension|'s permissions (does any
// necessary filtering of permissions or similar).
virtual void InitializePermissions(
const Extension* extension,
std::unique_ptr<const PermissionSet>* granted_permissions) = 0;
};
// If INIT_FLAG_TRANSIENT is specified, this updater is being used for an
// extension that is not actually installed (and instead is just being
// initialized e.g. to display the permission warnings in an install prompt).
// In these cases, this updater should follow all rules below.
// a) don't check prefs for stored permissions.
// b) don't send notifications of permission changes, because there is no
// installed extension that would be affected.
enum InitFlag {
INIT_FLAG_NONE = 0,
INIT_FLAG_TRANSIENT = 1 << 0,
};
enum RemoveType {
// Permissions will be removed from the active set of permissions, but not
// the stored granted permissions. This allows the extension to re-add the
// permissions without further prompting.
REMOVE_SOFT,
// Permissions will be removed from the active set of permissions and the
// stored granted permissions. The extension will need to re-prompt the
// user to re-add the permissions.
// TODO(devlin): REMOVE_HARD is only exercised in unit tests, but we have
// the desire to be able to able to surface revoking optional permissions to
// the user. We should either a) pursue it in earnest or b) remove support
// (and potentially add it back at a later date).
REMOVE_HARD,
};
explicit PermissionsUpdater(content::BrowserContext* browser_context);
PermissionsUpdater(content::BrowserContext* browser_context,
InitFlag init_flag);
~PermissionsUpdater();
// Sets a delegate to provide platform-specific logic. This should be set
// during startup (to ensure all extensions are initialized through the
// delegate).
static void SetPlatformDelegate(std::unique_ptr<Delegate> delegate);
// Grants |permissions| that were defined as optional in the manifest to
// |extension|, updating the active permission set and notifying any
// observers. This method assumes the user has already been prompted, if
// necessary, for the extra permissions.
// NOTE: This should only be used for granting permissions defined in the
// extension's optional permissions set through the permissions API.
void GrantOptionalPermissions(const Extension& extension,
const PermissionSet& permissions,
base::OnceClosure completion_callback);
// Grants |permissions| that were withheld at installation and granted at
// runtime to |extension|, updating the active permission set and notifying
// any observers. |permissions| may contain permissions that were not
// explicitly requested by the extension; if this happens, those permissions
// will be added to the runtime-granted permissions in the preferences, but
// will not be granted to the extension object or process itself.
// NOTE: This should only be used for granting permissions through the runtime
// host permissions feature.
void GrantRuntimePermissions(const Extension& extension,
const PermissionSet& permissions,
base::OnceClosure completion_callback);
// Removes |permissions| that were defined as optional in the manifest from
// the |extension|, updating the active permission set and notifying any
// observers. |remove_type| specifies whether the permissions should be
// revoked from the preferences, thus requiring the extension to re-prompt
// the user if it wants to add them back.
// NOTE: This should only be used for removing permissions defined in the
// extension's optional permissions set through the permissions API.
void RevokeOptionalPermissions(const Extension& extension,
const PermissionSet& permissions,
RemoveType remove_type,
base::OnceClosure completion_callback);
// Removes |permissions| that were withheld at installation and granted at
// runtime from |extension|, updating the active permission set and notifying
// any observers.
// NOTE: This should only be used for removing permissions through the runtime
// host permissions feature.
void RevokeRuntimePermissions(const Extension& extension,
const PermissionSet& permissions,
base::OnceClosure completion_callback);
// Removes the |permissions| from |extension| and makes no effort to determine
// if doing so is safe in the slightlest. This method shouldn't be used,
// except for removing permissions totally blacklisted by management.
void RemovePermissionsUnsafe(const Extension* extension,
const PermissionSet& permissions);
// Sets list of hosts |extension| may not interact with (overrides default).
void SetPolicyHostRestrictions(const Extension* extension,
const URLPatternSet& runtime_blocked_hosts,
const URLPatternSet& runtime_allowed_hosts);
// Sets extension to use the default list of policy host restrictions.
void SetUsesDefaultHostRestrictions(const Extension* extension);
// Sets list of hosts extensions may not interact with. Extension specific
// exceptions to this default policy are defined with
// SetPolicyHostRestrictions.
void SetDefaultPolicyHostRestrictions(
const URLPatternSet& default_runtime_blocked_hosts,
const URLPatternSet& default_runtime_allowed_hosts);
// Returns the set of revokable permissions.
std::unique_ptr<const PermissionSet> GetRevokablePermissions(
const Extension* extension) const;
// Adds all permissions in the |extension|'s active permissions to its
// granted permission set.
void GrantActivePermissions(const Extension* extension);
// Initializes the |extension|'s active permission set to include only
// permissions currently requested by the extension and all the permissions
// required by the extension.
void InitializePermissions(const Extension* extension);
// Adds |permissions| to |extension| without doing any validation or
// persisting values in prefs.
// TODO(devlin): We shouldn't need this, even for tests. Tests shouldn't be
// testing behavior that is impossible in production.
void AddPermissionsForTesting(const Extension& extension,
const PermissionSet& permissions);
private:
class NetworkPermissionsUpdateHelper;
enum EventType {
ADDED,
REMOVED,
POLICY,
};
// A bit mask of the permission set to be updated in ExtensionPrefs.
enum PermissionsStore {
kNone = 0,
kGrantedPermissions = 1 << 0,
kRuntimeGrantedPermissions = 1 << 1,
kActivePermissions = 1 << 2,
};
// Issues the relevant events, messages and notifications when the
// |extension|'s permissions have |changed| (|changed| is the delta).
// Specifically, this sends the EXTENSION_PERMISSIONS_UPDATED notification,
// the ExtensionMsg_UpdatePermissions IPC message, and fires the
// onAdded/onRemoved events in the extension.
static void NotifyPermissionsUpdated(
content::BrowserContext* browser_context,
EventType event_type,
scoped_refptr<const Extension> extension,
std::unique_ptr<const PermissionSet> changed,
base::OnceClosure completion_callback);
// Sets the |extension|'s active permissions to |active|, and calculates and
// sets the |extension|'s new withheld permissions. If |update_prefs| is true,
// also updates the set of active permissions in the extension preferences.
void SetPermissions(const Extension* extension,
std::unique_ptr<const PermissionSet> active,
bool update_prefs);
// Issues the relevant events, messages and notifications when the
// default scope management policy have changed.
// Specifically, this sends the ExtensionMsg_UpdateDefaultHostRestrictions
// IPC message.
void NotifyDefaultPolicyHostRestrictionsUpdated(
const URLPatternSet& default_runtime_blocked_hosts,
const URLPatternSet& default_runtime_allowed_hosts);
// Adds the given |active_permissions_to_add| to |extension|'s current
// active permissions (i.e., the permissions associated with the |extension|
// object and the extension's process). Updates the preferences according to
// |permission_store_mask| with |prefs_permissions_to_add|.
// The sets of |prefs_permissions_to_add| and |active_permissions_to_add| may
// differ in the case of granting a wider set of permissions than what the
// extension explicitly requested, as described in GrantRuntimePermissions().
void AddPermissionsImpl(const Extension& extension,
const PermissionSet& active_permissions_to_add,
int permission_store_mask,
const PermissionSet& prefs_permissions_to_add,
base::OnceClosure completion_callback);
// Removes the given |active_permissions_to_remove| from |extension|'s current
// active permissions. Updates the preferences according to
// |permission_store_mask| with |prefs_permissions_to_remove|. As above, the
// permission sets may be different.
void RemovePermissionsImpl(const Extension& extension,
const PermissionSet& active_permissions_to_remove,
int permission_store_mask,
const PermissionSet& prefs_permissions_to_remove,
base::OnceClosure completion_callback);
// The associated BrowserContext.
content::BrowserContext* browser_context_;
// Initialization flag that determines whether prefs is consulted about the
// extension. Transient extensions should not have entries in prefs.
InitFlag init_flag_;
DISALLOW_COPY_AND_ASSIGN(PermissionsUpdater);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_PERMISSIONS_UPDATER_H__
|