// 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/renderer/script_context_set.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/render_frame.h"
#include "extensions/common/extension.h"
#include "extensions/renderer/extensions_renderer_client.h"
#include "extensions/renderer/script_context.h"
#include "extensions/renderer/script_injection.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "v8/include/v8.h"

namespace extensions {

namespace {
// There is only ever one instance of the ScriptContextSet.
ScriptContextSet* g_context_set = nullptr;
}

ScriptContextSet::ScriptContextSet(ExtensionIdSet* active_extension_ids)
    : active_extension_ids_(active_extension_ids) {
  DCHECK(!g_context_set);
  g_context_set = this;
}

ScriptContextSet::~ScriptContextSet() {
  g_context_set = nullptr;
}

ScriptContext* ScriptContextSet::Register(
    blink::WebLocalFrame* frame,
    const v8::Local<v8::Context>& v8_context,
    int32_t world_id) {
  const Extension* extension =
      GetExtensionFromFrameAndWorld(frame, world_id, false);
  const Extension* effective_extension =
      GetExtensionFromFrameAndWorld(frame, world_id, true);

  GURL frame_url = ScriptContext::GetDocumentLoaderURLForFrame(frame);
  Feature::Context context_type = ClassifyJavaScriptContext(
      extension, world_id, frame_url, frame->GetDocument().GetSecurityOrigin());
  Feature::Context effective_context_type = ClassifyJavaScriptContext(
      effective_extension, world_id,
      ScriptContext::GetEffectiveDocumentURL(frame, frame_url, true),
      frame->GetDocument().GetSecurityOrigin());

  ScriptContext* context =
      new ScriptContext(v8_context, frame, extension, context_type,
                        effective_extension, effective_context_type);
  contexts_.insert(context);  // takes ownership
  return context;
}

void ScriptContextSet::Remove(ScriptContext* context) {
  if (contexts_.erase(context)) {
    context->Invalidate();
    base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, context);
  }
}

ScriptContext* ScriptContextSet::GetCurrent() const {
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
  return isolate->InContext() ? GetByV8Context(isolate->GetCurrentContext())
                              : nullptr;
}

ScriptContext* ScriptContextSet::GetByV8Context(
    const v8::Local<v8::Context>& v8_context) const {
  for (ScriptContext* script_context : contexts_) {
    if (script_context->v8_context() == v8_context)
      return script_context;
  }
  return nullptr;
}

ScriptContext* ScriptContextSet::GetContextByObject(
    const v8::Local<v8::Object>& object) {
  return GetContextByV8Context(object->CreationContext());
}

ScriptContext* ScriptContextSet::GetContextByV8Context(
    const v8::Local<v8::Context>& v8_context) {
  // g_context_set can be null in unittests.
  return g_context_set ? g_context_set->GetByV8Context(v8_context) : nullptr;
}

ScriptContext* ScriptContextSet::GetMainWorldContextForFrame(
    content::RenderFrame* render_frame) {
  v8::HandleScope handle_scope(blink::MainThreadIsolate());
  return GetContextByV8Context(
      render_frame->GetWebFrame()->MainWorldScriptContext());
}

void ScriptContextSet::ForEach(
    const std::string& extension_id,
    content::RenderFrame* render_frame,
    const base::RepeatingCallback<void(ScriptContext*)>& callback) {
  // We copy the context list, because calling into javascript may modify it
  // out from under us.
  std::set<ScriptContext*> contexts_copy = contexts_;

  for (ScriptContext* context : contexts_copy) {
    // For the same reason as above, contexts may become invalid while we run.
    if (!context->is_valid())
      continue;

    if (!extension_id.empty()) {
      const Extension* extension = context->extension();
      if (!extension || (extension_id != extension->id()))
        continue;
    }

    content::RenderFrame* context_render_frame = context->GetRenderFrame();
    if (render_frame && render_frame != context_render_frame)
      continue;

    callback.Run(context);
  }
}

void ScriptContextSet::OnExtensionUnloaded(const std::string& extension_id) {
  ScriptContextSetIterable::ForEach(
      extension_id,
      base::BindRepeating(&ScriptContextSet::Remove, base::Unretained(this)));
}

void ScriptContextSet::AddForTesting(std::unique_ptr<ScriptContext> context) {
  contexts_.insert(context.release());  // Takes ownership
}

