// Copyright 2014 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 "extensions/common/manifest_handlers/permissions_parser.h"

#include "base/command_line.h"
#include "base/memory/ref_counted.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/public/common/url_constants.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handler.h"
#include "extensions/common/permissions/api_permission_set.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/switches.h"
#include "extensions/common/url_pattern_set.h"
#include "url/url_constants.h"

namespace extensions {

namespace {

namespace keys = manifest_keys;
namespace errors = manifest_errors;

struct ManifestPermissions : public Extension::ManifestData {
  ManifestPermissions(scoped_refptr<const PermissionSet> permissions);
  virtual ~ManifestPermissions();

  scoped_refptr<const PermissionSet> permissions;
};

ManifestPermissions::ManifestPermissions(
    scoped_refptr<const PermissionSet> permissions)
    : permissions(permissions) {
}

ManifestPermissions::~ManifestPermissions() {
}

// Custom checks for the experimental permission that can't be expressed in
// _permission_features.json.
bool CanSpecifyExperimentalPermission(const Extension* extension) {
  if (extension->location() == Manifest::COMPONENT)
    return true;

  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableExperimentalExtensionApis)) {
    return true;
  }

  // We rely on the webstore to check access to experimental. This way we can
  // whitelist extensions to have access to experimental in just the store, and
  // not have to push a new version of the client.
  if (extension->from_webstore())
    return true;

  return false;
}

// Checks whether the host |pattern| is allowed for the given |extension|,
// given API permissions |permissions|.
bool CanSpecifyHostPermission(const Extension* extension,
                              const URLPattern& pattern,
                              const APIPermissionSet& permissions) {
  if (!pattern.match_all_urls() &&
      pattern.MatchesScheme(content::kChromeUIScheme)) {
    URLPatternSet chrome_scheme_hosts =
        ExtensionsClient::Get()->GetPermittedChromeSchemeHosts(extension,
                                                               permissions);
    if (chrome_scheme_hosts.ContainsPattern(pattern))
      return true;

    // Component extensions can have access to all of chrome://*.
    if (PermissionsData::CanExecuteScriptEverywhere(extension))
      return true;

    if (CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kExtensionsOnChromeURLs)) {
      return true;
    }

    // TODO(aboxhall): return from_webstore() when webstore handles blocking
    // extensions which request chrome:// urls
    return false;
  }

  // Otherwise, the valid schemes were handled by URLPattern.
  return true;
}

// Parses the host and api permissions from the specified permission |key|
// from |extension|'s manifest.
bool ParseHelper(Extension* extension,
                 const char* key,
                 APIPermissionSet* api_permissions,
                 URLPatternSet* host_permissions,
                 base::string16* error) {
  if (!extension->manifest()->HasKey(key))
    return true;

  const base::ListValue* permissions = NULL;
  if (!extension->manifest()->GetList(key, &permissions)) {
    *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidPermissions,
                                                 std::string());
    return false;
  }

  // NOTE: We need to get the APIPermission before we check if features
  // associated with them are available because the feature system does not
  // know about aliases.

  std::vector<std::string> host_data;
  if (!APIPermissionSet::ParseFromJSON(
          permissions,
          APIPermissionSet::kDisallowInternalPermissions,
          api_permissions,
          error,
          &host_data)) {
    return false;
  }

  // Verify feature availability of permissions.
  std::vector<APIPermission::ID> to_remove;
  const FeatureProvider* permission_features =
      FeatureProvider::GetPermissionFeatures();
  for (APIPermissionSet::const_iterator iter = api_permissions->begin();
       iter != api_permissions->end();
       ++iter) {
    Feature* feature = permission_features->GetFeature(iter->name());

    // The feature should exist since we just got an APIPermission for it. The
    // two systems should be updated together whenever a permission is added.
    DCHECK(feature) << "Could not find feature for " << iter->name();
    // http://crbug.com/176381
    if (!feature) {
      to_remove.push_back(iter->id());
      continue;
    }

    Feature::Availability availability =
        feature->IsAvailableToExtension(extension);
    if (!availability.is_available()) {
      // Don't fail, but warn the developer that the manifest contains
      // unrecognized permissions. This may happen legitimately if the
      // extensions requests platform- or channel-specific permissions.
      extension->AddInstallWarning(
          InstallWarning(availability.message(), feature->name()));
      to_remove.push_back(iter->id());
      continue;
    }

    if (iter->id() == APIPermission::kExperimental) {
      if (!CanSpecifyExperimentalPermission(extension)) {
        *error = base::ASCIIToUTF16(errors::kExperimentalFlagRequired);
        return false;
      }
    }
  }

  api_permissions->AddImpliedPermissions();

  // Remove permissions that are not available to this extension.
  for (std::vector<APIPermission::ID>::const_iterator iter = to_remove.begin();
       iter != to_remove.end();
       ++iter) {
    api_permissions->erase(*iter);
  }

  // Parse host pattern permissions.
  const int kAllowedSchemes =
      PermissionsData::CanExecuteScriptEverywhere(extension)
          ? URLPattern::SCHEME_ALL
          : Extension::kValidHostPermissionSchemes;

  for (std::vector<std::string>::const_iterator iter = host_data.begin();
       iter != host_data.end();
       ++iter) {
    const std::string& permission_str = *iter;

    // Check if it's a host pattern permission.
    URLPattern pattern = URLPattern(kAllowedSchemes);
    URLPattern::ParseResult parse_result = pattern.Parse(permission_str);
    if (parse_result == URLPattern::PARSE_SUCCESS) {
      // The path component is not used for host permissions, so we force it
      // to match all paths.
      pattern.SetPath("/*");
      int valid_schemes = pattern.valid_schemes();
      if (pattern.MatchesScheme(url::kFileScheme) &&
          !PermissionsData::CanExecuteScriptEverywhere(extension)) {
        extension->set_wants_file_access(true);
        if (!(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS))
          valid_schemes &= ~URLPattern::SCHEME_FILE;
      }

      if (pattern.scheme() != content::kChromeUIScheme &&
          !PermissionsData::CanExecuteScriptEverywhere(extension)) {
        // Keep chrome:// in allowed schemes only if it's explicitly requested
        // or CanExecuteScriptEverywhere is true. If the
        // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission
        // will fail, so don't check the flag here.
        valid_schemes &= ~URLPattern::SCHEME_CHROMEUI;
      }
      pattern.SetValidSchemes(valid_schemes);

      if (!CanSpecifyHostPermission(extension, pattern, *api_permissions)) {
        // TODO(aboxhall): make a warning (see pattern.match_all_urls() block
        // below).
        extension->AddInstallWarning(InstallWarning(
            ErrorUtils::FormatErrorMessage(errors::kInvalidPermissionScheme,
                                           permission_str),
            key,
            permission_str));
        continue;
      }

      host_permissions->AddPattern(pattern);
      // We need to make sure all_urls matches chrome://favicon and (maybe)
      // chrome://thumbnail, so add them back in to host_permissions separately.
      if (pattern.match_all_urls()) {
        host_permissions->AddPatterns(
            ExtensionsClient::Get()->GetPermittedChromeSchemeHosts(
                extension, *api_permissions));
      }
      continue;
    }

    // It's probably an unknown API permission. Do not throw an error so
    // extensions can retain backwards compatability (http://crbug.com/42742).
    extension->AddInstallWarning(InstallWarning(
        ErrorUtils::FormatErrorMessage(
            manifest_errors::kPermissionUnknownOrMalformed, permission_str),
        key,
        permission_str));
  }

  return true;
}

}  // namespace

