<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
  <!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
  <title>Pubsub Subscription Storage</title>
  <abstract>This document defines an XMPP protocol extension for storing subscriptions to Pubsub nodes.</abstract>
  &LEGALNOTICE;
  <number>0173</number>
  <status>Deferred</status>
  <type>Historical</type>
  <sig>Standards</sig>
  <approver>Council</approver>
  <dependencies>
    <spec>XMPP Core</spec>
    <spec>XEP-0049</spec>
    <spec>XEP-0060</spec>
  </dependencies>
  <supersedes/>
  <supersededby/>
  <shortname>pubsubs</shortname>
  <author>
    <firstname>Magnus</firstname>
    <surname>Henoch</surname>
    <email>henoch@dtek.chalmers.se</email>
    <jid>legoscia@jabber.cd.chalmers.se</jid>
  </author>
  <revision>
    <version>0.1</version>
    <date>2006-02-09</date>
    <initials>psa</initials>
    <remark><p>Initial version; changed title to Pubsub Subscription Storage; changed namespace to storage:pubsubs for consistency with other storage XEPs.</p></remark>
  </revision>
  <revision>
    <version>0.0.4</version>
    <date>2005-12-11</date>
    <initials>mh</initials>
    <remark><p>Add resource attribute.</p></remark>
  </revision>
  <revision>
    <version>0.0.3</version>
    <date>2005-11-13</date>
    <initials>mh</initials>
    <remark><p>Add subscription attribute.</p></remark>
  </revision>
  <revision>
    <version>0.0.2</version>
    <date>2005-10-28</date>
    <initials>mh</initials>
    <remark><p>Fix typo and schema.</p></remark>
  </revision>
  <revision>
    <version>0.0.1</version>
    <date>2005-10-25</date>
    <initials>mh</initials>
    <remark><p>First draft.</p></remark>
  </revision>
</header>
<section1 topic='Introduction' anchor='intro'>
  <p>&xep0060; allows Jabber entities to subscribe to various kinds of information, but provides no way of remembering which nodes a user has subscribed to.  Other protocols (e.g. &xep0080;, &xep0084;) allow information about a certain entity to be published to a Pubsub node.  These protocols use &xep0030; to allow other entities to find the pubsub node used by a certain entity, but provide no way of performing the opposite mapping, from pubsub node to information source.  This document attempts to fill that void, using &xep0049; for storing information about subscriptions.</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
  <p>This protocol enables Jabber clients to do the following:</p>
  <ul>
    <li>Remember which pubsub nodes the entity has subscribed to, and what kind of information is available at each node</li>
    <li>Update the mappings when subscriptions are added or removed</li>
    <li>Correlate incoming pubsub events to subscriptions</li>
  </ul>
</section1>
<section1 topic='Protocol' anchor='proto'>
  <p>The &lt;subscriptions/&gt; element qualified by the 'storage:pubsubs' namespace is the root element used in the jabber:iq:private transactions.  It has zero or more &lt;subscription/&gt; child elements, each of which MUST possess the following attributes:</p>

  <ul>
    <li><em>jid</em> -- The JID of the pubsub service used</li>
    <li><em>node</em> -- The pubsub node at which the data is available</li>
    <li><em>subscription</em> -- The current subscription state, one of "none", "pending", "unconfigured" and "subscribed"</li>
  </ul>

  <p>Additionally, the &lt;subscription/&gt; element MAY possess these attributes:</p>
  <ul>
    <li><em>resource</em> -- The resource that is subscribed to this pubsub node.  If the 'resource' attribute is absent, the bare JID is subscribed.</li>
    <li><em>user</em> -- The JID of the owner of this particular piece of data</li>
    <li><em>targetns</em> -- The namespace of the data in question</li>
  </ul>