const Extension* ScriptContextSet::GetExtensionFromFrameAndWorld(
    blink::WebLocalFrame* frame,
    int32_t world_id,
    bool use_effective_url) {
  std::string extension_id;
  if (world_id != 0) {
    // Isolated worlds (content script).
    extension_id = ScriptInjection::GetHostIdForIsolatedWorld(world_id);
  } else {
    // For looking up the extension associated with this frame, we either want
    // to use the current url or possibly the data source url (which this frame
    // may be navigating to shortly), depending on the security origin of the
    // frame. We don't always want to use the data source url because some
    // frames (eg iframes and windows created via window.open) briefly contain
    // an about:blank script context that is scriptable by their parent/opener
    // before they finish navigating.
    GURL frame_url = ScriptContext::GetAccessCheckedFrameURL(frame);
    frame_url = ScriptContext::GetEffectiveDocumentURL(frame, frame_url,
                                                       use_effective_url);
    extension_id =
        RendererExtensionRegistry::Get()->GetExtensionOrAppIDByURL(frame_url);
  }

  // There are conditions where despite a context being associated with an
  // extension, no extension actually gets found. Ignore "invalid" because CSP
  // blocks extension page loading by switching the extension ID to "invalid".
  const Extension* extension =
      RendererExtensionRegistry::Get()->GetByID(extension_id);
  if (!extension && !extension_id.empty() && extension_id != "invalid") {
    // TODO(kalman): Do something here?
  }
  return extension;
}

Feature::Context ScriptContextSet::ClassifyJavaScriptContext(
    const Extension* extension,
    int32_t world_id,
    const GURL& url,
    const blink::WebSecurityOrigin& origin) {
  // WARNING: This logic must match ProcessMap::GetContextType, as much as
  // possible.

  // Worlds not within this range are not for content scripts, so ignore them.
  // TODO(devlin): Isolated worlds with a non-zero id could belong to
  // chrome-internal pieces, like dom distiller and translate. Do we need any
  // bindings (even those for basic web pages) for those?
  if (world_id >= ExtensionsRendererClient::Get()->GetLowestIsolatedWorldId()) {
    return extension ?  // TODO(kalman): when does this happen?
               Feature::CONTENT_SCRIPT_CONTEXT
                     : Feature::UNSPECIFIED_CONTEXT;
  }

  // We have an explicit check for sandboxed pages before checking whether the
  // extension is active in this process because:
  // 1. Sandboxed pages run in the same process as regular extension pages, so
  //    the extension is considered active.
  // 2. ScriptContext creation (which triggers bindings injection) happens
  //    before the SecurityContext is updated with the sandbox flags (after
  //    reading the CSP header), so the caller can't check if the context's
  //    security origin is unique yet.
  if (ScriptContext::IsSandboxedPage(url))
    return Feature::WEB_PAGE_CONTEXT;

  if (extension && active_extension_ids_->count(extension->id()) > 0) {
    // |extension| is active in this process, but it could be either a true
    // extension process or within the extent of a hosted app. In the latter
    // case this would usually be considered a (blessed) web page context,
    // unless the extension in question is a component extension, in which case
    // we cheat and call it blessed.
    if (extension->is_hosted_app() &&
        extension->location() != Manifest::COMPONENT) {
      return Feature::BLESSED_WEB_PAGE_CONTEXT;
    }

    return is_lock_screen_context_ ? Feature::LOCK_SCREEN_EXTENSION_CONTEXT
                                   : Feature::BLESSED_EXTENSION_CONTEXT;
  }

  // TODO(kalman): This isUnique() check is wrong, it should be performed as
  // part of ScriptContext::IsSandboxedPage().
  if (!origin.IsUnique() &&
      RendererExtensionRegistry::Get()->ExtensionBindingsAllowed(url)) {
    if (!extension)  // TODO(kalman): when does this happen?
      return Feature::UNSPECIFIED_CONTEXT;
    return extension->is_hosted_app() ? Feature::BLESSED_WEB_PAGE_CONTEXT
                                      : Feature::UNBLESSED_EXTENSION_CONTEXT;
  }

  if (!url.is_valid())
    return Feature::UNSPECIFIED_CONTEXT;

  if (url.SchemeIs(content::kChromeUIScheme))
    return Feature::WEBUI_CONTEXT;

  return Feature::WEB_PAGE_CONTEXT;
}

}  // namespace extensions
