/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISerializable.idl"
#include "nsIContentPolicy.idl"

interface nsIURI;
interface nsIChannel;
interface nsIDocShell;
interface nsIPrincipal;

/**
 * nsIContentSecurityPolicy
 * Describes an XPCOM component used to model and enforce CSPs.  Instances of
 * this class may have multiple policies within them, but there should only be
 * one of these per document/principal.
 */

[scriptable, uuid(3e923bf6-a974-4f3b-91c4-b4fd48b37732)]
interface nsIContentSecurityPolicy : nsISerializable
{

  /**
   * Set to true when the CSP has been read in and parsed and is ready to
   * enforce.  This is a barrier for the nsDocument so it doesn't load any
   * sub-content until either it knows that a CSP is ready or will not be used.
   */
  readonly attribute boolean isInitialized;

  /**
   * Accessor method for a read-only string version of the policy at a given
   * index.
   */
  AString getPolicy(in unsigned long index);

  /**
   * Returns the number of policies attached to this CSP instance.  Useful with
   * getPolicy().
   */
  readonly attribute unsigned long policyCount;

  /**
   * Remove a policy associated with this CSP context.
   * @throws NS_ERROR_FAILURE if the index is out of bounds or invalid.
   */
  void removePolicy(in unsigned long index);

  /**
   * Parse and install a CSP policy.
   * @param aPolicy
   *        String representation of the policy (e.g., header value)
   * @param selfURI
   *        the URI of the protected document/principal
   * @param reportOnly
   *        Should this policy affect content, script and style processing or
   *        just send reports if it is violated?
   */
  void appendPolicy(in AString policyString, in nsIURI selfURI,
                    in boolean reportOnly);

  /**
   * Whether this policy allows in-page script.
   * @param shouldReportViolations
   *     Whether or not the use of inline script should be reported.
   *     This function always returns "true" for report-only policies, but when
   *     any policy (report-only or otherwise) is violated,
   *     shouldReportViolations is true as well.
   * @return
   *     Whether or not the effects of the inline script should be allowed
   *     (block the compilation if false).
   */
  boolean getAllowsInlineScript(out boolean shouldReportViolations);

  /**
   * whether this policy allows eval and eval-like functions
   * such as setTimeout("code string", time).
   * @param shouldReportViolations
   *     Whether or not the use of eval should be reported.
   *     This function returns "true" when violating report-only policies, but
   *     when any policy (report-only or otherwise) is violated,
   *     shouldReportViolations is true as well.
   * @return
   *     Whether or not the effects of the eval call should be allowed
   *     (block the call if false).
   */
  boolean getAllowsEval(out boolean shouldReportViolations);

  /**
   * Whether this policy allows in-page styles.
   * This includes <style> tags with text content and style="" attributes in
   * HTML elements.
   * @param shouldReportViolations
   *     Whether or not the use of inline style should be reported.
   *     If there are report-only policies, this function may return true
   *     (don't block), but one or more policy may still want to send
   *     violation reports so shouldReportViolations will be true even if the
   *     inline style should be permitted.
   * @return
   *     Whether or not the effects of the inline style should be allowed
   *     (block the rules if false).
   */
  boolean getAllowsInlineStyle(out boolean shouldReportViolations);

  /**
   * Whether this policy accepts the given nonce
   * @param aNonce
   *     The nonce string to check against the policy
   * @param aContentType
   *     The type of element on which we encountered this nonce
   * @param shouldReportViolation
   *     Whether or not the use of an incorrect nonce should be reported.
   *     This function always returns "true" for report-only policies, but when
   *     the report-only policy is violated, shouldReportViolation is true as
   *     well.
   * @return
   *     Whether or not this nonce is valid
   */
   boolean getAllowsNonce(in AString aNonce,
                          in unsigned long aContentType,
                          out boolean shouldReportViolation);

