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

#include "chrome/browser/extensions/api/permissions/permissions_api.h"

#include <memory>

#include "base/memory/ptr_util.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
#include "chrome/browser/extensions/extension_management.h"
#include "chrome/browser/extensions/permissions_updater.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/permissions.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/permissions_parser.h"
#include "extensions/common/permissions/permission_message_provider.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/permissions/permissions_info.h"

namespace extensions {

using api::permissions::Permissions;

namespace Contains = api::permissions::Contains;
namespace GetAll = api::permissions::GetAll;
namespace Remove = api::permissions::Remove;
namespace Request  = api::permissions::Request;
namespace helpers = permissions_api_helpers;

namespace {

const char kBlockedByEnterprisePolicy[] =
    "Permissions are blocked by enterprise policy.";
const char kCantRemoveRequiredPermissionsError[] =
    "You cannot remove required permissions.";
const char kNotInOptionalPermissionsError[] =
    "Optional permissions must be listed in extension manifest.";
const char kNotWhitelistedError[] =
    "The optional permissions API does not support '*'.";
const char kUserGestureRequiredError[] =
    "This function must be called during a user gesture";

enum AutoConfirmForTest {
  DO_NOT_SKIP = 0,
  PROCEED,
  ABORT
};
AutoConfirmForTest auto_confirm_for_tests = DO_NOT_SKIP;
bool ignore_user_gesture_for_tests = false;

}  // namespace

ExtensionFunction::ResponseAction PermissionsContainsFunction::Run() {
  std::unique_ptr<Contains::Params> params(Contains::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  // NOTE: |permissions| is not used to make any security decisions. Therefore,
  // it is entirely fine to set |allow_file_access| to true below. This will
  // avoid throwing error when extension() doesn't have access to file://.
  std::string error;
  std::unique_ptr<const PermissionSet> permissions =
      helpers::UnpackPermissionSet(params->permissions,
                                   true /* allow_file_access */, &error);
  if (!permissions.get())
    return RespondNow(Error(error));

  return RespondNow(ArgumentList(Contains::Results::Create(
      extension()->permissions_data()->active_permissions().Contains(
          *permissions))));
}

ExtensionFunction::ResponseAction PermissionsGetAllFunction::Run() {
  std::unique_ptr<Permissions> permissions = helpers::PackPermissionSet(
      extension()->permissions_data()->active_permissions());
  return RespondNow(ArgumentList(GetAll::Results::Create(*permissions)));
}

ExtensionFunction::ResponseAction PermissionsRemoveFunction::Run() {
  std::unique_ptr<Remove::Params> params(Remove::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  std::string error;
  std::unique_ptr<const PermissionSet> permissions =
      helpers::UnpackPermissionSet(params->permissions,
                                   ExtensionPrefs::Get(browser_context())
                                       ->AllowFileAccess(extension_->id()),
                                   &error);

  if (!permissions.get())
    return RespondNow(Error(error));

  // Make sure they're only trying to remove permissions supported by this API.
  APIPermissionSet apis = permissions->apis();
  for (const APIPermission* permission : apis) {
    if (!permission->info()->supports_optional())
      return RespondNow(Error(kNotWhitelistedError, permission->name()));
  }

  // Make sure we only remove optional permissions, and not required
  // permissions. Sadly, for some reason we support having a permission be both
  // optional and required (and should assume its required), so we need both of
  // these checks.
  // TODO(devlin): *Why* do we support that? Should be a load error.
  const PermissionSet& optional =
      PermissionsParser::GetOptionalPermissions(extension());
  const PermissionSet& required =
      PermissionsParser::GetRequiredPermissions(extension());
  if (!optional.Contains(*permissions) ||
      !std::unique_ptr<const PermissionSet>(
           PermissionSet::CreateIntersection(*permissions, required))
           ->IsEmpty()) {
    return RespondNow(Error(kCantRemoveRequiredPermissionsError));
  }

  // Only try and remove those permissions that are active on the extension.
  // For backwards compatability with behavior before this check was added, just
  // silently remove any that aren't present.
  permissions = PermissionSet::CreateIntersection(
      *permissions, extension()->permissions_data()->active_permissions());

  PermissionsUpdater(browser_context())
      .RemovePermissions(extension(), *permissions,
                         PermissionsUpdater::REMOVE_SOFT);
  return RespondNow(ArgumentList(Remove::Results::Create(true)));
}

// static
void PermissionsRequestFunction::SetAutoConfirmForTests(bool should_proceed) {
  auto_confirm_for_tests = should_proceed ? PROCEED : ABORT;
}

// static
void PermissionsRequestFunction::SetIgnoreUserGestureForTests(
    bool ignore) {
  ignore_user_gesture_for_tests = ignore;
}

PermissionsRequestFunction::PermissionsRequestFunction() {}

PermissionsRequestFunction::~PermissionsRequestFunction() {}

bool PermissionsRequestFunction::RunAsync() {
  results_ = Request::Results::Create(false);

  if (!user_gesture() &&
      !ignore_user_gesture_for_tests &&
      extension_->location() != Manifest::COMPONENT) {
    error_ = kUserGestureRequiredError;
    return false;
  }

  std::unique_ptr<Request::Params> params(Request::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  requested_permissions_ = helpers::UnpackPermissionSet(
      params->permissions,
      ExtensionPrefs::Get(GetProfile())->AllowFileAccess(extension_->id()),
      &error_);
  if (!requested_permissions_.get())
    return false;

  // Make sure they're only requesting permissions supported by this API.
  APIPermissionSet apis = requested_permissions_->apis();
  for (APIPermissionSet::const_iterator i = apis.begin();
       i != apis.end(); ++i) {
    if (!i->info()->supports_optional()) {
      error_ = ErrorUtils::FormatErrorMessage(
          kNotWhitelistedError, i->name());
      return false;
    }
  }

  // The requested permissions must be defined as optional in the manifest.
  if (!PermissionsParser::GetOptionalPermissions(extension())
           .Contains(*requested_permissions_)) {
    error_ = kNotInOptionalPermissionsError;
    return false;
  }

  // Automatically declines api permissions requests, which are blocked by
  // enterprise policy.
  if (!ExtensionManagementFactory::GetForBrowserContext(GetProfile())
           ->IsPermissionSetAllowed(extension(), *requested_permissions_)) {
    error_ = kBlockedByEnterprisePolicy;
    return false;
  }

  // We don't need to prompt the user if the requested permissions are a subset
  // of the granted permissions set.
  std::unique_ptr<const PermissionSet> granted =
      ExtensionPrefs::Get(GetProfile())
          ->GetGrantedPermissions(extension()->id());
  if (granted.get() && granted->Contains(*requested_permissions_)) {
    PermissionsUpdater perms_updater(GetProfile());
    perms_updater.AddPermissions(extension(), *requested_permissions_);
    results_ = Request::Results::Create(true);
    SendResponse(true);
    return true;
  }

  // Filter out the granted permissions so we only prompt for new ones.
  requested_permissions_ =
      PermissionSet::CreateDifference(*requested_permissions_, *granted);

  // Filter out the active permissions.
  requested_permissions_ = PermissionSet::CreateDifference(
      *requested_permissions_,
      extension()->permissions_data()->active_permissions());

  AddRef();  // Balanced in OnInstallPromptDone().

  // We don't need to show the prompt if there are no new warnings, or if
  // we're skipping the confirmation UI. All extension types but INTERNAL
  // are allowed to silently increase their permission level.
  const PermissionMessageProvider* message_provider =
      PermissionMessageProvider::Get();
  bool has_no_warnings =
      message_provider->GetPermissionMessages(
                          message_provider->GetAllPermissionIDs(
                              *requested_permissions_, extension()->GetType()))
          .empty();
  if (auto_confirm_for_tests == PROCEED || has_no_warnings ||
      extension_->location() == Manifest::COMPONENT) {
    OnInstallPromptDone(ExtensionInstallPrompt::Result::ACCEPTED);
  } else if (auto_confirm_for_tests == ABORT) {
    // Pretend the user clicked cancel.
    OnInstallPromptDone(ExtensionInstallPrompt::Result::USER_CANCELED);
  } else {
    CHECK_EQ(DO_NOT_SKIP, auto_confirm_for_tests);
    install_ui_.reset(new ExtensionInstallPrompt(GetAssociatedWebContents()));
    install_ui_->ShowDialog(
        base::Bind(&PermissionsRequestFunction::OnInstallPromptDone, this),
        extension(), nullptr, base::MakeUnique<ExtensionInstallPrompt::Prompt>(
                                  ExtensionInstallPrompt::PERMISSIONS_PROMPT),
        requested_permissions_->Clone(),
        ExtensionInstallPrompt::GetDefaultShowDialogCallback());
  }

  return true;
}

void PermissionsRequestFunction::OnInstallPromptDone(
    ExtensionInstallPrompt::Result result) {
  if (result == ExtensionInstallPrompt::Result::ACCEPTED) {
    PermissionsUpdater perms_updater(GetProfile());
    perms_updater.AddPermissions(extension(), *requested_permissions_);

    results_ = Request::Results::Create(true);
  }

  SendResponse(true);
  Release();  // Balanced in RunAsync().
}

}  // namespace extensions