</section1>
<section1 topic='Use Cases' anchor='usecases'>
  <section2 topic='Retrieving Existing Subscriptions' anchor='retrieving'>
    <p>In this example, the user already has a subscription to Juliet's geolocation, possibly established through another client.</p>
    <example caption='Client requests existing subscriptions'><![CDATA[
<iq type='get' id='retrieve1'>
  <query xmlns='jabber:iq:private'>
    <subscriptions xmlns='storage:pubsubs'/>
  </query>
</iq>
]]></example>
    <example caption='Server returns existing subscriptions'><![CDATA[
<iq type='result' id='retrieve1'>
  <query xmlns='jabber:iq:private'>
    <subscriptions xmlns='storage:pubsubs'>
      <subscription user='juliet@capulet.com'
		    jid='pubsub.capulet.com'
		    node='juliet/geoloc'
		    targetns='http://jabber.org/protocol/geoloc'
		    subscription='subscribed'/>
    </subscriptions>
  </query>
</iq>
]]></example>
  </section2>

  <section2 topic='Updating Subscriptions' anchor='updating'>
    <p>Due to the nature of XEP-0049, incremental updates are not possible; a client MUST send the entire &lt;subscriptions/&gt; node for each update.  Before performing the update, the client SHOULD retrieve the stored subscriptions, and incorporate any changes.</p>
    <p>In this example, the user has just subscribed to Romeo's tune (see &xep0118;).  Assuming that retrieving happened as in the previous use case, updating the subscriptions proceeds as follows:</p>
    <example caption='Client sends updated subscriptions'><![CDATA[
<iq type='set' id='update1'>
  <query xmlns='jabber:iq:private'>
    <subscriptions xmlns='storage:pubsubs'>
      <subscription user='juliet@capulet.com'
		    jid='pubsub.capulet.com'
		    node='juliet/geoloc'
		    targetns='http://jabber.org/protocol/geoloc'
		    subscription='subscribed'/>
      <subscription user='romeo@montague.net'
		    jid='pubsub.montague.net'
		    node='5017cdc9f4a3d1450445c9096064e459'
		    targetns='http://jabber.org/protocol/tune'
		    subscription='subscribed'/>
    </subscriptions>
  </query>
</iq>
]]></example>
    <example caption='Server reports success'><![CDATA[
<iq type='result' id='update1'/>
]]></example>
  </section2>

  <section2 topic='Identifying Incoming Events' anchor='identifying'>
    <p>Having recorded the retrieved mappings, the client is now prepared to identify incoming pubsub events.  Assume that the following event arrives:</p>
    <example caption='Client receives pubsub event'><![CDATA[
<message
    from='pubsub.montague.net'
    to='mercutio@shakespeare.lit'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='5017cdc9f4a3d1450445c9096064e459'>
      <item id='current'>
        <tune xmlns='http://jabber.org/protocol/tune'>
          <artist>Yes</artist>
          <title>Heart of the Sunrise</title>
          <source>Yessongs</source>
          <track>3</track>
          <length>686</length>
        </tune>
      </item>
    </items>
  </event>
</message>
]]></example>
    <p>The client now knows that this information comes from romeo@montague.net.</p>
  </section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
  <p>Pubsub events offer an opportunity to spoof sender addresses e.g. through 'replyto' data (as specified by the &xep0033; protocol).  This protocol attempts to close that hole.  It does so by the following rules and assumptions:</p>
  <ul>
    <li>A client MUST add mappings (i.e. associations between a publisher's JID and a pubsub node) only from trustworthy sources, i.e. published disco items (see &xep0030;).  This relies on disco information not being cracked or falsified.</li>
    <li>A client MUST retrieve mappings only from trustworthy sources, i.e. private XML storage.  This assumes that no-one but the user is able to change such information.</li>
  </ul>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
  <p>This document requires no interaction with &IANA;.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
  <p>No namespaces or parameters need to be registered with the &REGISTRAR; as a result of this document.</p>
</section1>
<section1 topic='XML Schema' anchor='schema'>
  <code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='storage:pubsubs'
    xmlns='storage:pubsubs'
    elementFormDefault='qualified'>

  <xs:element name='subscriptions'>
    <xs:complexType>
      <xs:sequence>
	<xs:element ref='subscription' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='subscription'>
    <xs:complexType>
      <xs:attribute name='jid' type='xs:string' use='required'/>
      <xs:attribute name='node' type='xs:string' use='required'/>
      <xs:attribute name='subscription' use='required'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='none'/>
            <xs:enumeration value='pending'/>
            <xs:enumeration value='subscribed'/>
            <xs:enumeration value='unconfigured'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='resource' type='xs:string' use='optional'/>
      <xs:attribute name='user' type='xs:string' use='optional'/>
      <xs:attribute name='targetns' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>

</xs:schema>
]]></code>
</section1>
</xep>