   /**
    * Whether this policy accepts the given inline resource based on the hash
    * of its content.
    * @param aContent
    *     The content of the inline resource to hash (and compare to the
    *     hashes listed in the policy)
    * @param aContentType
    *     The type of inline element (script or style)
    * @param shouldReportViolation
    *     Whether this inline resource should be reported as a hash-source
    *     violation. If there are no hash-sources in the policy, this is
    *     always false.
    * @return
    *     Whether or not this inline resource is whitelisted by a hash-source
    */
   boolean getAllowsHash(in AString aContent,
                         in unsigned short aContentType,
                         out boolean shouldReportViolation);

  /**
   * For each violated policy (of type violationType), log policy violation on
   * the Error Console and send a report to report-uris present in the violated
   * policies.
   *
   * @param violationType
   *     one of the VIOLATION_TYPE_* constants, e.g. inline-script or eval
   * @param sourceFile
   *     name of the source file containing the violation (if available)
   * @param contentSample
   *     sample of the violating content (to aid debugging)
   * @param lineNum
   *     source line number of the violation (if available)
   * @param aNonce
   *     (optional) If this is a nonce violation, include the nonce so we can
   *     recheck to determine which policies were violated and send the
   *     appropriate reports.
   * @param aContent
   *     (optional) If this is a hash violation, include contents of the inline
   *     resource in the question so we can recheck the hash in order to
   *     determine which policies were violated and send the appropriate
   *     reports.
   */
  void logViolationDetails(in unsigned short violationType,
                           in AString sourceFile,
                           in AString scriptSample,
                           in int32_t lineNum,
                           [optional] in AString nonce,
                           [optional] in AString content);

  const unsigned short VIOLATION_TYPE_INLINE_SCRIPT = 1;
  const unsigned short VIOLATION_TYPE_EVAL          = 2;
  const unsigned short VIOLATION_TYPE_INLINE_STYLE  = 3;
  const unsigned short VIOLATION_TYPE_NONCE_SCRIPT  = 4;
  const unsigned short VIOLATION_TYPE_NONCE_STYLE   = 5;
  const unsigned short VIOLATION_TYPE_HASH_SCRIPT   = 6;
  const unsigned short VIOLATION_TYPE_HASH_STYLE    = 7;

  /**
   * Called after the CSP object is created to fill in appropriate request
   * context and give it a reference to its owning principal for violation
   * report generation.
   * This will use whatever data is available, choosing earlier arguments first
   * if multiple are available.  Either way, it will attempt to obtain the URI,
   * referrer and the principal from whatever is available.  If the channel is
   * available, it'll also store that for processing policy-uri directives.
   */
  void setRequestContext(in nsIURI selfURI,
                         in nsIURI referrer,
                         in nsIPrincipal documentPrincipal,
                         in nsIChannel aChannel);

  /**
   * Verifies ancestry as permitted by the policy.
   *
   * NOTE: Calls to this may trigger violation reports when queried, so this
   * value should not be cached.
   *
   * @param docShell
   *    containing the protected resource
   * @return
   *    true if the frame's ancestors are all allowed by policy (except for
   *    report-only policies, which will send reports and then return true
   *    here when violated).
   */
  boolean permitsAncestry(in nsIDocShell docShell);

  /**
   * Delegate method called by the service when sub-elements of the protected
   * document are being loaded.  Given a bit of information about the request,
   * decides whether or not the policy is satisfied.
   *
   * Calls to this may trigger violation reports when queried, so
   * this value should not be cached.
   */
  short shouldLoad(in nsContentPolicyType aContentType,
                   in nsIURI          aContentLocation,
                   in nsIURI          aRequestOrigin,
                   in nsISupports     aContext,
                   in ACString        aMimeTypeGuess,
                   in nsISupports     aExtra);

%{ C++
// nsIObserver topic to fire when the policy encounters a violation.
#define CSP_VIOLATION_TOPIC "csp-on-violate-policy"
%}

};
