Setting up XMPP Publish-Subscribe nodes: item-forbidden error posting items to the node - xmpp

I'm trying to set up an XMPP Publish-Subscribe node and to configure it such that when new items are posted to the node, the payload gets automatically delivered to all the subscribers.
For this I am setting the "pubsub#deliver_payloads" configuration option to true, but when posting items to the node, I get an error. Here are the details of what I'm doing:
First I create the node:
<body rid='614709033' xmlns='http://jabber.org/protocol/httpbind' sid='515c16e0'>
<iq to='pubsub.myserver' type='set' xmlns='jabber:client' id='2:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<create node='mynode'/>
</pubsub>
</iq>
</body>
The server replies saying that it's ok:
<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xmlns="jabber:client" type="result" id="2:sendIQ" from="pubsub.myserver" to="user#myserver/515c16e0"/>
</body>
Then I configure the node setting the "pubsub#deliver_payloads" option to "true", in this way:
<body rid='614709036' xmlns='http://jabber.org/protocol/httpbind' sid='515c16e0'>
<iq from='user#myserver' to='pubsub.myserver' type='set' xmlns='jabber:client' id='4:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='mynode'>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#deliver_payloads'>
<value>true</value>
</field>
</x>
</configure>
</pubsub>
</iq>
</body>
The server replies successfully:
<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xmlns="jabber:client" type="result" id="4:sendIQ" from="pubsub.myserver" to="user#myserver/515c16e0"/>
</body>
But when I try to post some data onto that node, like this:
<body rid='614709038' xmlns='http://jabber.org/protocol/httpbind' sid='515c16e0'>
<iq type='set' to='pubsub.myserver' xmlns='jabber:client' id='5:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='mynode'>
<item id='test'>
<geoloc xmlns='http://jabber.org/protocol/geoloc' xml:lang='en'>
<lat>0.55</lat>
<lon>1.66</lon>
<timestamp>2014-04-02T15:14:58.783Z</timestamp>
</geoloc>
</item>
</publish>
</pubsub>
</iq>
</body>
The server replies with this error:
<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xmlns="jabber:client" type="error" id="5:sendIQ" from="pubsub.myserver" to="user#myserver/515c16e0">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish node="mynode">
<item id="test">
<geoloc xmlns="http://jabber.org/protocol/geoloc" xml:lang="en">
<lat>0.55</lat>
<lon>1.66</lon>
<timestamp>2014-04-02T15:14:58.783Z</timestamp>
</geoloc>
</item>
</publish>
</pubsub>
<error code="400" type="modify">
<bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<item-forbidden xmlns="http://jabber.org/protocol/pubsub#errors"/>
</error>
</iq>
</body>
I'm using Openfire 3.9.1 as a server, while on the client side I'm using javascript and the Strophe library.
Can anyone explain me why I get this error?
I tried to use different configurations on the node, and when I omit the "pubsub#deliver_payloads" option I get no errors while posting items to the node...

All error conditions are explained in XEP-0060: Publish-Subscribe. You can find the item-forbidden error message at 7.1.3.6 Request Does Not Match Configuration, where it reads:
If the event type is notification + transient and the publisher
provides an item, the service MUST bounce the publication request with
a error and a pubsub-specific error condition of
.

