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