.. module:: flashpolicies.policies


Utilities for generating cross-domain policy files
==================================================

Internally, all policy files generated by django-flashpolicies are
represented by instances of :class:`flashpolicies.policies.Policy`,
which understands how to handle the various permitted options in
policy files and can generate the correct XML. This documentation
covers :class:`Policy` objects and their API, but is not and should
not be taken to be documentation on the format and options for
cross-domain policy files; `Adobe's cross-domain policy specification
<http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html>`_
is the canonical source for that information.


Simple interaction with :class:`Policy` objects
-----------------------------------------------

For most cases, simply instantiating a :class:`Policy` object with one
or more domains will accomplish the desired effect. The property
:attr:`~Policy.xml_dom` will yield an ``xml.dom.minidom.Document``
object representing the policy's XML; for information on working with
these objects, consult the documentation for `the xml.dom.minidom
module in the Python standard library
<http://docs.python.org/library/xml.dom.minidom.html>`_. In general,
however, calling ``str()`` with a ``Policy`` instance will be all
that's required; this will serialize the XML to a UTF-8-encoded
bytestring, suitable for writing to a file or serving over HTTP.

For example:

.. code-block:: pycon

   >>> from flashpolicies import policies
   >>> my_policy = policies.Policy('media.example.com', 'api.example.com')
   >>> print str(my_policy)
   <?xml version="1.0" encoding="utf-8"?>
   <!DOCTYPE cross-domain-policy
     SYSTEM 'http://www.adobe.com/xml/dtds/cross-domain-policy.dtd'>
   <cross-domain-policy>
           <allow-access-from domain="media.example.com"/>
           <allow-access-from domain="api.example.com"/>
   </cross-domain-policy>


API reference
-------------

.. class:: Policy

   Wrapper object for creating and manipulating a Flash cross-domain
   policy.

   In the simplest case -- specifying one or more domains from which
   to allow access -- simply pass the domains to the constructor. For
   example:

   .. code-block:: python

      my_policy = Policy('media.example.com', 'api.example.com')

   .. attribute:: xml_dom

      A read-only property which returns an XML representation of this
      policy, as an ``xml.dom.minidom.Document`` object.

   .. method:: allow_domain(domain, to_ports=None, secure=True)

      Allow access for Flash content served from a particular domain.

      :param domain: The domain from which to allow access. May be
         either a full domain name (e.g., ``example.com``) or a
         wildcard (e.g., ``*.example.com``). Due to serious potential
         security concerns, it is strongly recommended that you avoid
         wildcard domain values.
      :param to_ports: (only for socket policy files) A list of ports
         the domain will be permitted to access. Each value in the
         list may be either a port number (e.g., ``80``), a range of
         ports (e.g., ``"80-120"``) or the wildcard value ``"*"``,
         which will permit all ports.
      :param secure: If ``True``, will require the security level of
         the HTTP protocol for Flash content to match that of this
         policy file; for example, if the policy file was retrieved
         via HTTPS, Flash content from ``domain`` must also be
         retrieved via HTTPS. If ``False``, this matching of security
         levels will be disabled. It is strongly recommended that you
         not disable the matching of security levels.

   .. method:: allow_headers(domain, headers, secure=True)

      Allow Flash content from a particular domain to push data via
      HTTP headers.

      :param domain: The domain from which to allow access. May be
         either a full domain name (e.g., ``example.com``) or a
         wildcard (e.g., ``*.example.com``). Due to serious potential
         security concerns, it is strongly recommended that you avoid
         wildcard domain values.
      :param headers: A list of HTTP header names in which data may be
         submitted.
      :param secure: If ``True``, will require the security level of
         the HTTP protocol for Flash content to match that of this
         policy file; for example, if the policy file was retrieved
         via HTTPS, Flash content from ``domain`` must also be
         retrieved via HTTPS. If ``False``, this matching of security
         levels will be disabled. It is strongly recommended that you
         not disable the matching of security levels.

   .. method:: metapolicy(permitted)

      Set metapolicy information (only applicable to master policy
      files), determining which other policy files may be used on the
      same domain.

      :param permitted: The metapolicy to use. Acceptable values are
         `those listed in the cross-domain policy specification
         <http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html#site-control>`_,
         and are also available as :ref:`a set of constants defined in
         this module <metapolicy-constants>`. Passing an invalid
         value will raise ``TypeError``.

      By default, Flash assumes a default metapolicy of
      ``master-only`` (except for socket policies, which assume a
      default of ``all``), so if this is the desired metapolicy (and,
      for security reasons, it often is), this method does not need to
      be called.

      Note that a metapolicy of ``none`` forbids **all** access, even
      if one or more domains have previously been specified as
      allowed. As such, setting the metapolicy to ``none`` will remove
      all access previously granted by :meth:`allow_domain` or
      :meth:`allow_headers`. Additionally, attempting to grant access
      via :meth:`allow_domain` or :meth:`allow_headers` will, when the
      metapolicy is ``none``, raise ``TypeError``.


.. _metapolicy-constants:

Available constants
-------------------

For ease of working with metapolicies, the following constants are
defined, and correspond to `the acceptable values for metapolicies as
defined in the cross-domain policy specification
<http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html#site-control>`_.

.. data:: SITE_CONTROL_ALL

   All policy files available on the current domain are
   permitted. Actual value is the string ``"all"``.

.. data:: SITE_CONTROL_BY_CONTENT_TYPE

   Only policy files served from the current domain with an HTTP
   ``Content-Type`` of ``text/x-cross-domain-policy`` are
   permitted. Actual value is the string ``"by-content-type"``.

.. data:: SITE_CONTROL_BY_FTP_FILENAME

   Only policy files served from the current domain as files named
   ``crossdomain.xml`` are permitted. Actual value is the string
   ``"by-ftp-filename"``.

.. data:: SITE_CONTROL_MASTER_ONLY

   Only the master policy file for this domain -- the policy served
   from the URL ``/crossdomain.xml`` -- is permitted. Actual value is
   the string ``"master-only"``.

.. data:: SITE_CONTROL_NONE

   No policy files are permitted, including the master policy
   file. Actual value is the string ``"none"``.

.. data:: VALID_SITE_CONTROL

   A tuple containing the above constants, for convenient validation
   of metapolicy values.