Ok, I see, having only the option "pubsub#deliver_payloads" in the configuration the node is considered a "transient node" (no items allowed).
However, if I change the configuration to make the node "persistent" (i.e. adding the "pubsub#persist_items" and setting it to true), the server should not complain, according to 4.3 Event Types of the XEP-0060, Table 4.
But with this configuration:
<iq from='user#myserver' to='pubsub.myserver' type='set' xmlns='jabber:client' id='5:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='mynode'>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#persist_items'>
<value>true</value>
</field>
<field var='pubsub#deliver_payloads'>
<value>true</value>
</field>
</x>
</configure>
</pubsub>
</iq>
if I try to post an item to the node I still get the same error:
<iq xmlns="jabber:client" type="error" id="13:sendIQ" from="pubsub.myserver" to="user#myserver/2b35c426">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish node="mynode">
<item id="test">
<geoloc xmlns="http://jabber.org/protocol/geoloc" xml:lang="en">
<lat>0.55</lat>
<lon>1.66</lon>
<timestamp>2014-04-03T08:50:48.682Z</timestamp>
</geoloc>
</item>
</publish>
</pubsub>
<error code="400" type="modify">
<bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<item-forbidden xmlns="http://jabber.org/protocol/pubsub#errors"/>
</error>
</iq>
I solved the problem by simply chenging the value in the configuration from "true" to "1". Actually while reading the XEP-0060 specifications, both "true" - "false" and "1" - "0" values are used in configuration examples. However, in the form that the Openfire server sends me when I ask to configure the node, only "1" - "0" values are used.
With the following configuration all works fine:
<iq from='user#myserver' to='pubsub.myserver' type='set' xmlns='jabber:client' id='5:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='mynode'>
<x xmlns='jabber:x:data' type='submit'>
<field var='pubsub#persist_items'>
<value>1</value>
</field>
<field var='pubsub#deliver_payloads'>
<value>1</value>
</field>
</x>
</configure>
</pubsub>
</iq>

Related

ejabberd MucSub not working

