// Copyright 2018 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 "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"

#include <utility>

#include "base/check.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"

namespace blink {

namespace {

enum class CSPType { kEmpty, kNonEmpty };

class IsolatedWorldCSPDelegate final
    : public GarbageCollected<IsolatedWorldCSPDelegate>,
      public ContentSecurityPolicyDelegate {

 public:
  IsolatedWorldCSPDelegate(LocalDOMWindow& window,
                           scoped_refptr<SecurityOrigin> security_origin,
                           int32_t world_id,
                           CSPType type)
      : window_(&window),
        security_origin_(std::move(security_origin)),
        world_id_(world_id),
        csp_type_(type) {
    DCHECK(security_origin_);
  }

  void Trace(Visitor* visitor) const override {
    visitor->Trace(window_);
    ContentSecurityPolicyDelegate::Trace(visitor);
  }

  const SecurityOrigin* GetSecurityOrigin() override {
    return security_origin_.get();
  }

  const KURL& Url() const override {
    // This is used to populate violation data's violation url. See
    // https://w3c.github.io/webappsec-csp/#violation-url.
    // TODO(crbug.com/916885): Figure out if we want to support violation
    // reporting for isolated world CSPs.
    DEFINE_STATIC_LOCAL(const KURL, g_empty_url, ());
    return g_empty_url;
  }

  // Isolated world CSPs don't support these directives: "sandbox",
  // "trusted-types" and "upgrade-insecure-requests".
  //
  // These directives depend on ExecutionContext for their implementation and
  // since isolated worlds don't have their own ExecutionContext, these are not
  // supported.
  void SetSandboxFlags(network::mojom::blink::WebSandboxFlags) override {}
  void SetRequireTrustedTypes() override {}
  void AddInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy) override {}

  // TODO(crbug.com/916885): Figure out if we want to support violation
  // reporting for isolated world CSPs.
  std::unique_ptr<SourceLocation> GetSourceLocation() override {
    return nullptr;
  }
  base::Optional<uint16_t> GetStatusCode() override { return base::nullopt; }
  String GetDocumentReferrer() override { return g_empty_string; }
  void DispatchViolationEvent(const SecurityPolicyViolationEventInit&,
                              Element*) override {
    // Sanity check that an empty CSP doesn't lead to a violation.
    DCHECK(csp_type_ == CSPType::kNonEmpty);
  }
  void PostViolationReport(const SecurityPolicyViolationEventInit&,
                           const String& stringified_report,
                           bool is_frame_ancestors_violation,
                           const Vector<String>& report_endpoints,
                           bool use_reporting_api) override {
    // Sanity check that an empty CSP doesn't lead to a violation.
    DCHECK(csp_type_ == CSPType::kNonEmpty);
  }

  void Count(WebFeature feature) override {
    // Log the features used by isolated world CSPs on the underlying window.
    UseCounter::Count(window_, feature);
  }

  void AddConsoleMessage(ConsoleMessage* console_message) override {
    // Add console messages on the underlying window.
    window_->AddConsoleMessage(console_message);
  }

  void AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr info) override {
    window_->AddInspectorIssue(std::move(info));
  }

  void DisableEval(const String& error_message) override {
    window_->GetScriptController().DisableEvalForIsolatedWorld(world_id_,
                                                               error_message);
  }

  void ReportBlockedScriptExecutionToInspector(
      const String& directive_text) override {
    // This allows users to set breakpoints in the Devtools for the case when
    // script execution is blocked by CSP.
    probe::ScriptExecutionBlockedByCSP(window_.Get(), directive_text);
  }

  void DidAddContentSecurityPolicies(
      WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override {}

 private:
  const Member<LocalDOMWindow> window_;
  const scoped_refptr<SecurityOrigin> security_origin_;
  const int32_t world_id_;
  const CSPType csp_type_;
};

}  // namespace

// static
IsolatedWorldCSP& IsolatedWorldCSP::Get() {
  DCHECK(IsMainThread());
  DEFINE_STATIC_LOCAL(IsolatedWorldCSP, g_isolated_world_csp, ());
  return g_isolated_world_csp;
}

void IsolatedWorldCSP::SetContentSecurityPolicy(
    int32_t world_id,
    const String& policy,
    scoped_refptr<SecurityOrigin> self_origin) {
  DCHECK(IsMainThread());
  DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id));

  if (!policy) {
    csp_map_.erase(world_id);
    return;
  }

  DCHECK(self_origin);
  PolicyInfo policy_info;
  policy_info.policy = policy;
  policy_info.self_origin = std::move(self_origin);
  csp_map_.Set(world_id, policy_info);
}

bool IsolatedWorldCSP::HasContentSecurityPolicy(int32_t world_id) const {
  DCHECK(IsMainThread());
  DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id));

  auto it = csp_map_.find(world_id);
  return it != csp_map_.end();
}

ContentSecurityPolicy* IsolatedWorldCSP::CreateIsolatedWorldCSP(
    LocalDOMWindow& window,
    int32_t world_id) {
  DCHECK(IsMainThread());
  DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id));

  auto it = csp_map_.find(world_id);
  if (it == csp_map_.end())
    return nullptr;

  const String& policy = it->value.policy;
  scoped_refptr<SecurityOrigin> self_origin = it->value.self_origin;

  auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();

  IsolatedWorldCSPDelegate* delegate =
      MakeGarbageCollected<IsolatedWorldCSPDelegate>(
          window, self_origin, world_id,
          policy.IsEmpty() ? CSPType::kEmpty : CSPType::kNonEmpty);
  csp->BindToDelegate(*delegate);
  csp->DidReceiveHeader(policy, *self_origin,
                        network::mojom::ContentSecurityPolicyType::kEnforce,
                        network::mojom::ContentSecurityPolicySource::kHTTP);

  return csp;
}

IsolatedWorldCSP::IsolatedWorldCSP() = default;

}  // namespace blink
