// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/web/csp_delegate.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "url/gurl.h"

namespace cobalt {
namespace web {

CspDelegate::CspDelegate() {}
CspDelegate::~CspDelegate() {}

CspDelegateSecure::CspDelegateSecure(
    std::unique_ptr<CspViolationReporter> violation_reporter, const GURL& url,
    csp::CSPHeaderPolicy csp_header_policy,
    const base::Closure& policy_changed_callback) {
  csp_header_policy_ = csp_header_policy;
  was_header_received_ = false;
  policy_changed_callback_ = policy_changed_callback;

  reporter_ = std::move(violation_reporter);
  csp::ViolationCallback violation_callback;
  if (reporter_) {
    violation_callback = base::Bind(&CspViolationReporter::Report,
                                    base::Unretained(reporter_.get()));
  }
  csp_.reset(new csp::ContentSecurityPolicy(url, violation_callback));
}

CspDelegateSecure::~CspDelegateSecure() {}

void CspDelegateSecure::ClonePolicyContainer(
    const csp::ContentSecurityPolicy& other) {
  // https://html.spec.whatwg.org/commit-snapshots/814668ef2d1919a2a9387a0b29ebc6df7748fa80/#clone-a-policy-container
  // To clone a policy container given a policy container policyContainer:
  // 1. Let clone be a new policy container.
  //   We already have csp_ initialized in the constructor.
  // 2. For each policy in policyContainer's CSP list, append a copy of policy
  // into clone's CSP list.
  for (const auto& directive_list : other.policies()) {
    DCHECK(directive_list);
    csp_->append_policy(*directive_list);
  }
  // 3. Set clone's embedder policy to a copy of policyContainer's embedder
  // policy.
  //   Cobalt doesn't currently store embedder policy.
  // 4. Set clone's referrer policy to policyContainer's referrer policy.
  csp_->set_referrer_policy(csp_->referrer_policy());
}

bool CspDelegateSecure::CanLoad(ResourceType type, const GURL& url,
                                bool did_redirect) const {
  const csp::RedirectStatus redirect_status =
      did_redirect ? csp::kDidRedirect : csp::kDidNotRedirect;

  // Special case for "offline" mode- in the absence of any server policy,
  // we check our default navigation policy, to permit navigation to
  // and from the main site and error pages, and disallow everything else.
  if (!was_header_received_) {
    bool should_allow = false;
    if (type == kLocation) {
      should_allow = csp_->AllowNavigateToSource(url, redirect_status);
    }
    if (csp_header_policy_ == csp::kCSPRequired || should_allow) {
      return should_allow;
    } else {
      DLOG(WARNING) << "Page must include Content-Security-Policy header, it "
                       "will fail to load in production builds of Cobalt!";
    }
  }

  bool can_load = false;
  switch (type) {
    case kFont:
      can_load = csp_->AllowFontFromSource(url, redirect_status);
      break;
    case kImage:
      can_load = csp_->AllowImageFromSource(url, redirect_status);
      break;
    case kLocation:
      can_load = csp_->AllowNavigateToSource(url, redirect_status);
      break;
    case kMedia:
      can_load = csp_->AllowMediaFromSource(url, redirect_status);
      break;
    case kScript:
      can_load = csp_->AllowScriptFromSource(url, redirect_status);
      break;
    case kStyle:
      can_load = csp_->AllowStyleFromSource(url, redirect_status);
      break;
    case kWorker:
      can_load = csp_->AllowWorkerFromSource(url, redirect_status);
      break;
    case kXhr:
      can_load = csp_->AllowConnectToSource(url, redirect_status);
      break;
    case kWebSocket:
      can_load = csp_->AllowConnectToSource(url, redirect_status);
      break;
  }
  return can_load;
}

bool CspDelegateSecure::IsValidNonce(ResourceType type,
                                     const std::string& nonce) const {
  bool is_valid = false;
  switch (type) {
    case kScript:
      is_valid = csp_->AllowScriptWithNonce(nonce);
      break;
    case kStyle:
      is_valid = csp_->AllowStyleWithNonce(nonce);
      break;
    case kWorker:
      is_valid = csp_->AllowWorkerWithNonce(nonce);
      break;
    default:
      NOTREACHED() << "Invalid resource type " << type;
  }
  return is_valid;
}

bool CspDelegateSecure::AllowInline(ResourceType type,
                                    const base::SourceLocation& location,
                                    const std::string& content) const {
  // If CSP is not provided, allow inline script.
  if (!was_header_received_) {
    return true;
  }
  bool can_load = false;
  switch (type) {
    case kScript:
      can_load = csp_->AllowInlineScript(location.file_path,
                                         location.line_number, content);
      break;
    case kStyle:
      can_load = csp_->AllowInlineStyle(location.file_path,
                                        location.line_number, content);
      break;
    case kWorker:
      can_load = csp_->AllowInlineWorker(location.file_path,
                                         location.line_number, content);
      break;
    default:
      NOTREACHED() << "Invalid resource type" << type;
  }
  return can_load;
}

bool CspDelegateSecure::AllowEval(std::string* eval_disabled_message) const {
  bool allow_eval =
      // If CSP is not provided, allow eval() function.
      !was_header_received_ || csp_->AllowEval(csp::kSuppressReport);
  if (!allow_eval && eval_disabled_message) {
    *eval_disabled_message = csp_->disable_eval_error_message();
  }
  return allow_eval;
}

void CspDelegateSecure::ReportEval() const {
  csp_->AllowEval(csp::kSendReport);
}

bool CspDelegateSecure::OnReceiveHeaders(const csp::ResponseHeaders& headers) {
  was_header_received_ = !headers.content_security_policy().empty();
  if (was_header_received_) {
    csp_->OnReceiveHeaders(headers);
  } else {
    // Didn't find Content-Security-Policy header.
    if (!headers.content_security_policy_report_only().empty()) {
      DLOG(INFO)
          << "Content-Security-Policy-Report-Only headers were "
             "received, but Content-Security-Policy headers are required.";
    }
  }
  if (!policy_changed_callback_.is_null()) {
    policy_changed_callback_.Run();
  }
  return was_header_received_;
}

void CspDelegateSecure::OnReceiveHeader(const std::string& header,
                                        csp::HeaderType header_type,
                                        csp::HeaderSource header_source) {
  if (header_source == csp::kHeaderSourceMetaOutsideHead) {
    csp_->ReportMetaOutsideHead(header);
  } else {
    csp_->OnReceiveHeader(header, header_type, header_source);
    // We don't consider a Report-Only header to be sufficient.
    if (header_type == csp::kHeaderTypeEnforce) {
      was_header_received_ = true;
    }

    if (!policy_changed_callback_.is_null()) {
      policy_changed_callback_.Run();
    }
  }
}

}  // namespace web
}  // namespace cobalt
