// 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.

#ifndef COBALT_CSP_CONTENT_SECURITY_POLICY_H_
#define COBALT_CSP_CONTENT_SECURITY_POLICY_H_

#include <memory>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "cobalt/csp/directive_list.h"
#include "cobalt/csp/parsers.h"
#include "net/http/http_response_headers.h"
#include "url/gurl.h"

namespace cobalt {
namespace csp {

class Source;

// Wrap up information about a CSP violation, for passing to the Delegate.
struct ViolationInfo {
  std::string directive_text;
  std::string effective_directive;
  std::string console_message;
  GURL blocked_url;
  std::vector<std::string> endpoints;
  std::string header;
};

// Whether Cobalt can start without CSP headers.
enum CSPHeaderPolicy {
  kCSPRequired,
  kCSPOptional,
};

// A callback that a URL fetcher will call to check if the URL is permitted
// by our security policy. This may be called multiple times if the URL results
// in a redirect. The callback should return |true| if the URL is safe to
// load.
typedef base::Callback<bool(const GURL& url, bool did_redirect)>
    SecurityCallback;
typedef base::Callback<void(const ViolationInfo&)> ViolationCallback;

// Extract CSP-related headers from HttpResponseHeaders.
class ResponseHeaders {
 public:
  ResponseHeaders() {}
  explicit ResponseHeaders(
      const scoped_refptr<net::HttpResponseHeaders>& response);

  const std::string& content_security_policy() const {
    return content_security_policy_;
  }
  const std::string& content_security_policy_report_only() const {
    return content_security_policy_report_only_;
  }

 private:
  std::string content_security_policy_;
  std::string content_security_policy_report_only_;
};

class ContentSecurityPolicy {
 public:
  typedef std::vector<std::unique_ptr<DirectiveList>> PolicyList;

  // CSP Level 1 Directives
  //   https://www.w3.org/TR/2012/CR-CSP-20121115/
  static const char kConnectSrc[];
  static const char kDefaultSrc[];
  static const char kFontSrc[];
  static const char kFrameSrc[];
  static const char kImgSrc[];
  static const char kMediaSrc[];
  static const char kObjectSrc[];
  static const char kReportURI[];
  static const char kSandbox[];
  static const char kScriptSrc[];
  static const char kStyleSrc[];

  // CSP Level 2 Directives
  //   https://www.w3.org/TR/2016/REC-CSP2-20161215/
  static const char kBaseURI[];
  static const char kChildSrc[];
  static const char kFormAction[];
  static const char kFrameAncestors[];
  static const char kPluginTypes[];
  static const char kReflectedXSS[];
  static const char kReferrer[];

  // CSP Level 3 Directives
  //   https://www.w3.org/TR/2022/WD-CSP3-20221014/#directive-manifest-src

  static const char kManifestSrc[];
  // https://www.w3.org/TR/2022/WD-CSP3-20221014/#directive-worker-src
  static const char kWorkerSrc[];

  // Directives Defined in Other Documents.
  //   https://www.w3.org/TR/2022/WD-CSP3-20221014/#directives-elsewhere

  // Mixed Content Directive. Note: Deprecated in the current spec.
  //   https://www.w3.org/TR/2021/CRD-mixed-content-20211004/#strict-checking
  static const char kBlockAllMixedContent[];

  // The upgrade-insecure-requests Directive.
  //   https://w3c.github.io/webappsec-upgrade-insecure-requests/#delivery
  static const char kUpgradeInsecureRequests[];

  // Suborigin Directive
  //   https://metromoxie.github.io/webappsec/specs/suborigins/index.html#the-suborigin-directive
  static const char kSuborigin[];

  // Custom CSP directive h5vcc-location-src for Cobalt
  static const char kLocationSrc[];

  static bool IsDirectiveName(const std::string& name);

  ContentSecurityPolicy(const GURL& url,
                        const ViolationCallback& violation_callback);
  ~ContentSecurityPolicy();

  void OnReceiveHeaders(const ResponseHeaders& headers);
  void OnReceiveHeader(const std::string& header, HeaderType header_type,
                       HeaderSource header_source);

  bool UrlMatchesSelf(const GURL& url) const;
  bool SchemeMatchesSelf(const GURL& url) const;

  void ReportViolation(const std::string& directive_text,
                       const std::string& effective_directive,
                       const std::string& console_message,
                       const GURL& blocked_url,
                       const std::vector<std::string>& report_endpoints,
                       const std::string& header);

  // Diagnostic functions for reporting errors in the CSP directives.
  void ReportInvalidReferrer(const std::string& invalid_value);
  void ReportInvalidPluginTypes(const std::string& invalid_plugin);
  void ReportMetaOutsideHead(const std::string& header);
  void ReportValueForEmptyDirective(const std::string& directive_name,
                                    const std::string& value);
  void ReportDirectiveAsSourceExpression(const std::string& directive_name,
                                         const std::string& source_expression);
  void ReportInvalidSourceExpression(const std::string& directive_name,
                                     const std::string& source);
  void ReportInvalidPathCharacter(const std::string& directive_name,
                                  const std::string& value, char c);
  void ReportDuplicateDirective(const std::string& name);
  void ReportInvalidDirectiveValueCharacter(const std::string& directive_name,
                                            const std::string& value);
  void ReportInvalidReflectedXSS(const std::string& invalid_value);
  void ReportMissingReportURI(const std::string& policy);
  void ReportReportOnlyInMeta(const std::string& header);
  void ReportInvalidSuboriginFlags(const std::string& invalid_flags);
  void ReportUnsupportedDirective(const std::string& name);
  void ReportInvalidInReportOnly(const std::string& name);
  void ReportDirectiveNotSupportedInsideMeta(const std::string& name);

