// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/webui/url_data_manager_backend.h"

#include <set>
#include <utility>

#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "content/browser/webui/shared_resources_data_source.h"
#include "content/browser/webui/url_data_source_impl.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "net/log/net_log_util.h"
#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "ui/base/template_expressions.h"
#include "ui/base/webui/i18n_source_stream.h"
#include "url/url_util.h"

namespace content {

namespace {

const char kChromeURLContentSecurityPolicyHeaderName[] =
    "Content-Security-Policy";

const char kChromeURLCrossOriginOpenerPolicyName[] =
    "Cross-Origin-Opener-Policy";
const char kChromeURLCrossOriginEmbedderPolicyName[] =
    "Cross-Origin-Embedder-Policy";
const char kChromeURLCrossOriginResourcePolicyName[] =
    "Cross-Origin-Resource-Policy";

const char kChromeURLXFrameOptionsHeaderName[] = "X-Frame-Options";
const char kChromeURLXFrameOptionsHeaderValue[] = "DENY";
const char kNetworkErrorKey[] = "netError";
const char kURLDataManagerBackendKeyName[] = "url_data_manager_backend";

bool g_disallow_webui_scheme_caching_for_testing = false;

std::vector<std::string> GetWebUISchemesSlow() {
  std::vector<std::string> schemes = {kChromeUIScheme,
                                      kChromeUIUntrustedScheme};
  GetContentClient()->browser()->GetAdditionalWebUISchemes(&schemes);
  return schemes;
}

std::vector<std::string> GetWebUISchemesCached() {
  // It's OK to cache this in a static because the class implementing
  // GetAdditionalWebUISchemes() won't change while the application is
  // running, and because those methods always add the same items.
  //
  // However, be careful using this with unit tests which use
  // GetAdditionalWebUISchemes() to change the list of WebUI schemes, since
  // this caching may persist across tests. For those, this caching should be
  // disabled via SetDisallowWebUISchemeCachingForTesting().
  static base::NoDestructor<std::vector<std::string>> webui_schemes(
      GetWebUISchemesSlow());

  return *webui_schemes;
}

}  // namespace

URLDataManagerBackend::URLDataManagerBackend() {
  {
    // Add a shared data source for chrome://resources.
    auto* source = new WebUIDataSourceImpl(kChromeUIResourcesHost);
    PopulateSharedResourcesDataSource(source);
    AddDataSource(source);  // Takes ownership.
  }

  {
    // Add a shared data source for chrome-untrusted://resources.
    auto* source = new WebUIDataSourceImpl(kChromeUIUntrustedResourcesURL);
    PopulateSharedResourcesDataSource(source);
    AddDataSource(source);  // Takes ownership.
  }
}

URLDataManagerBackend::~URLDataManagerBackend() = default;

URLDataManagerBackend* URLDataManagerBackend::GetForBrowserContext(
    BrowserContext* context) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!context->GetUserData(kURLDataManagerBackendKeyName)) {
    context->SetUserData(kURLDataManagerBackendKeyName,
                         std::make_unique<URLDataManagerBackend>());
  }
  return static_cast<URLDataManagerBackend*>(
      context->GetUserData(kURLDataManagerBackendKeyName));
}

void URLDataManagerBackend::AddDataSource(URLDataSourceImpl* source) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!source->source()->ShouldReplaceExistingSource() &&
      data_sources_.contains(source->source_name())) {
    return;
  }
  data_sources_[source->source_name()] = source;
  source->backend_ = weak_factory_.GetWeakPtr();
}

void URLDataManagerBackend::UpdateWebUIDataSource(
    const std::string& source_name,
    const base::Value::Dict& update) {
  auto it = data_sources_.find(source_name);
  if (it == data_sources_.end() || !it->second->IsWebUIDataSourceImpl()) {
    NOTREACHED();
  }
  static_cast<WebUIDataSourceImpl*>(it->second.get())
      ->AddLocalizedStrings(update);
}

URLDataSourceImpl* URLDataManagerBackend::GetDataSourceFromURL(
    const GURL& url) {
  // chrome-untrusted:// sources keys are of the form "chrome-untrusted://host".
  if (url.GetScheme() == kChromeUIUntrustedScheme) {
    auto i = data_sources_.find(url.DeprecatedGetOriginAsURL().spec());
    if (i == data_sources_.end())
      return nullptr;
    return i->second.get();
  }

  // The input usually looks like: chrome://source_name/extra_bits?foo
  // so do a lookup using the host of the URL.
  auto i = data_sources_.find(url.GetHost());
  if (i != data_sources_.end())
    return i->second.get();

  // No match using the host of the URL, so do a lookup using the scheme for
  // URLs on the form source_name://extra_bits/foo .
  i = data_sources_.find(url.GetScheme() + "://");
  if (i != data_sources_.end())
    return i->second.get();

  // No matches found, so give up.
  return nullptr;
}

