blob: aaaa09f26f6a174624ef0b5c44b39f03b5ec5f3e [file] [log] [blame]
// 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);
// Issues the relevant events, messages and notifications when the default
// scope management policy have changed.
// Specifically, this sends the ExtensionMsg_UpdateDefaultHostRestrictions
// IPC 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. 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);
// 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__