// Copyright 2015 Google Inc. 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 <string>
#include <vector>

#include "base/callback.h"
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "cobalt/csp/parsers.h"
#include "googleurl/src/gurl.h"
#include "net/http/http_response_headers.h"

namespace cobalt {
namespace csp {

class DirectiveList;
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;
};

// 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 ScopedVector<DirectiveList> PolicyList;

  // CSP Level 1 Directives
  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
  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[];

  // Custom CSP directive for Cobalt
  static const char kLocationSrc[];

  // Manifest Directives (to be merged into CSP Level 2)
  // https://w3c.github.io/manifest/#content-security-policy
  static const char kManifestSrc[];

  // Mixed Content Directive
  // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode
  static const char kBlockAllMixedContent[];

  // https://w3c.github.io/webappsec/specs/upgrade/
  static const char kUpgradeInsecureRequests[];

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

  enum ReportingStatus {
    kSendReport,
    kSuppressReport,
  };

  // When a resource is loaded after a redirect, source paths are
  // ignored in the matching algorithm.
  enum RedirectStatus {
    kDidRedirect,
    kDidNotRedirect,
  };

  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);
  void SetNavigationPolicy(const std::string& header);

  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 AllowJavaScriptURLs(const std::string& context_url, int context_line,
                           ReportingStatus status = kSendReport) const;
  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 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 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 AllowStyleWithNonce(const std::string& nonce) const;
  bool AllowScriptWithHash(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 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);

  PolicyList policies_;
  scoped_ptr<DirectiveList> navigation_policy_;
  scoped_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_
