| // 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__ |