  // https://www.w3.org/TR/2015/CR-CSP2-20150721/#directives
  bool AllowInlineEventHandlers(const std::string& context_url,
                                int context_line,
                                ReportingStatus status = kSendReport) const;
  bool AllowInlineScript(const std::string& context_url, int context_line,
                         const std::string& script_content,
                         ReportingStatus status = kSendReport) const;
  bool AllowInlineWorker(const std::string& context_url, int context_line,
                         const std::string& script_content,
                         ReportingStatus status = kSendReport) const;
  bool AllowInlineStyle(const std::string& context_url, int context_line,
                        const std::string& style_content,
                        ReportingStatus status = kSendReport) const;
  bool AllowEval(ReportingStatus status = kSendReport) const;
  bool AllowScriptFromSource(const GURL& url,
                             RedirectStatus redirect = kDidNotRedirect,
                             ReportingStatus report = kSendReport) const;
  bool AllowWorkerFromSource(const GURL& url,
                             RedirectStatus redirect = kDidNotRedirect,
                             ReportingStatus report = kSendReport) const;
  bool AllowObjectFromSource(const GURL& url,
                             RedirectStatus redirect = kDidNotRedirect,
                             ReportingStatus report = kSendReport) const;
  bool AllowImageFromSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowStyleFromSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowFontFromSource(const GURL& url,
                           RedirectStatus redirect = kDidNotRedirect,
                           ReportingStatus report = kSendReport) const;
  bool AllowMediaFromSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowConnectToSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowNavigateToSource(const GURL& url,
                             RedirectStatus redirect = kDidNotRedirect,
                             ReportingStatus report = kSendReport) const;

  bool AllowFormAction(const GURL& url,
                       RedirectStatus redirect = kDidNotRedirect,
                       ReportingStatus report = kSendReport) const;
  bool AllowBaseURI(const GURL& url, RedirectStatus redirect = kDidNotRedirect,
                    ReportingStatus report = kSendReport) const;
  bool AllowManifestFromSource(const GURL& url,
                               RedirectStatus redirect = kDidNotRedirect,
                               ReportingStatus report = kSendReport) const;

  // The nonce and hash allow functions are guaranteed to not have any side
  // effects, including reporting.
  // Nonce/Hash functions check all policies relating to use of a script/style
  // with the given nonce/hash and return true all CSP policies allow it.
  // If these return true, callers can then process the content or
  // issue a load and be safe disabling any further CSP checks.
  bool AllowScriptWithNonce(const std::string& nonce) const;
  bool AllowWorkerWithNonce(const std::string& nonce) const;
  bool AllowStyleWithNonce(const std::string& nonce) const;
  bool AllowScriptWithHash(const std::string& source) const;
  bool AllowWorkerWithHash(const std::string& source) const;
  bool AllowStyleWithHash(const std::string& source) const;

  void set_uses_script_hash_algorithms(uint8 algorithm) {
    script_hash_algorithms_used_ |= algorithm;
  }
  void set_uses_style_hash_algorithms(uint8 algorithm) {
    style_hash_algorithms_used_ |= algorithm;
  }

  // Configure the origin URL for the document that owns this policy.
  // This could change during loading if the document load is redirected.
  void NotifyUrlChanged(const GURL& url);
  bool DidSetReferrerPolicy() const;

  const PolicyList& policies() const { return policies_; }
  void append_policy(const DirectiveList& directive_list) {
    policies_.emplace_back(new DirectiveList(this, directive_list));
  }

  const ReferrerPolicy& referrer_policy() const { return referrer_policy_; }
  void set_referrer_policy(const ReferrerPolicy& referrer_policy) {
    referrer_policy_ = referrer_policy;
  }

  const GURL& url() const { return url_; }
  void set_enforce_strict_mixed_content_checking() {
    enforce_strict_mixed_content_checking_ = true;
  }

  const std::string& disable_eval_error_message() const {
    return disable_eval_error_message_;
  }

 private:
  void CreateSelfSource();
  // Parses CSP header and creates policy based on that.
  void AddPolicyFromHeaderValue(const std::string& header, HeaderType type,
                                HeaderSource source);

  // List of CSP Policies.
  //   https://www.w3.org/TR/2022/WD-CSP3-20221014/#csp-list
  PolicyList policies_;
  std::unique_ptr<Source> self_source_;
  std::string self_scheme_;
  std::string disable_eval_error_message_;
  GURL url_;

  // Callback to use for reporting CSP violations.
  ViolationCallback violation_callback_;

  // Fields needing initialization.
  // Bitmasks of HashAlgorithm
  uint8 script_hash_algorithms_used_;
  uint8 style_hash_algorithms_used_;
  bool enforce_strict_mixed_content_checking_;
  ReferrerPolicy referrer_policy_;

  DISALLOW_COPY_AND_ASSIGN(ContentSecurityPolicy);
};

}  // namespace csp
}  // namespace cobalt

#endif  // COBALT_CSP_CONTENT_SECURITY_POLICY_H_
