mirror of
https://github.com/bjc/prosody.git
synced 2025-04-03 21:27:38 +03:00
Including the payload of the stanza that caused the error is optional and we're generally not doing it anywhere else.
542 lines
15 KiB
Text
542 lines
15 KiB
Text
# MUC: Room registration and presence broadcast of unavailable members
|
|
|
|
[Client] Romeo
|
|
jid: user@localhost
|
|
password: password
|
|
|
|
[Client] Juliet
|
|
jid: user2@localhost
|
|
password: password
|
|
|
|
[Client] Rosaline
|
|
jid: user3@localhost
|
|
password: password
|
|
|
|
-----
|
|
|
|
Romeo connects
|
|
|
|
Romeo sends:
|
|
<presence to="room@conference.localhost/Romeo">
|
|
<x xmlns="http://jabber.org/protocol/muc"/>
|
|
</presence>
|
|
|
|
Romeo receives:
|
|
<presence from='room@conference.localhost/Romeo'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<status code='201'/>
|
|
<item jid="${Romeo's full JID}" affiliation='owner' role='moderator'/>
|
|
<status code='110'/>
|
|
</x>
|
|
</presence>
|
|
|
|
Romeo receives:
|
|
<message type='groupchat' from='room@conference.localhost'><subject/></message>
|
|
|
|
# Submit config form
|
|
Romeo sends:
|
|
<iq id='config1' to='room@conference.localhost' type='set'>
|
|
<query xmlns='http://jabber.org/protocol/muc#owner'>
|
|
<x xmlns='jabber:x:data' type='submit'>
|
|
<field var='FORM_TYPE'>
|
|
<value>http://jabber.org/protocol/muc#roomconfig</value>
|
|
</field>
|
|
<field var='muc#roomconfig_presencebroadcast'>
|
|
<value>none</value>
|
|
<value>participant</value>
|
|
<value>moderator</value>
|
|
</field>
|
|
</x>
|
|
</query>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<iq id="config1" from="room@conference.localhost" type="result">
|
|
</iq>
|
|
|
|
Romeo sends:
|
|
<iq id='member1' to='room@conference.localhost' type='set'>
|
|
<query xmlns='http://jabber.org/protocol/muc#admin'>
|
|
<item affiliation='member' jid="${Juliet's JID}" />
|
|
</query>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<message from='room@conference.localhost'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item jid="${Juliet's JID}" affiliation='member' />
|
|
</x>
|
|
</message>
|
|
|
|
Romeo receives:
|
|
<iq from='room@conference.localhost' id='member1' type='result'/>
|
|
|
|
# Juliet connects, and joins the room
|
|
Juliet connects
|
|
|
|
Juliet sends:
|
|
<presence to="room@conference.localhost/Juliet">
|
|
<x xmlns="http://jabber.org/protocol/muc"/>
|
|
</presence>
|
|
|
|
Juliet receives:
|
|
<presence from="room@conference.localhost/Romeo" />
|
|
|
|
Juliet receives:
|
|
<presence from="room@conference.localhost/Juliet" />
|
|
|
|
Juliet receives:
|
|
<message type='groupchat' from='room@conference.localhost'><subject/></message>
|
|
|
|
Romeo receives:
|
|
<presence from="room@conference.localhost/Juliet" />
|
|
|
|
# Juliet retrieves the registration form
|
|
|
|
Juliet sends:
|
|
<iq id='jw81b36f' to='room@conference.localhost' type='get'>
|
|
<query xmlns='jabber:iq:register'/>
|
|
</iq>
|
|
|
|
Juliet receives:
|
|
<iq type='result' from='room@conference.localhost' id='jw81b36f'>
|
|
<query xmlns='jabber:iq:register'>
|
|
<x type='form' xmlns='jabber:x:data'>
|
|
<field type='hidden' var='FORM_TYPE'>
|
|
<value>http://jabber.org/protocol/muc#register</value>
|
|
</field>
|
|
<field type='text-single' label='Nickname' var='muc#register_roomnick'>
|
|
<required/>
|
|
</field>
|
|
</x>
|
|
</query>
|
|
</iq>
|
|
|
|
Juliet sends:
|
|
<iq id='nv71va54' to='room@conference.localhost' type='set'>
|
|
<query xmlns='jabber:iq:register'>
|
|
<x xmlns='jabber:x:data' type='submit'>
|
|
<field var='FORM_TYPE'>
|
|
<value>http://jabber.org/protocol/muc#register</value>
|
|
</field>
|
|
<field var='muc#register_roomnick'>
|
|
<value>Juliet</value>
|
|
</field>
|
|
</x>
|
|
</query>
|
|
</iq>
|
|
|
|
Juliet receives:
|
|
<presence from='room@conference.localhost/Juliet'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='member' jid="${Juliet's full JID}" role='participant'/>
|
|
<status code='110'/>
|
|
</x>
|
|
</presence>
|
|
|
|
Juliet receives:
|
|
<iq type='result' from='room@conference.localhost' id='nv71va54'/>
|
|
|
|
# Juliet discovers her reserved nick
|
|
|
|
Juliet sends:
|
|
<iq id='getnick1' to='room@conference.localhost' type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/>
|
|
</iq>
|
|
|
|
Juliet receives:
|
|
<iq type='result' from='room@conference.localhost' id='getnick1'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'>
|
|
<identity category='conference' name='Juliet' type='text'/>
|
|
</query>
|
|
</iq>
|
|
|
|
# Juliet leaves the room:
|
|
|
|
Juliet sends:
|
|
<presence type="unavailable" to="room@conference.localhost/Juliet" />
|
|
|
|
Juliet receives:
|
|
<presence type='unavailable' from='room@conference.localhost/Juliet'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item jid="${Juliet's full JID}" affiliation='member' role='none'/>
|
|
<status code='110'/>
|
|
</x>
|
|
</presence>
|
|
|
|
Romeo receives:
|
|
<presence from='room@conference.localhost/Juliet'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item jid="${Juliet's full JID}" affiliation='member' role='participant'/>
|
|
</x>
|
|
</presence>
|
|
|
|
# Rosaline connect and tries to join the room as Juliet
|
|
|
|
Rosaline connects
|
|
|
|
Rosaline sends:
|
|
<presence to="room@conference.localhost/Juliet">
|
|
<x xmlns="http://jabber.org/protocol/muc"/>
|
|
</presence>
|
|
|
|
Rosaline receives:
|
|
<presence type='error' from='room@conference.localhost/Juliet'>
|
|
<error type='cancel' by='room@conference.localhost'>
|
|
<conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
|
</error>
|
|
</presence>
|
|
|
|
# In a heated moment, Juliet unregisters from the room
|
|
|
|
Juliet sends:
|
|
<iq type='set' to='room@conference.localhost' id='unreg1'>
|
|
<query xmlns='jabber:iq:register'>
|
|
<remove/>
|
|
</query>
|
|
</iq>
|
|
|
|
Juliet receives:
|
|
<iq type='result' from='room@conference.localhost' id='unreg1'/>
|
|
|
|
# Romeo is notified of Juliet's sad decision
|
|
|
|
Romeo receives:
|
|
<message from='room@conference.localhost'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user' scansion:strict='true'>
|
|
<item jid="${Juliet's JID}" affiliation='none' />
|
|
</x>
|
|
</message>
|
|
|
|
# Rosaline attempts once more to sneak into the room, disguised as Juliet
|
|
|
|
Rosaline sends:
|
|
<presence to="room@conference.localhost/Juliet">
|
|
<x xmlns="http://jabber.org/protocol/muc"/>
|
|
</presence>
|
|
|
|
Rosaline receives:
|
|
<presence from='room@conference.localhost/Romeo'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='owner' role='moderator'/>
|
|
</x>
|
|
</presence>
|
|
|
|
Rosaline receives:
|
|
<presence from='room@conference.localhost/Juliet'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='none' jid="${Rosaline's full JID}" role='participant'/>
|
|
<status code='110'/>
|
|
</x>
|
|
</presence>
|
|
|
|
Romeo receives:
|
|
<presence from='room@conference.localhost/Juliet'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='none' jid="${Rosaline's full JID}" role='participant'/>
|
|
</x>
|
|
</presence>
|
|
|
|
# On discovering the ruse, Romeo restores Juliet's nick and status within the room
|
|
|
|
Romeo sends:
|
|
<iq id='member1' to='room@conference.localhost' type='set'>
|
|
<query xmlns='http://jabber.org/protocol/muc#admin'>
|
|
<item affiliation='member' jid="${Juliet's JID}" nick='Juliet' />
|
|
</query>
|
|
</iq>
|
|
|
|
# Rosaline is evicted from the room
|
|
|
|
Romeo receives:
|
|
<presence from='room@conference.localhost/Juliet' type='unavailable'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<status code='307'/>
|
|
<item affiliation='none' role='none' jid="${Rosaline's full JID}">
|
|
<reason>This nickname is reserved</reason>
|
|
</item>
|
|
</x>
|
|
</presence>
|
|
|
|
# An out-of-room affiliation change is received for Juliet
|
|
|
|
Romeo receives:
|
|
<message from='room@conference.localhost'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item jid="${Juliet's JID}" affiliation='member' />
|
|
</x>
|
|
</message>
|
|
|
|
Romeo receives:
|
|
<iq type='result' id='member1' from='room@conference.localhost' />
|
|
|
|
Rosaline receives:
|
|
<presence type='unavailable' from='room@conference.localhost/Juliet'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<status code='307'/>
|
|
<item affiliation='none' jid="${Rosaline's full JID}" role='none'>
|
|
<reason>This nickname is reserved</reason>
|
|
</item>
|
|
<status code='110'/>
|
|
</x>
|
|
</presence>
|
|
|
|
# Rosaline, frustrated, attempts to get back into the room...
|
|
|
|
Rosaline sends:
|
|
<presence to="room@conference.localhost/Juliet">
|
|
<x xmlns="http://jabber.org/protocol/muc"/>
|
|
</presence>
|
|
|
|
# ...but once again, is denied
|
|
|
|
Rosaline receives:
|
|
<presence type='error' from='room@conference.localhost/Juliet'>
|
|
<error type='cancel' by='room@conference.localhost'>
|
|
<conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
|
</error>
|
|
</presence>
|
|
|
|
# Juliet, however, quietly joins the room with success
|
|
|
|
Juliet sends:
|
|
<presence to="room@conference.localhost/Juliet">
|
|
<x xmlns="http://jabber.org/protocol/muc"/>
|
|
</presence>
|
|
|
|
Juliet receives:
|
|
<presence from="room@conference.localhost/Romeo" />
|
|
|
|
Juliet receives:
|
|
<presence from="room@conference.localhost/Juliet" />
|
|
|
|
Juliet receives:
|
|
<message type='groupchat' from='room@conference.localhost'><subject/></message>
|
|
|
|
Romeo receives:
|
|
<presence from="room@conference.localhost/Juliet" />
|
|
|
|
# Romeo checks whether he has reserved his own nick yet
|
|
|
|
Romeo sends:
|
|
<iq id='getnick1' to='room@conference.localhost' type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/>
|
|
</iq>
|
|
|
|
# But no nick is returned, as he hasn't registered yet!
|
|
|
|
Romeo receives:
|
|
<iq type='result' from='room@conference.localhost' id='getnick1'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item' scansion:strict='true' />
|
|
</iq>
|
|
|
|
# Romeo updates his own registration
|
|
|
|
Romeo sends:
|
|
<iq id='jw81b36f' to='room@conference.localhost' type='get'>
|
|
<query xmlns='jabber:iq:register'/>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<iq type='result' from='room@conference.localhost' id='jw81b36f'>
|
|
<query xmlns='jabber:iq:register'>
|
|
<x type='form' xmlns='jabber:x:data'>
|
|
<field type='hidden' var='FORM_TYPE'>
|
|
<value>http://jabber.org/protocol/muc#register</value>
|
|
</field>
|
|
<field type='text-single' label='Nickname' var='muc#register_roomnick'>
|
|
<required/>
|
|
</field>
|
|
</x>
|
|
</query>
|
|
</iq>
|
|
|
|
Romeo sends:
|
|
<iq id='nv71va54' to='room@conference.localhost' type='set'>
|
|
<query xmlns='jabber:iq:register'>
|
|
<x xmlns='jabber:x:data' type='submit'>
|
|
<field var='FORM_TYPE'>
|
|
<value>http://jabber.org/protocol/muc#register</value>
|
|
</field>
|
|
<field var='muc#register_roomnick'>
|
|
<value>Romeo</value>
|
|
</field>
|
|
</x>
|
|
</query>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<presence from='room@conference.localhost/Romeo'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='owner' jid="${Romeo's full JID}" role='moderator'/>
|
|
<status code='110'/>
|
|
</x>
|
|
</presence>
|
|
|
|
Romeo receives:
|
|
<iq type='result' from='room@conference.localhost' id='nv71va54'/>
|
|
|
|
Juliet receives:
|
|
<presence from='room@conference.localhost/Romeo'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item role='moderator' xmlns='http://jabber.org/protocol/muc#user' affiliation='owner'/>
|
|
</x>
|
|
</presence>
|
|
|
|
# Romeo discovers his reserved nick
|
|
|
|
Romeo sends:
|
|
<iq id='getnick1' to='room@conference.localhost' type='get'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<iq type='result' from='room@conference.localhost' id='getnick1'>
|
|
<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'>
|
|
<identity category='conference' name='Romeo' type='text'/>
|
|
</query>
|
|
</iq>
|
|
|
|
# To check the status of the room is as expected, Romeo requests the member list
|
|
|
|
Romeo sends:
|
|
<iq id='member3' to='room@conference.localhost' type='get'>
|
|
<query xmlns='http://jabber.org/protocol/muc#admin'>
|
|
<item affiliation='member'/>
|
|
</query>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<iq from='room@conference.localhost' type='result' id='member3'>
|
|
<query xmlns='http://jabber.org/protocol/muc#admin'>
|
|
<item jid="${Juliet's JID}" affiliation='member' nick='Juliet'/>
|
|
</query>
|
|
</iq>
|
|
|
|
Juliet sends:
|
|
<presence type="unavailable" to="room@conference.localhost/Juliet" />
|
|
|
|
Juliet receives:
|
|
<presence from='room@conference.localhost/Juliet' type='unavailable' />
|
|
|
|
Romeo receives:
|
|
<presence type='unavailable' from='room@conference.localhost/Juliet' />
|
|
|
|
# Rosaline joins as herself
|
|
|
|
Rosaline sends:
|
|
<presence to="room@conference.localhost/Rosaline">
|
|
<x xmlns="http://jabber.org/protocol/muc"/>
|
|
</presence>
|
|
|
|
Rosaline receives:
|
|
<presence from="room@conference.localhost/Romeo" />
|
|
|
|
Rosaline receives:
|
|
<presence from='room@conference.localhost/Juliet' type='unavailable'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='member' role='none' nick='Juliet' xmlns='http://jabber.org/protocol/muc#user'/>
|
|
</x>
|
|
</presence>
|
|
|
|
Rosaline receives:
|
|
<presence from="room@conference.localhost/Rosaline" />
|
|
|
|
Rosaline receives:
|
|
<message type='groupchat' from='room@conference.localhost'><subject/></message>
|
|
|
|
Romeo receives:
|
|
<presence from='room@conference.localhost/Rosaline'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item jid="${Rosaline's full JID}" affiliation='none' role='participant'/>
|
|
</x>
|
|
</presence>
|
|
|
|
# Rosaline tries to register her own nickname, but unaffiliated
|
|
# registration is disabled by default
|
|
|
|
Rosaline sends:
|
|
<iq id='reg990' to='room@conference.localhost' type='get'>
|
|
<query xmlns='jabber:iq:register'/>
|
|
</iq>
|
|
|
|
Rosaline receives:
|
|
<iq type='error' from='room@conference.localhost' id='reg990'>
|
|
<error type='auth'>
|
|
<registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
|
</error>
|
|
</iq>
|
|
|
|
Rosaline sends:
|
|
<iq id='reg991' to='room@conference.localhost' type='set'>
|
|
<query xmlns='jabber:iq:register'>
|
|
<x xmlns='jabber:x:data' type='submit'>
|
|
<field var='FORM_TYPE'>
|
|
<value>http://jabber.org/protocol/muc#register</value>
|
|
</field>
|
|
<field var='muc#register_roomnick'>
|
|
<value>Romeo</value>
|
|
</field>
|
|
</x>
|
|
</query>
|
|
</iq>
|
|
|
|
Rosaline receives:
|
|
<iq id='reg991' type='error'>
|
|
<error type='auth'>
|
|
<registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
|
</error>
|
|
</iq>
|
|
|
|
# Romeo reserves her nickname for her
|
|
|
|
Romeo sends:
|
|
<iq id='member2' to='room@conference.localhost' type='set'>
|
|
<query xmlns='http://jabber.org/protocol/muc#admin'>
|
|
<item affiliation='member' jid="${Rosaline's JID}" nick='Rosaline' />
|
|
</query>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<presence from='room@conference.localhost/Rosaline'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='member' role='participant' jid="${Rosaline's full JID}">
|
|
<actor jid="${Romeo's full JID}" nick='Romeo'/>
|
|
</item>
|
|
</x>
|
|
</presence>
|
|
|
|
Romeo receives:
|
|
<iq type='result' id='member2' from='room@conference.localhost' />
|
|
|
|
Rosaline receives:
|
|
<presence from='room@conference.localhost/Rosaline'>
|
|
<x xmlns='http://jabber.org/protocol/muc#user'>
|
|
<item affiliation='member' role='participant' jid="${Rosaline's full JID}">
|
|
<actor nick='Romeo' />
|
|
</item>
|
|
<status xmlns='http://jabber.org/protocol/muc#user' code='110'/>
|
|
</x>
|
|
</presence>
|
|
|
|
# Romeo sets their their own nickname via admin query (see #1273)
|
|
Romeo sends:
|
|
<iq to="room@conference.localhost" id="reserve" type="set">
|
|
<query xmlns="http://jabber.org/protocol/muc#admin">
|
|
<item nick="Romeo" affiliation="owner" jid="${Romeo's JID}"/>
|
|
</query>
|
|
</iq>
|
|
|
|
Romeo receives:
|
|
<presence from="room@conference.localhost/Romeo">
|
|
<x xmlns="http://jabber.org/protocol/muc#user">
|
|
<item xmlns="http://jabber.org/protocol/muc#user" role="moderator" jid="${Romeo's full JID}" affiliation="owner">
|
|
<actor xmlns="http://jabber.org/protocol/muc#user" nick="Romeo"/>
|
|
</item>
|
|
<status xmlns="http://jabber.org/protocol/muc#user" code="110"/>
|
|
</x>
|
|
</presence>
|
|
|
|
Romeo receives:
|
|
<iq from="room@conference.localhost" id="reserve" type="result"/>
|
|
|