struct PermissionsParser::InitialPermissions {
  APIPermissionSet api_permissions;
  ManifestPermissionSet manifest_permissions;
  URLPatternSet host_permissions;
  URLPatternSet scriptable_hosts;
};

PermissionsParser::PermissionsParser() {
}

PermissionsParser::~PermissionsParser() {
}

bool PermissionsParser::Parse(Extension* extension, base::string16* error) {
  initial_required_permissions_.reset(new InitialPermissions);
  if (!ParseHelper(extension,
                   keys::kPermissions,
                   &initial_required_permissions_->api_permissions,
                   &initial_required_permissions_->host_permissions,
                   error)) {
    return false;
  }

  initial_optional_permissions_.reset(new InitialPermissions);
  if (!ParseHelper(extension,
                   keys::kOptionalPermissions,
                   &initial_optional_permissions_->api_permissions,
                   &initial_optional_permissions_->host_permissions,
                   error)) {
    return false;
  }

  return true;
}

void PermissionsParser::Finalize(Extension* extension) {
  ManifestHandler::AddExtensionInitialRequiredPermissions(
      extension, &initial_required_permissions_->manifest_permissions);

  scoped_refptr<const PermissionSet> required_permissions(
      new PermissionSet(initial_required_permissions_->api_permissions,
                        initial_required_permissions_->manifest_permissions,
                        initial_required_permissions_->host_permissions,
                        initial_required_permissions_->scriptable_hosts));
  extension->SetManifestData(keys::kPermissions,
                             new ManifestPermissions(required_permissions));

  scoped_refptr<const PermissionSet> optional_permissions(
      new PermissionSet(initial_optional_permissions_->api_permissions,
                        initial_optional_permissions_->manifest_permissions,
                        initial_optional_permissions_->host_permissions,
                        URLPatternSet()));
  extension->SetManifestData(keys::kOptionalPermissions,
                             new ManifestPermissions(optional_permissions));
}

// static
void PermissionsParser::AddAPIPermission(Extension* extension,
                                         APIPermission::ID permission) {
  DCHECK(extension->permissions_parser());
  extension->permissions_parser()
      ->initial_required_permissions_->api_permissions.insert(permission);
}

// static
void PermissionsParser::AddAPIPermission(Extension* extension,
                                         APIPermission* permission) {
  DCHECK(extension->permissions_parser());
  extension->permissions_parser()
      ->initial_required_permissions_->api_permissions.insert(permission);
}

// static
bool PermissionsParser::HasAPIPermission(const Extension* extension,
                                         APIPermission::ID permission) {
  DCHECK(extension->permissions_parser());
  return extension->permissions_parser()
             ->initial_required_permissions_->api_permissions.count(
                 permission) > 0;
}

// static
void PermissionsParser::SetScriptableHosts(
    Extension* extension,
    const URLPatternSet& scriptable_hosts) {
  DCHECK(extension->permissions_parser());
  extension->permissions_parser()
      ->initial_required_permissions_->scriptable_hosts = scriptable_hosts;
}

// static
scoped_refptr<const PermissionSet> PermissionsParser::GetRequiredPermissions(
    const Extension* extension) {
  DCHECK(extension->GetManifestData(keys::kPermissions));
  return static_cast<const ManifestPermissions*>(
             extension->GetManifestData(keys::kPermissions))->permissions;
}

// static
scoped_refptr<const PermissionSet> PermissionsParser::GetOptionalPermissions(
    const Extension* extension) {
  DCHECK(extension->GetManifestData(keys::kOptionalPermissions));
  return static_cast<const ManifestPermissions*>(
             extension->GetManifestData(keys::kOptionalPermissions))
      ->permissions;
}

}  // namespace extensions
