| // 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_UPDATER_H__ |
| #define CHROME_BROWSER_EXTENSIONS_PERMISSIONS_UPDATER_H__ |
| |
| #include <memory> |
| |
| #include "base/callback_forward.h" |
| #include "base/memory/raw_ptr.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: |
| // 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); |
| |
| 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. |
| void SetPermissions(const Extension* extension, |
| std::unique_ptr<const PermissionSet> active); |
| |
| // 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`. 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, |
| 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_UPDATER_H__ |