1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-25 02:32:18 -05:00

reversion to 1.0

git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@373 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2007-01-18 16:04:00 +00:00
parent a9b09025c3
commit 9f0b6ebf9a

View File

@ -12,7 +12,7 @@
<number>0163</number> <number>0163</number>
<status>Draft</status> <status>Draft</status>
<type>Standards Track</type> <type>Standards Track</type>
<sig>Standards</sig> <sig>Standards JIG</sig>
<approver>Council</approver> <approver>Council</approver>
<dependencies> <dependencies>
<spec>XMPP Core</spec> <spec>XMPP Core</spec>
@ -31,12 +31,6 @@
<email>kevin@kismith.co.uk</email> <email>kevin@kismith.co.uk</email>
<jid>kevdadrum@jabber.ex.ac.uk</jid> <jid>kevdadrum@jabber.ex.ac.uk</jid>
</author> </author>
<revision>
<version>1.1pre2</version>
<date>in progress, last updated 2006-12-19</date>
<initials>psa</initials>
<remark><p>Replaced hardcoded NodeIDs (one node per namespace) with server-side namespace matching; specified semantic layering of data format, wrapper, and NodeID; defined registry for NodeIDs; more fully specified use of PEP for private data storage.</p></remark>
</revision>
<revision> <revision>
<version>1.0</version> <version>1.0</version>
<date>2006-09-20</date> <date>2006-09-20</date>
@ -148,21 +142,19 @@
</header> </header>
<section1 topic='Introduction' anchor='intro'> <section1 topic='Introduction' anchor='intro'>
<p>The XMPP &xep0060; extension ("pubsub") can be used to broadcast state change events associated with a Jabber/XMPP account or user, such as those described in &xep0080; or &xep0107;. <p>The XMPP &xep0060; extension ("pubsub") can be used to broadcast state change events associated with a Jabber/XMPP account or user, such as those described in &xep0080;, &xep0107;, &xep0108;, and &xep0118;. <note>Currently, many "extended presence" formats are sent using the &PRESENCE; stanza type; however, this overloads presence, results in unnecessary presence traffic, and does not provide fine-grained control over access. The use of publish-subscribe rather than presence is therefore preferable.</note> However, the full, generic pubsub protocol is often thought of as complicated and therefore has not been widely implemented. To make publish-subscribe functionality more accessible (especially to instant messaging and presence applications that conform to &xmppim;), this document defines simplified protocol semantics that can be followed by instant messaging client and server developers, hopefully resulting in the deployment of personal eventing services across the Jabber/XMPP network.</p>
<note>Currently, many "extended presence" formats are sent using the &PRESENCE; stanza type; however, this overloads presence, results in unnecessary presence traffic, and does not provide fine-grained control over access. The use of publish-subscribe rather than presence is therefore preferable.</note>
However, the full, generic pubsub protocol is often thought of as complicated and therefore has not been widely implemented. To make publish-subscribe functionality more accessible (especially to instant messaging and presence applications that conform to &xmppim;), this document defines simplified protocol semantics that can be followed by instant messaging client and server developers, hopefully resulting in the deployment of personal eventing services across the Jabber/XMPP network.</p>
<p><em>Note: This document does not show error flows related to the various publish-subscribe use cases referenced herein, since they are exhaustively defined in <cite>XEP-0060</cite>. The reader is referred to <cite>XEP-0060</cite> for all relevant protocol details related to the XMPP publish-subscribe extension.</em></p> <p><em>Note: This document does not show error flows related to the various publish-subscribe use cases referenced herein, since they are exhaustively defined in <cite>XEP-0060</cite>. The reader is referred to <cite>XEP-0060</cite> for all relevant protocol details related to the XMPP publish-subscribe extension.</em></p>
</section1> </section1>
<section1 topic='Concepts and Approach' anchor='approach'> <section1 topic='Concepts and Approach' anchor='approach'>
<p>Personal eventing via pubsub ("PEP") is based on the following principles:</p> <p>Personal eventing via pubsub ("PEP") is based on six principles:</p>
<ol start='1'> <ol start='1'>
<li>Every account a pubsub service.</li> <li>Every account a pubsub service.</li>
<li>One publisher per node.</li> <li>One publisher per node.</li>
<li>One node per namespace.</li>
<li>Use presence.</li> <li>Use presence.</li>
<li>Notifications are filtered based on expressed interests.</li> <li>Notifications are filtered based on expressed interests.</li>
<li>Smart defaults.</li> <li>Smart defaults.</li>
<li>Semantic layering.</li>
</ol> </ol>
<p>These principles are described more fully below.</p> <p>These principles are described more fully below.</p>
<section2 topic='Every Account a Pubsub Service' anchor='approach-everyjid'> <section2 topic='Every Account a Pubsub Service' anchor='approach-everyjid'>
@ -171,30 +163,24 @@
<section2 topic='One Publisher Per Node' anchor='approach-publisher'> <section2 topic='One Publisher Per Node' anchor='approach-publisher'>
<p>There is no need for multiple publishers to a PEP service, since by definition the service generates information associated with only one entity. The owner-publisher for every node is the bare JID of the account owner.</p> <p>There is no need for multiple publishers to a PEP service, since by definition the service generates information associated with only one entity. The owner-publisher for every node is the bare JID of the account owner.</p>
</section2> </section2>
<section2 topic='One Node Per Namespace' anchor='approach-onenode'>
<p>There is only one publish-subscribe node associated with any given payload type (XML namespace) for the account owner (e.g., there is one pubsub node for geolocation events, one node for tune events, and one node for mood events). This simplifies node creation, discovery, publishing, and subscribing.</p>
</section2>
<section2 topic='Use Presence' anchor='approach-presence'> <section2 topic='Use Presence' anchor='approach-presence'>
<p>Although generic publish-subscribe services do not necessarily have access to presence information about subscribers, PEP services are integrated with presence in the following ways:</p> <p>Although generic publish-subscribe services do not necessarily have access to presence information about subscribers, PEP services are integrated with presence in the following ways:</p>
<ul> <ul>
<li>Each messaging and presence account simply <em>is</em> a virtual publish-subscribe service.</li> <li>Each messaging and presence account simply <em>is</em> a virtual publish-subscribe service.</li>
<li>The default access model is "presence".</li> <li>The default access model is "presence".</li>
<li>A contact's subscription to an account owner's personal eventing data is normally handled via the existence of an XMPP presence subscription.</li> <li>A contact's subscription to an account owner's personal eventing data is normally handled via the existence of an XMPP presence subscription.</li>
<li>Services take account of subscriber presence in the generation of notifications. (Note: This works only if the subscription state is "both" as explained in <cite>RFC 3921</cite>.)</li> <li>Services take account of subscriber presence in the generation of notifications. <note>This works only if the subscription state is "both" (see <cite>RFC 3921</cite>).</note></li>
</ul> </ul>
<p>These uses of presence simplify the task of developing compliant clients (cf. &xep0134;).</p> <p>These uses of presence simplify the task of developing compliant clients (cf. &xep0134;).</p>
</section2> </section2>
<section2 topic='Filtered Notifications' anchor='approach-filter'> <section2 topic='Filtered Notifications' anchor='approach-filter'>
<p>By default, the existence of an XMPP presence subscription is used to establish a PEP subscription to the account owner's personal eventing data. In order to filter which notifications are sent by the PEP service, the contact's client includes extended &xep0115; information in the presence notifications it sends to the account owner. The PEP service then sends only those notifications that match the contact's expressed notification preferences, based on the "pubsub#type" of the nodes that match -- where the payload type is the wrapper namespace (if any) or, in the absence of a wrapper, the data format namespace (as described below under <link url='#approach-layering'>Semantic Layering</link>).</p> <p>By default, the existence of an XMPP presence subscription is used to establish a PEP subscription to the account owner's personal eventing data. In order to filter which notifications are sent by the PEP service, the contact's client includes extended &xep0115; information in the presence notifications it sends to the account owner, and the PEP service sends only those notifications that match the contact's expressed notification preferences.</p>
</section2> </section2>
<section2 topic='Smart Defaults' anchor='approach-defaults'> <section2 topic='Smart Defaults' anchor='approach-defaults'>
<p>Most pubsub configuration options and metadata are not needed for personal eventing. Instead, PEP services offer smart defaults to simplify node creation and management. The only required configuration options are the access model and the pubsub type (payload namespace).</p> <p>Most pubsub configuration options and metadata are not needed for personal eventing. Instead, PEP services offer smart defaults to simplify node creation and management.</p>
</section2>
<section2 topic='Semantic Layering' anchor='approach-layering'>
<p>There are several layers of meaning in personal eventing: <note>Version 1.0 of this specification included the principle that "there is only one publish-subscribe node associated with any given payload type (XML namespace) for the account owner (e.g., there is one pubsub node for geolocation events, one node for tune events, and one node for mood events)." The rationale for this principle was simplification of node creation, discovery, publishing, and subscribing. However, node discovery and subscribing are already simplified through the use of presence extensions. In addition, hardcoding NodeIDs in this way violates the core pubsub principle that NodeIDs shall be opaque. Therefore the "one node per namespace" principle was removed in version 1.1 of this specification in favor of NodeID registration.</note></p>
<ol>
<li>The innermost layer is the data format. This can be a generic format (such as jabber:x:data as defined in &xep0004; or Atom as defined in &rfc4287;) or a specific format such as &xep0108; or &xep0118;. If generic, it may be contained within a wrapper element (middle layer) to form the payload type; if specific, the format alone is the payload type.</li>
<li>The optional middle layer is a wrapper around a generic data format. For instance, the Atom format could be used to describe a wide range of particular information types, such as a weblog; or the jabber:x:data format could be used to structure a wide variety of forms. In this case, it may be desirable to define an optional wrapper element and namespace to differentiate between distinct uses of the data format; the wrapper and data format together describe the payload type.</li>
<li>The outermost layer is the NodeID. Although NodeIDs are opaque in the core pubsub specification, PEP defines a registry of NodeIDs for use in personal eventing as a means of differentiating between particular instances of the payload type (e.g., &xep0048; for groupchat rooms as opposed to web pages).</li>
</ol>
<p>Thus there is a one to many relationship between data formats and wrappers, and a one to many relationship between wrappers and NodeIDs. The examples below show the function of semantic layering in PEP.</p>
</section2> </section2>
</section1> </section1>
@ -205,7 +191,7 @@
<p>An owner-publisher juliet@capulet.com who publishes the following information:</p> <p>An owner-publisher juliet@capulet.com who publishes the following information:</p>
<ol start='1'> <ol start='1'>
<li>Tune information that anyone may see (i.e., an access model of "open")</li> <li>Tune information that anyone may see (i.e., an access model of "open")</li>
<li>Tune information that only subscribers to her presence may see (i.e., an access model of "presence")</li> <li>Activity information that only subscribers to her presence may see (i.e., an access model of "presence")</li>
<li>Geolocation information that only contacts in her "Friends" group may see (i.e., an access model of "roster" with a group of "Friends")</li> <li>Geolocation information that only contacts in her "Friends" group may see (i.e., an access model of "roster" with a group of "Friends")</li>
<li>Bookmark information that only the account owner may see (i.e., an access model of "whitelist")</li> <li>Bookmark information that only the account owner may see (i.e., an access model of "whitelist")</li>
</ol> </ol>
@ -258,20 +244,17 @@
<section1 topic='Account Owner Node Creation' anchor='owner-create'> <section1 topic='Account Owner Node Creation' anchor='owner-create'>
<p>When an account owner attempts to publish an item to a PEP node and that node does not already exist, the PEP service MUST automatically create the node with default configuration. <note>This similar to the room creation process in <cite>XEP-0045: Multi-User Chat</cite>.</note> However, if the account owner wishes to create a node with a configuration other than the default (e.g., a node with an access model of "open", "roster", or "whitelist"), the account owner MUST follow the node creation protocol specified in <cite>XEP-0060</cite>.</p> <p>When an account owner attempts to publish an item to a PEP node and that node does not already exist, the PEP service MUST automatically create the node with default configuration. <note>This similar to the room creation process in <cite>XEP-0045: Multi-User Chat</cite>.</note> However, if the account owner wishes to create a node with a configuration other than the default (e.g., a node with an access model of "open", "roster", or "whitelist"), the account owner MUST follow the node creation protocol specified in <cite>XEP-0060</cite>.</p>
<p>For example, Juliet would send the following stanzas in order to create the nodes mentioned above:</p> <p>For example, Juliet would send the following stanzas in order to create the nodes mentioned above:</p>
<example caption='Account owner creates open node for blog data'><![CDATA[ <example caption='Account owner creates open node for tune data'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='create-open'> <iq from='juliet@capulet.com/balcony' type='set' id='create-open'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='blog1'/> <create node='http://jabber.org/protocol/tune'/>
<configure> <configure>
<x xmlns='jabber:x:data' type='submit'> <x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'> <field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value> <value>http://jabber.org/protocol/pubsub#node_config</value>
</field> </field>
<field var='pubsub#access_model'> <field var='pubsub#access_model'>
<value>open</value> <option><value>open</value></option>
</field>
<field var='pubsub#type'>
<value>http://weblog.example.org/schema</value>
</field> </field>
</x> </x>
</configure> </configure>
@ -280,23 +263,19 @@
<iq to='juliet@capulet.com/balcony' type='result' id='create-open'/> <iq to='juliet@capulet.com/balcony' type='result' id='create-open'/>
]]></example> ]]></example>
<example caption='Account owner creates presence node for tune data'><![CDATA[ <example caption='Account owner publishes initial item to presence node for activity data'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='create-presence'> <iq from='juliet@capulet.com/balcony' type='set' id='create-presence'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='mytunes'/> <publish node='http://jabber.org/protocol/activity'/>
<configure> <item>
<x xmlns='jabber:x:data' type='submit'> <activity xmlns='http://jabber.org/protocol/activity'>
<field var='FORM_TYPE' type='hidden'> <relaxing>
<value>http://jabber.org/protocol/pubsub#node_config</value> <partying/>
</field> </relaxing>
<field var='pubsub#access_model'> <text xml:lang='en'>My nurse&apos;s birthday!</text>
<value>presence</value> </activity>
</field> </item>
<field var='pubsub#type'> </publish>
<value>http://jabber.org/protocol/tune</value>
</field>
</x>
</configure>
</pubsub> </pubsub>
</iq> </iq>
@ -305,20 +284,17 @@
<example caption='Account owner creates roster access node for geolocation data'><![CDATA[ <example caption='Account owner creates roster access node for geolocation data'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='create-roster'> <iq from='juliet@capulet.com/balcony' type='set' id='create-roster'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='mylocation'/> <create node='http://jabber.org/protocol/geoloc'/>
<configure> <configure>
<x xmlns='jabber:x:data' type='submit'> <x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'> <field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value> <value>http://jabber.org/protocol/pubsub#node_config</value>
</field> </field>
<field var='pubsub#access_model'> <field var='pubsub#access_model'>
<value>roster</value> <option><value>roster</value></option>
</field> </field>
<field var='pubsub#roster_groups_allowed'> <field var='pubsub#roster_groups_allowed'>
<value>Friends</value> <option><value>Friends</value></option>
</field>
<field var='pubsub#type'>
<value>http://jabber.org/protocol/geoloc</value>
</field> </field>
</x> </x>
</configure> </configure>
@ -330,17 +306,14 @@
<example caption='Account owner creates whitelist node for bookmark data'><![CDATA[ <example caption='Account owner creates whitelist node for bookmark data'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='create-whitelist'> <iq from='juliet@capulet.com/balcony' type='set' id='create-whitelist'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='storage:bookmarks:conference'/> <create node='storage:bookmarks'/>
<configure> <configure>
<x xmlns='jabber:x:data' type='submit'> <x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'> <field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#node_config</value> <value>http://jabber.org/protocol/pubsub#node_config</value>
</field> </field>
<field var='pubsub#access_model'> <field var='pubsub#access_model'>
<value>whitelist</value> <option><value>whitelist</value></option>
</field>
<field var='pubsub#type'>
<value>storage:bookmarks</value>
</field> </field>
</x> </x>
</configure> </configure>
@ -349,17 +322,111 @@
<iq to='juliet@capulet.com/balcony' type='result' id='create-whitelist'/> <iq to='juliet@capulet.com/balcony' type='result' id='create-whitelist'/>
]]></example> ]]></example>
<p>In the foregoing examples, we assume the following semantic layering:</p> </section1>
<ul>
<li>The open node has an unregistered NodeID of "blog1", a wrapper namespace of "http://weblog.example.org/schema", and a data format of "http://www.w3.org/2005/Atom" (where we assume that the wrapper namespace is defined by some other specification to include only elements qualified by the data format namespace).</li> <section1 topic='Contact Service Discovery' anchor='contact-disco'>
<li>The presence node has an unregistered NodeID of "mytunes" and a payload type of "http://jabber.org/protocol/tune".</li> <p>A contact MAY send service discovery requests to the account owner's bare JID (&BAREJID;). Although this is not necessary in order to subscribe to the account owner's personal eventing data (as explained in the following section), it is shown here to further illustrate the role of access models.</p>
<li>The roster node has an unregistered NodeID of "mylocation" and a payload type of "http://jabber.org/protocol/geoloc".</li> <p>First, benvolio@montague.net sends a disco#info request to juliet@capulet.com:</p>
<li>The whitelist node has a registered NodeID of "storage:bookmarks:conference" and a payload type of "storage:bookmarks".</li> <example caption='Unaffiliated entity queries account owner regarding identity'><![CDATA[
</ul> <iq from='benvolio@montague.net/home'
to='juliet@capulet.com'
id='disco2'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<p>If Juliet's server supports PEP (thereby making juliet@capulet.com a virtual pubsub service), it MUST return an identity of "pubsub/pep":</p>
<example caption='Server communicates protocol support'><![CDATA[
<iq from='juliet@capulet.com'
to='benvolio@montague.net/home'
id='disco2'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='pubsub' type='pep'/>
<identity category='account' type='registered'/>
...
</query>
</iq>
]]></example>
<p>Second, benvolio@montague.net sends a disco#items request to juliet@capulet.com:</p>
<example caption='Unaffiliated entity queries account owner regarding items'><![CDATA[
<iq from='benvolio@montague.net/home'
to='juliet@capulet.com'
id='disco3'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>The account owner's server MUST check the access model for each of the account owner's PEP nodes and MUST return as service discovery items only those nodes to which the contact is allowed to subscribe or from which the contact is allowed to retrieve items without first subscribing.</p>
<p>Therefore, in this case, the server would return only the "http://jabber.org/protocol/tune" node (since it has an open access model and the contact does not have a presence subscription to the account owner's presence):</p>
<example caption='Server returns appropriate items'><![CDATA[
<iq from='juliet@capulet.com'
to='benvolio@montague.net/home'
id='disco3'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/tune'/>
</query>
</iq>
]]></example>
<p>Next, nurse@capulet.com sends a disco#items request to juliet@capulet.com:</p>
<example caption='Contact with presence subscription queries account owner regarding items'><![CDATA[
<iq from='nurse@capulet.com/chamber'
to='juliet@capulet.com'
id='disco4'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>However, in this case, the server would return the "http://jabber.org/protocol/tune" node (open access model) <em>and</em> the "http://jabber.org/protocol/activity" node (presence access model):</p>
<example caption='Server returns appropriate items'><![CDATA[
<iq from='juliet@capulet.com'
to='nurse@capulet.com/chamber'
id='disco4'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/tune'/>
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/activity'/>
</query>
</iq>
]]></example>
<p>Finally, romeo@montague.net sends a disco#items request to juliet@capulet.com:</p>
<example caption='Contact with presence subscription and in privileged roster group queries account owner regarding items'><![CDATA[
<iq from='romeo@montague.net/orchard'
to='juliet@capulet.com'
id='disco5'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
]]></example>
<p>In this case, the server would return the "http://jabber.org/protocol/tune" node (open access model) <em>and</em> the "http://jabber.org/protocol/activity" node (presence access model) <em>and</em> the "http://jabber.org/protocol/geoloc" node (roster access model):</p>
<example caption='Server returns appropriate items'><![CDATA[
<iq from='juliet@capulet.com'
to='romeo@montague.net/orchard'
id='disco5'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/tune'/>
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/activity'/>
<item jid='juliet@capulet.com' node='http://jabber.org/protocol/geoloc'/>
</query>
</iq>
]]></example>
</section1> </section1>
<section1 topic='Contact Subscription' anchor='contact-subscribe'> <section1 topic='Contact Subscription' anchor='contact-subscribe'>
<p>If an entity is not subscribed to the account owner's presence, it MUST discover and then subscribe to a node using the protocol defined in <cite>XEP-0060</cite>. However, when a contact and account owner are subscribed to each other's presence, PEP greatly simplifies the subscription process. This is done by associating the presence subscription with a pubsub subscription to the account owner's root collection node (i.e., bare JID), with a subscription_type of "items" and a subscription_depth of "all".</p> <p>If an entity is not subscribed to the account owner's presence, it MUST subscribe to a node using the protocol defined in <cite>XEP-0060</cite>. For instance, here is how benvolio@montague.net would subscribe Juliet's tune information:</p>
<example caption='Unaffiliated entity subscribes to an open node'><![CDATA[
<iq type='set'
from='benvolio@montague.net/home'
to='juliet@capulet.com'
id='sub1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscribe node='http://jabber.org/protocol/tune' jid='benvolio@montague.net'/>
</pubsub>
</iq>
]]></example>
<p>However, when a contact is affiliated with the account owner through a presence subscription, PEP greatly simplifies the subscription process. This is done by associating the presence subscription with a pubsub subscription to the account owner's root collection node (i.e., bare JID), with a subscription_type of "items" and a subscription_depth of "all".</p>
<p>Consider the following presence subscription exchange:</p> <p>Consider the following presence subscription exchange:</p>
<example caption='Presence subscription handshake'><![CDATA[ <example caption='Presence subscription handshake'><![CDATA[
<presence from='nurse@capulet.com' to='juliet@capulet.com' type='subscribe'/> <presence from='nurse@capulet.com' to='juliet@capulet.com' type='subscribe'/>
@ -400,7 +467,7 @@
<example caption='Account owner publishes item'><![CDATA[ <example caption='Account owner publishes item'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='pub1'> <iq from='juliet@capulet.com/balcony' type='set' id='pub1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='mytunes'> <publish node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
@ -423,7 +490,7 @@
type='headline' type='headline'
id='foo'> id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='mytunes'> <items node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
@ -442,7 +509,7 @@
type='headline' type='headline'
id='foo'> id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='mytunes'> <items node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
@ -464,7 +531,7 @@
type='headline' type='headline'
id='foo'> id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='mytunes'> <items node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
@ -486,9 +553,9 @@
<section1 topic='Contact Notification Filtering' anchor='contact-filter'> <section1 topic='Contact Notification Filtering' anchor='contact-filter'>
<p>A contact may not want to receive notifications for all payload types. A contact SHOULD signal its preferences to the account owner's server by including <cite>XEP-0115</cite> information that specifies the namespaces for which the contact wishes to receive notifications (if any).</p> <p>A contact may not want to receive notifications for all payload types. A contact SHOULD signal its preferences to the account owner's server by including <cite>XEP-0115</cite> information that specifies the namespaces for which the contact wishes to receive notifications (if any).</p>
<p>In order to make this possible, all possible payload namespaces can be appended with the string "+notify" to indicate that the contact wishes to receive notifications for the payload format. Thus if Romeo wants to receive notifications for tune data and geolocation data but not blog data, his client would advertise support for the following namespaces in the disco#info results it sends: <note>Including, say, the 'http://jabber.org/protocol/geoloc' namespace indicates that the client understands the geolocation namespace, whereas including the 'http://jabber.org/protocol/geoloc+notify' namespace indicates that the client wishes to receive notifications related to geolocation.</note></p> <p>In order to make this possible, all possible payload namespaces can be appended with the string "+notify" to indicate that the contact wishes to receive notifications for the payload format. Thus if Romeo wants to receive notifications for activity data and geolocation data but not tune data, his client would advertise support for the following namespaces in the disco#info results it sends: <note>Including, say, the 'http://jabber.org/protocol/geoloc' namespace indicates that the client understands the geolocation namespace, whereas including the 'http://jabber.org/protocol/geoloc+notify' namespace indicates that the client wishes to receive notifications related to geolocation.</note></p>
<ul> <ul>
<li>http://jabber.org/protocol/tune+notify</li> <li>http://jabber.org/protocol/activity+notify</li>
<li>http://jabber.org/protocol/geoloc+notify</li> <li>http://jabber.org/protocol/geoloc+notify</li>
</ul> </ul>
<p>This set of namespaces would then be advertised as a <cite>XEP-0115</cite> "ext" value, such as the following:</p> <p>This set of namespaces would then be advertised as a <cite>XEP-0115</cite> "ext" value, such as the following:</p>
@ -501,7 +568,7 @@
</presence> </presence>
]]></example> ]]></example>
<p>Note: In <cite>XEP-0115</cite>, the "ext" values are opaque strings with no semantic meaning.</p> <p>Note: In <cite>XEP-0115</cite>, the "ext" values are opaque strings with no semantic meaning.</p>
<p>It is the responsibility of the account owner's server to cache <cite>XEP-0115</cite> information (including "ext" values and their associated namespaces). When a PEP-enabled server receives presence from a contact, it MUST check that presence information for entity capabilities data and correlate that data with the desired namespaces for the contact's client. The server MUST NOT send notifications related to any data formats that the contact's client has not asked for via the relevant "namespace+notify" disco#info feature. This enables a client to turn off all notifications (e.g., because of bandwidth restrictions) and to easily receive all desired data formats simply by adding support for the appropriate "namespace+notify" combination in its disco#info results and client capabililies. However, it also implies that a client can request notifications only on a global basis and cannot request, say, mood information only from certain contacts in the user's roster. Community consensus is that this is an acceptable tradeoff. Also, note that this works only if the account owner has a presence subscription to the contact and the contact has a presence subscription to the account owner.</p> <p>It is the responsibility of the account owner's server to cache <cite>XEP-0115</cite> information (including "ext" values and their associated namespaces). When the server receives presence from a contact, it MUST check that presence information for entity capabilities data and correlate that data with the desired namespaces for the contact's client. The server MUST NOT send notifications related to any data formats that the contact's client has not asked for via the relevant "namespace+notify" disco#info feature. This enables a client to turn off all notifications (e.g., because of bandwidth restrictions) and to easily receive all desired data formats simply by adding support for the appropriate "namespace+notify" combination in its disco#info results and client capabililies. However, it also implies that a client can request notifications only on a global basis and cannot request, say, mood information only from certain contacts in the user's roster. Community consensus is that this is an acceptable tradeoff. Also, note that this works only if the account owner has a presence subscription to the contact and the contact has a presence subscription to the account owner.</p>
<p>Some examples may help to illustrate the concept of notification filtering. Here we show presence generated by two of the contacts listed above (benvolio@montague.net does have any presence subscriptions to or from juliet@capulet.com and therefore is not involved in these protocol flows).</p> <p>Some examples may help to illustrate the concept of notification filtering. Here we show presence generated by two of the contacts listed above (benvolio@montague.net does have any presence subscriptions to or from juliet@capulet.com and therefore is not involved in these protocol flows).</p>
<example caption='Presence with caps'><![CDATA[ <example caption='Presence with caps'><![CDATA[
<presence from='nurse@capulet.com/chamber'> <presence from='nurse@capulet.com/chamber'>
@ -534,10 +601,10 @@
id='disco123'> id='disco123'>
<query xmlns='http://jabber.org/protocol/disco#info' <query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#0.9'/> node='http://exodus.jabberstudio.org/caps#0.9'/>
<feature var='http://weblog.example.org/schema'/>
<feature var='http://weblog.example.org/schema+notify'/>
<feature var='http://jabber.org/protocol/tune'/> <feature var='http://jabber.org/protocol/tune'/>
<feature var='http://jabber.org/protocol/tune+notify'/> <feature var='http://jabber.org/protocol/tune+notify'/>
<feature var='http://jabber.org/protocol/activity'/>
<feature var='http://jabber.org/protocol/activity+notify'/>
<feature var='http://jabber.org/protocol/geoloc'/> <feature var='http://jabber.org/protocol/geoloc'/>
<feature var='http://jabber.org/protocol/geoloc+notify'/> <feature var='http://jabber.org/protocol/geoloc+notify'/>
</query> </query>
@ -558,8 +625,8 @@
id='disco234'> id='disco234'>
<query xmlns='http://jabber.org/protocol/disco#info' <query xmlns='http://jabber.org/protocol/disco#info'
node='http://www.chatopus.com/ec#2.1'/> node='http://www.chatopus.com/ec#2.1'/>
<feature var='http://weblog.example.org/schema'/>
<feature var='http://jabber.org/protocol/tune'/> <feature var='http://jabber.org/protocol/tune'/>
<feature var='http://jabber.org/protocol/activity'/>
<feature var='http://jabber.org/protocol/geoloc'/> <feature var='http://jabber.org/protocol/geoloc'/>
<feature var='http://jabber.org/protocol/geoloc+notify'/> <feature var='http://jabber.org/protocol/geoloc+notify'/>
</query> </query>
@ -567,9 +634,9 @@
]]></example> ]]></example>
<p>Now we revisit account owner publication and server generation of notifications, with filtering enabled because the server has caps information:</p> <p>Now we revisit account owner publication and server generation of notifications, with filtering enabled because the server has caps information:</p>
<ul> <ul>
<li><p>If Juliet publishes a blog item to the open-access "blog1" node (pubsub type "http://weblog.example.org/schema" node, her server will send notifications to &lt;benvolio@montague.net&gt; (bare JID) and to &lt;nurse@capulet.com/chamber&gt; (full JID) but not to &lt;romeo@montague.net/orchard&gt;.</p></li> <li><p>If Juliet publishes a tune item to the open-access "http://jabber.org/protocol/tune" node, her server will send notifications to &lt;benvolio@montague.net&gt; (bare JID) and to &lt;nurse@capulet.com/chamber&gt; (full JID) but not to &lt;romeo@montague.net/orchard&gt;.</p></li>
<li><p>If Juliet publishes a tune item to the presence-access "mytunes" node (pubsub type "http://jabber.org/protocol/tune"), her server will send notifications only to &lt;nurse@capulet.com/chamber&gt;.</p></li> <li><p>If Juliet publishes an activity item to the presence-access "http://jabber.org/protocol/activity" node, her server will send notifications only to &lt;nurse@capulet.com/chamber&gt;.</p></li>
<li><p>If Juliet publishes a geolocation item to the roster-access "mylocation" node (pubsub type "http://jabber.org/protocol/geoloc"), her server will send notifications only to &lt;romeo@montague.net/orchard&gt;.</p></li> <li><p>If Juliet publishes a geolocation item to the roster-access "http://jabber.org/protocol/geoloc" node, her server will send notifications only to &lt;romeo@montague.net/orchard&gt;.</p></li>
</ul> </ul>
</section1> </section1>
@ -614,7 +681,7 @@
type='headline' type='headline'
id='foo'> id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='mytunes'> <items node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
@ -632,20 +699,14 @@
</section1> </section1>
<section1 topic='Private Data Storage' anchor='privatedata'> <section1 topic='Private Data Storage' anchor='privatedata'>
<p>As noted, PEP services can be used to implement so-called "private data storage", similar in functionality to the dedicated protocol described in &xep0049; (which is often used for storing client preferences, user bookmarks, and the like). In essence, a private node is a pubsub node whose access model is "whitelist", where there are no entities in the whitelist (the account owner is automatically granted access to the node and therefore receives all node events and can retrieve items from the node at will). This results in the following functionality:</p> <p>As noted, PEP services may be used to implement private data storage, such as defined in &xep0049;. A future version of this document will specify this usage in more detail.</p>
<ul>
<li>The account owner is able to create as many private data nodes as desired (e.g., for client preferences, bookmarks, public keys, etc.).</li>
<li>The account owner is able to create any number of privata data nodes per payload namespace (e.g., different sets of bookmarks).</li>
<li>The account owner is able to add and delete private data in a granular fashion (not by updating the entire data store for the relevant namespace as in <cite>XEP-0049</cite>).</li>
<li>Each of the account owner's resources will receive notifications related to data updates (based on PEP's dynamic namespace matching).</li>
</ul>
</section1> </section1>
<section1 topic='Recommended Defaults' anchor='defaults'> <section1 topic='Recommended Defaults' anchor='defaults'>
<p>A PEP service MUST:</p> <p>A PEP service MUST:</p>
<ul> <ul>
<li>Support the node discovery, node creation, node deletion, publish item, subscribe, unsubscribe, and item retrieval use cases specified in <cite>XEP-0060</cite>.</li> <li>Support the node discovery, node creation, node deletion, publish item, subscribe, unsubscribe, and item retrieval use cases specified in <cite>XEP-0060</cite>.</li>
<li>Support the "owner" affiliation and (for subscribers) an affiliation of "none".</li> <li>Support the "owner" and "subscriber" affiliations.</li>
<li>Support the "presence" access model and set it to the default.</li> <li>Support the "presence" access model and set it to the default.</li>
<li>Support the "open", "roster", and "whitelist" access models.</li> <li>Support the "open", "roster", and "whitelist" access models.</li>
<li>Treat the account owner's bare JID (&BAREJID;) as a collection node (i.e., as the root collection node for the account's virtual pubsub service).</li> <li>Treat the account owner's bare JID (&BAREJID;) as a collection node (i.e., as the root collection node for the account's virtual pubsub service).</li>
@ -656,10 +717,7 @@
<p>A PEP service MAY support other use cases, affiliations, access models, and features, but such support is OPTIONAL.</p> <p>A PEP service MAY support other use cases, affiliations, access models, and features, but such support is OPTIONAL.</p>
</section1> </section1>
<section1 topic='Implementation Notes' anchor='impl'> <section1 topic='Implementation Notes' anchor='imple'>
<section2 topic='Registered NodeIDs' anchor='impl-nodeids'>
<p>A service SHOULD support all NodeIDs that are registered with the XMPP Registrar as described in the <link url='#registrar-pepnodes'>PEP Nodes</link> section of this document. This support shall include enforcement of the NodeID within the context of a given account, the payload type (whether wrapper or data format namespace), and any other configuration defaults as specified in the registry (this enables clients to perform seamless publish-and-create in one step).</p>
</section2>
<section2 topic='Cancelling Subscriptions' anchor='impl-subscriptions'> <section2 topic='Cancelling Subscriptions' anchor='impl-subscriptions'>
<p>In order to ensure appropriate access to information published at nodes of type "presence" and "roster", a PEP service MUST re-calculate access controls when:</p> <p>In order to ensure appropriate access to information published at nodes of type "presence" and "roster", a PEP service MUST re-calculate access controls when:</p>
<ol start='1'> <ol start='1'>
@ -696,22 +754,6 @@
</category> </category>
]]></code> ]]></code>
</section2> </section2>
<section2 topic='PEP Nodes Registry' anchor='registrar-pepnodes'>
<p>The XMPP Registrar shall create a registry of PEP nodes.</p>
&REGPROCESS;
<code><![CDATA[
<node>
<id>the NodeID for the PEP node</id>
<desc>a natural-language description of the PEP node</desc>
<spec>the specification in which the PEP node is specified</spec>
<field var='pubsub_configuration_field_name'>
<value>default_value</value>
</field>
</node>
]]></code>
<p>Note: The "pubsub_configuration_field_name" and "default_value" strings are as registered for the "pubsub#node_config" FORM_TYPE by <cite>XEP-0060</cite>.</p>
<p>The registrant may register more than one PEP node at a time, each contained in a separate &lt;node/&gt; element.</p>
</section2>
</section1> </section1>
<section1 topic='XML Schema' anchor='schema'> <section1 topic='XML Schema' anchor='schema'>
@ -719,7 +761,7 @@
</section1> </section1>
<section1 topic='Acknowledgements' anchor='ack'> <section1 topic='Acknowledgements' anchor='ack'>
<p>The authors wish to thank the participants in the XMPP Interoperability Testing Event held July 24 and 25, 2006, who provided valuable feedback that resulted in radical simplification of the protocol. Thanks also to Ralph Meijer and Ian Paterson for helpful discussions related to payload types and NodeID registration.</p> <p>The authors wish to thank the participants in the XMPP Interoperability Testing Event held July 24 and 25, 2006, who provided valuable feedback that resulted in radical simplification of the protocol.</p>
</section1> </section1>
</xep> </xep>