/*
 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "core/fetch/CrossOriginAccessControl.h"

#include "core/fetch/FetchUtils.h"
#include "core/fetch/Resource.h"
#include "core/fetch/ResourceLoaderOptions.h"
#include "platform/network/HTTPParsers.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
#include "platform/weborigin/SchemeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/PtrUtil.h"
#include "wtf/Threading.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/StringBuilder.h"
#include <algorithm>
#include <memory>

namespace blink {

bool isOnAccessControlResponseHeaderWhitelist(const String& name) {
  DEFINE_THREAD_SAFE_STATIC_LOCAL(
      HTTPHeaderSet, allowedCrossOriginResponseHeaders,
      (new HTTPHeaderSet({
          "cache-control", "content-language", "content-type", "expires",
          "last-modified", "pragma",
      })));
  return allowedCrossOriginResponseHeaders.contains(name);
}

void updateRequestForAccessControl(ResourceRequest& request,
                                   const SecurityOrigin* securityOrigin,
                                   StoredCredentials allowCredentials) {
  request.removeCredentials();
  request.setAllowStoredCredentials(allowCredentials == AllowStoredCredentials);

  if (securityOrigin)
    request.setHTTPOrigin(securityOrigin);
}

// Fetch API Spec: https://fetch.spec.whatwg.org/#cors-preflight-fetch-0
static AtomicString createAccessControlRequestHeadersHeader(
    const HTTPHeaderMap& headers) {
  Vector<String> filteredHeaders;
  for (const auto& header : headers) {
    if (FetchUtils::isSimpleHeader(header.key, header.value)) {
      // Exclude simple headers.
      continue;
    }
    if (equalIgnoringCase(header.key, "referer")) {
      // When the request is from a Worker, referrer header was added by
      // WorkerThreadableLoader. But it should not be added to
      // Access-Control-Request-Headers header.
      continue;
    }
    filteredHeaders.append(header.key.lower());
  }

  // Sort header names lexicographically.
  std::sort(filteredHeaders.begin(), filteredHeaders.end(),
            WTF::codePointCompareLessThan);
  StringBuilder headerBuffer;
  for (const String& header : filteredHeaders) {
    if (!headerBuffer.isEmpty())
      headerBuffer.append(", ");
    headerBuffer.append(header);
  }

  return AtomicString(headerBuffer.toString());
}

ResourceRequest createAccessControlPreflightRequest(
    const ResourceRequest& request,
    const SecurityOrigin* securityOrigin) {
  ResourceRequest preflightRequest(request.url());
  updateRequestForAccessControl(preflightRequest, securityOrigin,
                                DoNotAllowStoredCredentials);
  preflightRequest.setHTTPMethod(HTTPNames::OPTIONS);
  preflightRequest.setHTTPHeaderField(HTTPNames::Access_Control_Request_Method,
                                      AtomicString(request.httpMethod()));
  preflightRequest.setPriority(request.priority());
  preflightRequest.setRequestContext(request.requestContext());
  preflightRequest.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All);

  if (request.isExternalRequest()) {
    preflightRequest.setHTTPHeaderField(
        HTTPNames::Access_Control_Request_External, "true");
  }

  if (request.httpHeaderFields().size() > 0) {
    preflightRequest.setHTTPHeaderField(
        HTTPNames::Access_Control_Request_Headers,
        createAccessControlRequestHeadersHeader(request.httpHeaderFields()));
  }

  return preflightRequest;
}

static bool isOriginSeparator(UChar ch) {
  return isASCIISpace(ch) || ch == ',';
}

static bool isInterestingStatusCode(int statusCode) {
  // Predicate that gates what status codes should be included in console error
  // messages for responses containing no access control headers.
  return statusCode >= 400;
}

static String buildAccessControlFailureMessage(
    const String& detail,
    const SecurityOrigin* securityOrigin) {
  return detail + " Origin '" + securityOrigin->toString() +
         "' is therefore not allowed access.";
}

bool passesAccessControlCheck(const ResourceResponse& response,
                              StoredCredentials includeCredentials,
                              const SecurityOrigin* securityOrigin,
                              String& errorDescription,
                              WebURLRequest::RequestContext context) {
  DEFINE_THREAD_SAFE_STATIC_LOCAL(
      AtomicString, allowOriginHeaderName,
      (new AtomicString("access-control-allow-origin")));
  DEFINE_THREAD_SAFE_STATIC_LOCAL(
      AtomicString, allowCredentialsHeaderName,
      (new AtomicString("access-control-allow-credentials")));
  DEFINE_THREAD_SAFE_STATIC_LOCAL(
      AtomicString, allowSuboriginHeaderName,
      (new AtomicString("access-control-allow-suborigin")));

  // TODO(esprehn): This code is using String::append extremely inefficiently
  // causing tons of copies. It should pass around a StringBuilder instead.

  int statusCode = response.httpStatusCode();

  if (!statusCode) {
    errorDescription =
        buildAccessControlFailureMessage("Invalid response.", securityOrigin);
    return false;
  }

  const AtomicString& allowOriginHeaderValue =
      response.httpHeaderField(allowOriginHeaderName);

  // Check Suborigins, unless the Access-Control-Allow-Origin is '*', which
  // implies that all Suborigins are okay as well.
  if (securityOrigin->hasSuborigin() && allowOriginHeaderValue != starAtom) {
    const AtomicString& allowSuboriginHeaderValue =
        response.httpHeaderField(allowSuboriginHeaderName);
    AtomicString atomicSuboriginName(securityOrigin->suborigin()->name());
    if (allowSuboriginHeaderValue != starAtom &&
        allowSuboriginHeaderValue != atomicSuboriginName) {
      errorDescription = buildAccessControlFailureMessage(
          "The 'Access-Control-Allow-Suborigin' header has a value '" +
              allowSuboriginHeaderValue +
              "' that is not equal to the supplied suborigin.",
          securityOrigin);
      return false;
    }
  }

  if (allowOriginHeaderValue == starAtom) {
    // A wildcard Access-Control-Allow-Origin can not be used if credentials are
    // to be sent, even with Access-Control-Allow-Credentials set to true.
    if (includeCredentials == DoNotAllowStoredCredentials)
      return true;
    if (response.isHTTP()) {
      errorDescription = buildAccessControlFailureMessage(
          "A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' "
          "header when the credentials flag is true.",
          securityOrigin);

      if (context == WebURLRequest::RequestContextXMLHttpRequest) {
        errorDescription.append(
            " The credentials mode of an XMLHttpRequest is controlled by the "
            "withCredentials attribute.");
      }

      return false;
    }
  } else if (allowOriginHeaderValue != securityOrigin->toAtomicString()) {
    if (allowOriginHeaderValue.isNull()) {
      errorDescription = buildAccessControlFailureMessage(
          "No 'Access-Control-Allow-Origin' header is present on the requested "
          "resource.",
          securityOrigin);

      if (isInterestingStatusCode(statusCode)) {
        errorDescription.append(" The response had HTTP status code ");
        errorDescription.append(String::number(statusCode));
        errorDescription.append('.');
      }

      if (context == WebURLRequest::RequestContextFetch) {
        errorDescription.append(
            " If an opaque response serves your needs, set the request's mode "
            "to 'no-cors' to fetch the resource with CORS disabled.");
      }

      return false;
    }

    String detail;
    if (allowOriginHeaderValue.getString().find(isOriginSeparator, 0) !=
        kNotFound) {
      detail =
          "The 'Access-Control-Allow-Origin' header contains multiple values "
          "'" +
          allowOriginHeaderValue + "', but only one is allowed.";
    } else {
      KURL headerOrigin(KURL(), allowOriginHeaderValue);
      if (!headerOrigin.isValid()) {
        detail =
            "The 'Access-Control-Allow-Origin' header contains the invalid "
            "value '" +
            allowOriginHeaderValue + "'.";
      } else {
        detail = "The 'Access-Control-Allow-Origin' header has a value '" +
                 allowOriginHeaderValue +
                 "' that is not equal to the supplied origin.";
      }
    }
    errorDescription = buildAccessControlFailureMessage(detail, securityOrigin);
    if (context == WebURLRequest::RequestContextFetch) {
      errorDescription.append(
          " Have the server send the header with a valid value, or, if an "
          "opaque response serves your needs, set the request's mode to "
          "'no-cors' to fetch the resource with CORS disabled.");
    }
    return false;
  }

  if (includeCredentials == AllowStoredCredentials) {
    const AtomicString& allowCredentialsHeaderValue =
        response.httpHeaderField(allowCredentialsHeaderName);
    if (allowCredentialsHeaderValue != "true") {
      errorDescription = buildAccessControlFailureMessage(
          "Credentials flag is 'true', but the "
          "'Access-Control-Allow-Credentials' header is '" +
              allowCredentialsHeaderValue +
              "'. It must be 'true' to allow credentials.",
          securityOrigin);
      return false;
    }
  }

  return true;
}

bool passesPreflightStatusCheck(const ResourceResponse& response,
                                String& errorDescription) {
  // CORS preflight with 3XX is considered network error in
  // Fetch API Spec: https://fetch.spec.whatwg.org/#cors-preflight-fetch
  // CORS Spec: http://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
  // https://crbug.com/452394
  if (response.httpStatusCode() < 200 || response.httpStatusCode() >= 300) {
    errorDescription = "Response for preflight has invalid HTTP status code " +
                       String::number(response.httpStatusCode());
    return false;
  }

  return true;
}

bool passesExternalPreflightCheck(const ResourceResponse& response,
                                  String& errorDescription) {
  AtomicString result =
      response.httpHeaderField(HTTPNames::Access_Control_Allow_External);
  if (result.isNull()) {
    errorDescription =
        "No 'Access-Control-Allow-External' header was present in the "
        "preflight response for this external request (This is an experimental "
        "header which is defined in "
        "'https://mikewest.github.io/cors-rfc1918/').";
    return false;
  }
  if (!equalIgnoringCase(result, "true")) {
    errorDescription =
        "The 'Access-Control-Allow-External' header in the preflight response "
        "for this external request had a value of '" +
        result +
        "',  not 'true' (This is an experimental header which is defined in "
        "'https://mikewest.github.io/cors-rfc1918/').";
    return false;
  }
  return true;
}

void parseAccessControlExposeHeadersAllowList(const String& headerValue,
                                              HTTPHeaderSet& headerSet) {
  Vector<String> headers;
  headerValue.split(',', false, headers);
  for (unsigned headerCount = 0; headerCount < headers.size(); headerCount++) {
    String strippedHeader = headers[headerCount].stripWhiteSpace();
    if (!strippedHeader.isEmpty())
      headerSet.add(strippedHeader);
  }
}

void extractCorsExposedHeaderNamesList(const ResourceResponse& response,
                                       HTTPHeaderSet& headerSet) {
  // If a response was fetched via a service worker, it will always have
  // corsExposedHeaderNames set, either from the Access-Control-Expose-Headers
  // header, or explicitly via foreign fetch. For requests that didn't come from
  // a service worker, foreign fetch doesn't apply so just parse the CORS
  // header.
  if (response.wasFetchedViaServiceWorker()) {
    for (const auto& header : response.corsExposedHeaderNames())
      headerSet.add(header);
    return;
  }
  parseAccessControlExposeHeadersAllowList(
      response.httpHeaderField(HTTPNames::Access_Control_Expose_Headers),
      headerSet);
}

bool CrossOriginAccessControl::isLegalRedirectLocation(
    const KURL& requestURL,
    String& errorDescription) {
  // Block non HTTP(S) schemes as specified in the step 4 in
  // https://fetch.spec.whatwg.org/#http-redirect-fetch. Chromium also allows
  // the data scheme.
  //
  // TODO(tyoshino): This check should be performed regardless of the CORS flag
  // and request's mode.
  if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(
          requestURL.protocol())) {
    errorDescription = "Redirect location '" + requestURL.getString() +
                       "' has a disallowed scheme for cross-origin requests.";
    return false;
  }

  // Block URLs including credentials as specified in the step 9 in
  // https://fetch.spec.whatwg.org/#http-redirect-fetch.
  //
  // TODO(tyoshino): This check should be performed also when request's
  // origin is not same origin with the redirect destination's origin.
  if (!(requestURL.user().isEmpty() && requestURL.pass().isEmpty())) {
    errorDescription =
        "Redirect location '" + requestURL.getString() +
        "' contains userinfo, which is disallowed for cross-origin requests.";
    return false;
  }

  return true;
}

bool CrossOriginAccessControl::handleRedirect(
    PassRefPtr<SecurityOrigin> securityOrigin,
    ResourceRequest& newRequest,
    const ResourceResponse& redirectResponse,
    StoredCredentials withCredentials,
    ResourceLoaderOptions& options,
    String& errorMessage) {
  // http://www.w3.org/TR/cors/#redirect-steps terminology:
  const KURL& lastURL = redirectResponse.url();
  const KURL& newURL = newRequest.url();

  RefPtr<SecurityOrigin> currentSecurityOrigin = securityOrigin;

  RefPtr<SecurityOrigin> newSecurityOrigin = currentSecurityOrigin;

  // TODO(tyoshino): This should be fixed to check not only the last one but
  // all redirect responses.
  if (!currentSecurityOrigin->canRequest(lastURL)) {
    // Follow http://www.w3.org/TR/cors/#redirect-steps
    String errorDescription;

    if (!isLegalRedirectLocation(newURL, errorDescription)) {
      errorMessage = "Redirect from '" + lastURL.getString() +
                     "' has been blocked by CORS policy: " + errorDescription;
      return false;
    }

    // Step 5: perform resource sharing access check.
    if (!passesAccessControlCheck(redirectResponse, withCredentials,
                                  currentSecurityOrigin.get(), errorDescription,
                                  newRequest.requestContext())) {
      errorMessage = "Redirect from '" + lastURL.getString() +
                     "' has been blocked by CORS policy: " + errorDescription;
      return false;
    }

    RefPtr<SecurityOrigin> lastOrigin = SecurityOrigin::create(lastURL);
    // Set request's origin to a globally unique identifier as specified in
    // the step 10 in https://fetch.spec.whatwg.org/#http-redirect-fetch.
    if (!lastOrigin->canRequest(newURL)) {
      options.securityOrigin = SecurityOrigin::createUnique();
      newSecurityOrigin = options.securityOrigin;
    }
  }

  if (!currentSecurityOrigin->canRequest(newURL)) {
    newRequest.clearHTTPOrigin();
    newRequest.setHTTPOrigin(newSecurityOrigin.get());

    // Unset credentials flag if request's credentials mode is "same-origin" as
    // request's response tainting becomes "cors".
    //
    // This is equivalent to the step 2 in
    // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
    if (options.credentialsRequested == ClientDidNotRequestCredentials)
      options.allowCredentials = DoNotAllowStoredCredentials;
  }
  return true;
}

}  // namespace blink