scoped_refptr<net::HttpResponseHeaders> URLDataManagerBackend::GetHeaders(
    URLDataSourceImpl* source_impl,
    const GURL& url,
    const std::string& origin) {
  // Set the headers so that requests serviced by ChromeURLDataManager return a
  // status code of 200. Without this they return a 0, which makes the status
  // indistiguishable from other error types. Instant relies on getting a 200.
  auto headers =
      base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
  if (!source_impl)
    return headers;

  URLDataSource* source = source_impl->source();
  // Determine the least-privileged content security policy header, if any,
  // that is compatible with a given WebUI URL, and append it to the existing
  // response headers.
  if (source->ShouldAddContentSecurityPolicy()) {
    std::string csp_header;

    constexpr network::mojom::CSPDirectiveName kAllDirectives[] = {
        network::mojom::CSPDirectiveName::BaseURI,
        network::mojom::CSPDirectiveName::ChildSrc,
        network::mojom::CSPDirectiveName::ConnectSrc,
        network::mojom::CSPDirectiveName::DefaultSrc,
        network::mojom::CSPDirectiveName::FencedFrameSrc,
        network::mojom::CSPDirectiveName::FormAction,
        network::mojom::CSPDirectiveName::FontSrc,
        network::mojom::CSPDirectiveName::FrameSrc,
        network::mojom::CSPDirectiveName::ImgSrc,
        network::mojom::CSPDirectiveName::MediaSrc,
        network::mojom::CSPDirectiveName::ObjectSrc,
        network::mojom::CSPDirectiveName::RequireTrustedTypesFor,
        network::mojom::CSPDirectiveName::ScriptSrc,
        network::mojom::CSPDirectiveName::StyleSrc,
        network::mojom::CSPDirectiveName::TrustedTypes,
        network::mojom::CSPDirectiveName::WorkerSrc};
    for (const auto& directive : kAllDirectives) {
      csp_header.append(source->GetContentSecurityPolicy(directive));
    }

    // TODO(crbug.com/40118579): Both CSP frame ancestors and XFO headers may be
    // added to the response but frame ancestors would take precedence. In the
    // future, XFO will be removed so when that happens remove the check and
    // always add frame ancestors.
    if (source->ShouldDenyXFrameOptions()) {
      csp_header.append(source->GetContentSecurityPolicy(
          network::mojom::CSPDirectiveName::FrameAncestors));
    }

    headers->SetHeader(kChromeURLContentSecurityPolicyHeaderName, csp_header);
  }

  if (source->ShouldDenyXFrameOptions()) {
    headers->SetHeader(kChromeURLXFrameOptionsHeaderName,
                       kChromeURLXFrameOptionsHeaderValue);
  }

  if (!source->AllowCaching())
    headers->SetHeader("Cache-Control", "no-cache");

  std::string mime_type = source->GetMimeType(url);
  if (source->ShouldServeMimeTypeAsContentTypeHeader() && !mime_type.empty())
    headers->SetHeader(net::HttpRequestHeaders::kContentType, mime_type);

  const std::string coop_value = source->GetCrossOriginOpenerPolicy();
  if (!coop_value.empty()) {
    headers->SetHeader(kChromeURLCrossOriginOpenerPolicyName, coop_value);
  }
  const std::string coep_value = source->GetCrossOriginEmbedderPolicy();
  if (!coep_value.empty()) {
    headers->SetHeader(kChromeURLCrossOriginEmbedderPolicyName, coep_value);
  }
  const std::string corp_value = source->GetCrossOriginResourcePolicy();
  if (!corp_value.empty()) {
    headers->SetHeader(kChromeURLCrossOriginResourcePolicyName, corp_value);
  }

  if (!origin.empty()) {
    std::string header = source->GetAccessControlAllowOriginForOrigin(origin);
    DCHECK(header.empty() || header == origin || header == "*" ||
           header == "null");
    if (!header.empty()) {
      headers->SetHeader("Access-Control-Allow-Origin", header);
      headers->SetHeader("Vary", "Origin");
    }
  }

  return headers;
}

bool URLDataManagerBackend::CheckURLIsValid(const GURL& url) {
  std::vector<std::string> additional_schemes;
  DCHECK(url.SchemeIs(kChromeUIScheme) ||
         url.SchemeIs(kChromeUIUntrustedScheme) ||
         (GetContentClient()->browser()->GetAdditionalWebUISchemes(
              &additional_schemes),
          base::Contains(additional_schemes, url.GetScheme())));

  if (!url.is_valid()) {
    NOTREACHED();
  }

  return true;
}

bool URLDataManagerBackend::IsValidNetworkErrorCode(int error_code) {
  base::Value::Dict error_codes = net::GetNetConstants();
  const base::Value::Dict* net_error_codes_dict =
      error_codes.FindDict(kNetworkErrorKey);
  if (net_error_codes_dict) {
    for (auto [key, value] : *net_error_codes_dict) {
      if (error_code == value.GetInt()) {
        return true;
      }
    }
  }
  return false;
}

std::vector<std::string> URLDataManagerBackend::GetWebUISchemes() {
  if (g_disallow_webui_scheme_caching_for_testing) {
    return GetWebUISchemesSlow();
  }

  return GetWebUISchemesCached();
}

void URLDataManagerBackend::SetDisallowWebUISchemeCachingForTesting(
    bool disallow_caching) {
  g_disallow_webui_scheme_caching_for_testing = disallow_caching;
}

}  // namespace content