I'm working on developing an XMPP Client communicating over an ejabberd community server (version 17.09) that we host ourselves.
I'm having trouble to implement the MucSub Feature (supported since version 16.08 as far as I know).
When I'm sending this XML command (described in the ejabberd documentation for subscribing to a chatroom):
<iq from='hag66#shakespeare.example'
to='coven#muc.shakespeare.example'
type='set'
id='E6E10350-76CF-40C6-B91B-1EA08C332FC7'>
<subscribe xmlns='urn:xmpp:mucsub:0'
nick='mynick'
password='roompassword'>
<event node='urn:xmpp:mucsub:nodes:messages' />
<event node='urn:xmpp:mucsub:nodes:affiliations' />
<event node='urn:xmpp:mucsub:nodes:subject' />
<event node='urn:xmpp:mucsub:nodes:config' />
</subscribe>
</iq>
(of course entering existing jid's for this server, allow_subscription set to true for this chatroom) I get the result:
<iq xml:lang='de'
to='hag66#shakespeare.example'
from='coven#muc.shakespeare.example'
type='error' id='E6E10350-76CF-40C6-B91B-1EA08C332FC7'>
<subscribe xmlns='urn:xmpp:mucsub:0' nick='mynick'>
<event node='urn:xmpp:mucsub:nodes:messages'/>
<event node='urn:xmpp:mucsub:nodes:affiliations'/>
<event node='urn:xmpp:mucsub:nodes:subject'/>
<event node='urn:xmpp:mucsub:nodes:config'/>
</subscribe>
<error code='503' type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<text xml:lang='de' xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>No module is handling this query</text>
</error>
</iq>
When I alter the query to:
<iq from='hag66#shakespeare.example'
to='coven#muc.shakespeare.example'
type='set'
id='E6E10350-76CF-40C6-B91B-1EA08C332FC7'>
<subscribe xmlns='urn:xmpp:mucsub:0'
nick='mynick'
password='roompassword'>
<event xmlns="http://jabber.org/protocol/pubsub#event" node="urn:xmpp:mucsub:nodes:messages" />
<event xmlns="http://jabber.org/protocol/pubsub#event" node="urn:xmpp:mucsub:nodes:affiliations' />
<event xmlns="http://jabber.org/protocol/pubsub#event" node="urn:xmpp:mucsub:nodes:subject' />
<event xmlns="http://jabber.org/protocol/pubsub#event" node="urn:xmpp:mucsub:nodes:config' />
</subscribe>
</iq>
I get the result:
<iq xmlns="jabber:client"
to="hag66#shakespeare.example"
xml:lang="en"
type="result"
from="coven#muc.shakespeare.example"
id="agsXMPP_8">
<subscribe xmlns="urn:xmpp:mucsub:0" nick="mynick" />
</iq>
which I interpret as the query being successfull. Also when I query the Chatrooms this user is subscribed to the chatroom is listed.
My Problem now is: no matter which of this methods I use, the user does not get notifications for messages in that chat if he is not present in exactly this chatroom.
Now the strangest thing is: if I get DiscoInfo from the server the MucSub Feature (urn:xmpp:mucsub:0) is not listed, which I don't understand as the Feature is supported by the server version I'm using and according to the documentation is enabled by default and can't even be disabled.
Has anyone experienced the same issue and/or knows how to resolve it?
Thanks in advance for your help
So finally we found the issue:
instead of sending the request to "coven#muc.shakespeare.example" we were sending it to "coven#shakespeare.example" which didn't work and was forgotten to change in the questions text

ejabberd MUC client unable to get configuration form after creating room

I was trying to create a MUC room from my XMPP client side communicating with Ejabberd.
Here's my Ejabberd muc config:
mod_muc:
## host: "conference.#HOST#"
access: muc
access_create: muc_create
access_persistent: mud_create
access_admin: muc_admin
db_type: odbc
max_user_conferences: 100
default_room_options:
mam: true
public: false
public_list: false
allow_change_subj: false
allow_user_invites: false
members_only: false
members_by_default: false
anonymous: false
allow_private_messages: true
persistent: true
Here's the features I got from the client side on muc:
<iq xmlns='jabber:client' from='conference.my.domain.com' to='my_id#my.domain.com/null' id='iqid1:sendIQ' type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='conference' type='text' name='Chatrooms'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='http://jabber.org/protocol/disco#items'/>
<feature var='http://jabber.org/protocol/muc'/>
<feature var='http://jabber.org/protocol/muc#unique'/>
<feature var='jabber:iq:register'/>
<feature var='http://jabber.org/protocol/rsm'/>
<feature var='vcard-temp'/>
<feature var='urn:xmpp:mam:tmp'/>
<feature var='urn:xmpp:mam:0'/>
<feature var='urn:xmpp:mam:1'/>
<x xmlns='jabber:x:data' type='result'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/network/serverinfo</value>
</field>
</x>
</query>
</iq>
When I tried to create a MUC room from my client side with:
<presence from='my_id#my.domain.com/null' to='new_room_id#conference.my.domain.com/my_nickname' xmlns='jabber:client'>
<x xmlns='http://jabber.org/protocol/muc'/>
</presence>
I got a new room created response:
<presence xmlns='jabber:client' from='new_room_id#conference.my.domain.com/my_nickname' to='my_id#my.domain.com/null'>
<x xmlns='http://jabber.org/protocol/muc#user'>
<item jid='my_id#my.domain.com/null' affiliation='owner' role='moderator'/>
<status code='110'/>
<status code='100'/>
<status code='201'/>
</x>
</presence>
When I tried to get the configuration form to set up room fields with:
<iq from='my_id#my.domain.com/null' to='new_room_id#conference.my.domain.com/my_nickname' type='get' xmlns='jabber:client' id='iqid2:sendIQ'>
<query xmlns='http://jabber.org/protocol/muc#owner'/>
</iq>
I got the answer from Ejabberd server:
<iq xmlns='jabber:client' from='new_room_id#conference.my.domain.com/my_nickname' to='my_id#my.domain.com/null' id='iqid2:sendIQ' type='get'>
<query xmlns='http://jabber.org/protocol/muc#owner'/>
</iq>
So here are my questions:
Why does Ejabberd server response to my queries with the same type, but not with something like type='result' or type='error'? I've tried other queries with type='set', the same thing happened.
Why aren't there something like : <feature var='http://jabber.org/protocol/muc#owner'/> or <feature var='http://jabber.org/protocol/muc#admin'/> in the features on muc service?
It seems possible to create v-card for rooms, how does it work? Does it require some additionnal configurations on the server side?
Actually, you are not sending the packet to the room but to user nickname: 'new_room_id#conference.my.domain.com/my_nickname'. Thus, the packet you send is routed back to you. Remove "/my_nickname" and you will be able to talk to the room itself and get your configuration form.
As Mickaël points out, you're just sending the <iq/> to your own occupant address, so ejabberd is passing it back to you.
For your other questions:
Interesting - I tried it out and read the Service Discovery XEP, and I think it's basically considered redundant. The #owner, #admin and #user namespaces are components of MUC, so you should assume their support just from http://jabber.org/protocol/muc. As you can see in XEP-0030, the reference example does not include them either: http://xmpp.org/extensions/xep-0030.html#example-2
I don't think vcard-temp means you can set anything - you can only request the MUC server's vCard, which returned
<vCard xmlns='vcard-temp'>
<FN>ejabberd/mod_muc</FN>
<URL>http://www.process-one.net/en/ejabberd/</URL>
<DESC>
ejabberd MUC module
Copyright (c) 2003-2011 ProcessOne
</DESC>
</vCard>
when I tried it.

ejabberd MAM does not work for MUC

xep-0313 works for rosters, but does not work for room chat.
I can get archive message for the rosters, but I can not get archive message for the room, why?
<iq type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>urn:xmpp:mam:0</value>
</field>
<field var='with'>
<value>roomJid#conference.host</value>
</field>
</x>
</query>
</iq>
The receive message is:
<message xmlns="jabber:client" from="test3#192.168.1.67" to="test3#192.168.1.67/iPhone" id="dHS0oejBDWHp”>
<fin xmlns="urn:xmpp:mam:0" complete="true”>
<set xmlns="http://jabber.org/protocol/rsm”/>
</fin>
<no-copy xmlns="urn:xmpp:hints”/>
</message>
I guess you are using ejabberd contributed module. However, a new official MAM module has been added to official ejabberd and it support latest version of MAM (0.4 as of today) and MUC archiving.
It has been released in ejabberd 15.06. You can can also get direct access to source from ejabberd Github repository. The module is here: https://github.com/processone/ejabberd/blob/master/src/mod_mam.erl

Unable to publish in pubsub xmpp

i sent the following stanza to ejabbers server after creating a node "test1_node1"
<iq id="publish1" to="pubsub.oomaxmpp.com" type="get" from="admin#oomaxmpp.com/1697575709134613774110793">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish node="test_node1"><item id="qwert12345">
<entry xmlns="http://www.w3.org/2005/Atom">
<title>*publish*</title>
<summary>*1234567890*</summary>
<published>2003-12-13T18:30:02Z</published>
<updated>2003-12-13T18:30:02Z</updated>
</entry>
</item>
</publish>
</pubsub>
</iq>
but i get an error result with following stanza,
<iq id="publish1" xml:lang="en" type="error" to="admin#oomaxmpp.com/1697575709134613774110793" from="pubsub.oomaxmpp.com">
<pubsub xmlns="http://jabber.org/protocol/pubsub"><publish node="test_node1">
<item id="qwert12345"><entry xmlns="http://www.w3.org/2005/Atom">
<title>*publish*</title>
<summary>*1234567890*</summary>
<published>2003-12-13T18:30:02Z</published>
<updated>2003-12-13T18:30:02Z</updated>
</entry>
</item>
</publish>
</pubsub>
<error code="501" type="cancel"><feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
i dont understand,if feature was not implemented how nodes were created?
Why cant i publish?

node getting formed but cannot publish in pubsub xmpp

I am using libstrophe C library to Create xmpp clint.I am successfully able to create node(open node) and send request for subscription from other users,which get added.
Now when i try to publish,using the following stanza,
<iq type='set'
from='hamlet#pratik.com/blogbot'
to='pubsub.pratik.com'
id='publish1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='pratik'>
<item id='123456'>
<entry xmlns='http://www.w3.org/2005/Atom'>
<title>Soliloquy</title>
<summary>
To be, or not to be
</summary>
</entry>
</item>
</publish>
</pubsub>
I get,
<error code="501" type="cancel"><feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>
Any suggestions?
am using ejabberd as server