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
|
// Copyright 2012 The Chromium Authors
// 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_PERMISSIONS_UPDATER_H_
#define CHROME_BROWSER_EXTENSIONS_PERMISSIONS_PERMISSIONS_UPDATER_H_
#include <memory>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "extensions/browser/extension_event_histogram_value.h"
#include "extensions/buildflags/buildflags.h"
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
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:
// 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(const PermissionsUpdater&) = delete;
PermissionsUpdater& operator=(const PermissionsUpdater&) = delete;
~PermissionsUpdater();
// 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 blocklisted by management.
void RemovePermissionsUnsafe(const Extension* extension,
const PermissionSet& permissions);
// Fetches the policy settings from the ExtensionManagement service and
// applies them to the extension.
void ApplyPolicyHostRestrictions(const Extension& extension);
// 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);
static void EnsureAssociatedFactoryBuilt();
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 UpdatePermissions Mojo 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);
// Issues the relevant events, messages and notifications when the default
// scope management policy have changed.
// Specifically, this sends the UpdateDefaultHostRestrictions Mojo message.
static void NotifyDefaultPolicyHostRestrictionsUpdated(
content::BrowserContext* browser_context,
const URLPatternSet default_runtime_blocked_hosts,
const URLPatternSet default_runtime_allowed_hosts);
// Sets the `extension`'s active permissions to `active`, and calculates and
// sets the `extension`'s new withheld permissions. This also calculates the
// set of permissions to be withheld on the extension.
void SetPermissions(const Extension* extension,
std::unique_ptr<const PermissionSet> active,
bool withhold_optional_permissions);
// 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 `permissions_to_add_to_prefs`.
// The sets of `permissions_to_add_to_prefs` 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 prefs_permissions_store_mask,
const PermissionSet& permissions_to_add_to_prefs,
base::OnceClosure completion_callback);
// Sets the given `extension`'s active permissions to the specified
// `new_active_permissions`. Also removes `permissions_to_remove_from_prefs`
// from the preferences indicated by `prefs_permissions_store_mask`. It also
// allows withholding optional permissions if `withhold_optional_permissions`
// is set to true. Invokes `completion_callback` when done.
void RemovePermissionsImpl(
const Extension& extension,
std::unique_ptr<const PermissionSet> new_active_permissions,
const PermissionSet& permissions_to_remove_from_prefs,
int prefs_permissions_store_mask,
bool withhold_optional_permissions,
base::OnceClosure completion_callback);
// The associated BrowserContext.
raw_ptr<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_;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_PERMISSIONS_PERMISSIONS_UPDATER_H_
|