// Copyright 2017 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 "content/common/content_security_policy/csp_context.h"
#include "content/public/common/origin_util.h"

namespace content {

namespace {

// Helper function that returns true if |policy| should be checked under
// |check_csp_disposition|.
bool ShouldCheckPolicy(const ContentSecurityPolicy& policy,
                       CSPContext::CheckCSPDisposition check_csp_disposition) {
  switch (check_csp_disposition) {
    case CSPContext::CHECK_REPORT_ONLY_CSP:
      return policy.header.type == blink::kWebContentSecurityPolicyTypeReport;
    case CSPContext::CHECK_ENFORCED_CSP:
      return policy.header.type == blink::kWebContentSecurityPolicyTypeEnforce;
    case CSPContext::CHECK_ALL_CSP:
      return true;
  }
  NOTREACHED();
  return true;
}

}  // namespace

CSPContext::CSPContext() {}
CSPContext::~CSPContext() {}

bool CSPContext::IsAllowedByCsp(CSPDirective::Name directive_name,
                                const GURL& url,
                                bool has_followed_redirect,
                                bool is_response_check,
                                const SourceLocation& source_location,
                                CheckCSPDisposition check_csp_disposition,
                                bool is_form_submission) {
  if (SchemeShouldBypassCSP(url.scheme_piece()))
    return true;

  bool allow = true;
  for (const auto& policy : policies_) {
    if (ShouldCheckPolicy(policy, check_csp_disposition)) {
      allow &= ContentSecurityPolicy::Allow(
          policy, directive_name, url, has_followed_redirect, is_response_check,
          this, source_location, is_form_submission);
    }
  }

  DCHECK(allow || check_csp_disposition != CSPContext::CHECK_REPORT_ONLY_CSP);

  return allow;
}

bool CSPContext::ShouldModifyRequestUrlForCsp(
    bool is_subresource_or_form_submission) {
  for (const auto& policy : policies_) {
    if (ContentSecurityPolicy::ShouldUpgradeInsecureRequest(policy) &&
        is_subresource_or_form_submission) {
      return true;
    }
  }
  return false;
}

void CSPContext::ModifyRequestUrlForCsp(GURL* url) {
  if (url->SchemeIs(url::kHttpScheme) && !IsOriginSecure(*url)) {
    // Updating the URL's scheme also implicitly updates the URL's port from 80
    // to 443 if needed.
    GURL::Replacements replacements;
    replacements.SetSchemeStr(url::kHttpsScheme);
    *url = url->ReplaceComponents(replacements);
  }
}

void CSPContext::SetSelf(const url::Origin origin) {
  self_source_.reset();

  // When the origin is unique, no URL should match with 'self'. That's why
  // |self_source_| stays undefined here.
  if (origin.opaque())
    return;

  if (origin.scheme() == url::kFileScheme) {
    self_source_ = CSPSource(url::kFileScheme, "", false, url::PORT_UNSPECIFIED,
                             false, "");
    return;
  }

  self_source_ = CSPSource(
      origin.scheme(), origin.host(), false,
      origin.port() == 0 ? url::PORT_UNSPECIFIED : origin.port(), false, "");

  DCHECK_NE("", self_source_->scheme);
}

void CSPContext::SetSelf(const CSPSource& self_source) {
  self_source_ = self_source;
}

bool CSPContext::SchemeShouldBypassCSP(const base::StringPiece& scheme) {
  return false;
}

void CSPContext::SanitizeDataForUseInCspViolation(
    bool has_followed_redirect,
    CSPDirective::Name directive,
    GURL* blocked_url,
    SourceLocation* source_location) const {
  return;
}

void CSPContext::ReportContentSecurityPolicyViolation(
    const CSPViolationParams& violation_params) {
  return;
}

CSPViolationParams::CSPViolationParams() = default;

CSPViolationParams::CSPViolationParams(
    const std::string& directive,
    const std::string& effective_directive,
    const std::string& console_message,
    const GURL& blocked_url,
    const std::vector<std::string>& report_endpoints,
    bool use_reporting_api,
    const std::string& header,
    const blink::WebContentSecurityPolicyType& disposition,
    bool after_redirect,
    const SourceLocation& source_location)
    : directive(directive),
      effective_directive(effective_directive),
      console_message(console_message),
      blocked_url(blocked_url),
      report_endpoints(report_endpoints),
      use_reporting_api(use_reporting_api),
      header(header),
      disposition(disposition),
      after_redirect(after_redirect),
      source_location(source_location) {}

CSPViolationParams::CSPViolationParams(const CSPViolationParams& other) =
    default;
CSPViolationParams::~CSPViolationParams() {}

}  // namespace content
