// 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/macros.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;
  };

  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).
  // |delegate| is a singleton instance and is leaked.
  static void SetPlatformDelegate(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);

  // Grants |permissions| that were withheld at installation and granted at
  // runtime to |extension|, updating the active permission set and notifying
  // any observers.
  // NOTE: This should only be used for granting permissions through the runtime
  // host permissions feature.
  void GrantRuntimePermissions(const Extension& extension,
                               const PermissionSet& permissions);

  // 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);

  // 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);

  // 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:
  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,
  };

  // Sets the |extension|'s active permissions to |active| and records the
  // change in the prefs. If |withheld| is non-null, also sets the extension's
  // withheld permissions to |withheld|. Otherwise, |withheld| permissions are
  // not changed.
  void SetPermissions(const Extension* extension,
                      std::unique_ptr<const PermissionSet> active,
                      std::unique_ptr<const PermissionSet> withheld);

  // Dispatches specified event to the extension.
  void DispatchEvent(const std::string& extension_id,
                     events::HistogramValue histogram_value,
                     const char* event_name,
                     const PermissionSet& changed_permissions);

  // 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.
  void NotifyPermissionsUpdated(EventType event_type,
                                const Extension* extension,
                                const PermissionSet& changed);

  // Issues the relevant events, messages and notifications when the
  // default scope management policy have changed.
  // Specifically, this sends the ExtensionMsg_UpdateDefaultHostRestrictions
  // IPC message.
  void NotifyDefaultPolicyHostRestrictionsUpdated(
      const URLPatternSet& default_runtime_blocked_hosts,
      const URLPatternSet& default_runtime_allowed_hosts);

  // Adds the given |permissions| to |extension|. Updates the preferences
  // according to |permission_store_mask|.
  void AddPermissionsImpl(const Extension& extension,
                          const PermissionSet& permissions,
                          int permission_store_mask);

  // Removes the given |permissions| to |extension|. Updates the preferences
  // according to |permission_store_mask|.
  void RemovePermissionsImpl(const Extension& extension,
                             const PermissionSet& permissions,
                             int permission_store_mask);

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