Moderator and Admin Use Cases

This commit is contained in:
stpeter 2011-08-15 10:18:31 -06:00
parent 03c392bb96
commit d65b8f951c
1 changed files with 70 additions and 113 deletions

View File

@ -304,7 +304,7 @@
<version>0.15</version>
<date>2002-10-18</date>
<initials>psa</initials>
<remark><p>Fully incorporated the change to affiliations + roles; moved a number of admin use cases to a new section for moderator use cases; added participant use case for requesting membership; added admin use cases for adding members, removing members, granting and revoking moderator privileges, and modifying the moderator list; organized the sections in a more logical manner.</p></remark>
<remark><p>Fully incorporated the change to affiliations + roles; moved a number of admin use cases to a new section for moderator use cases; added participant use case for requesting membership; added admin use cases for adding members, removing members, granting and revoking moderator status, and modifying the moderator list; organized the sections in a more logical manner.</p></remark>
</revision>
<revision>
<version>0.14</version>
@ -471,7 +471,7 @@
<li>allowing only moderators to change the room subject</li>
<li>enabling moderators to kick participants and visitors from the room</li>
<li>enabling moderators to grant and revoke voice (i.e., the privilege to speak) in a moderated room, and to manage the voice list</li>
<li>enabling admins to grant and revoke moderator privileges, and to manage the moderator list</li>
<li>enabling admins to grant and revoke moderator status, and to manage the moderator list</li>
<li>enabling admins to ban users from the room, and to manage the ban list</li>
<li>enabling admins to grant and revoke membership privileges, and to manage the member list for a members-only room</li>
<li>enabling owners to configure various room parameters (e.g., limiting the number of occupants)</li>
@ -785,24 +785,24 @@
<td>Exit room or be kicked by a moderator</td>
<td>--</td>
<td>Moderator grants voice</td>
<td>Admin or owner grants moderator privileges</td>
<td>Admin or owner grants moderator status</td>
</tr>
<tr>
<td>Participant</td>
<td>Exit room or be kicked by a moderator</td>
<td>Moderator revokes voice</td>
<td>--</td>
<td>Admin or owner grants moderator privileges</td>
<td>Admin or owner grants moderator status</td>
</tr>
<tr>
<td>Moderator</td>
<td>Exit room or be kicked by an admin or owner</td>
<td>Admin or owner changes role to visitor *</td>
<td>Admin or owner changes role to participant or revokes moderator privileges *</td>
<td>Admin or owner changes role to participant or revokes moderator status *</td>
<td>--</td>
</tr>
</table>
<p>* A moderator MUST NOT be able to revoke moderator privileges from an occupant who is equal to or above the moderator in the hierarchy of affiliations.</p>
<p>* A moderator MUST NOT be able to revoke moderator status from an occupant who is equal to or above the moderator in the hierarchy of affiliations.</p>
<p class='box'>Note: Certain roles are typically implicit in certain affiliations. For example, an admin or owner is automatically a moderator, so if an occupant is granted an affiliation of admin then the occupant will by that fact be granted a role of moderator; similarly, when an occupant is granted an affiliation of member in a moderated room, the occupant automatically has a role of participant. However, the loss of the admin affiliation does not necessarily mean that the occupant no longer has a role of moderator (since a "mere" occupant can be a moderator). Therefore, the role that is gained when an occupant is granted a certain affiliation is stable, whereas the role that is lost when an occupant loses a certain affilitation is not hardcoded and is left up to the implementation. Since a client cannot predict what the role will be after revoking a certain affiliation, if it wants to remove both the admin/owner affiliation and the moderator role at the same time then it must specifically request the role change in addition to the affiliation change by including both the 'role' attribute and the 'affiliation' attribute.</p>
</section3>
@ -1157,7 +1157,7 @@
</query>
</iq>
]]></example>
<p>Some extended room information is dynamically generated (e.g., the URL for discussion logs, which may be based on service-wide configuration), whereas other information is based on the more-stable room configuration, which is why any field defined for the <link url='#registrar-formtype-owner'>muc#roomconfig FORM_TYPE</link> can be included in the extended service discovery fields (as shown above for the muc#roomconfig_changesubject field).</p>
<p>Some extended room information is dynamically generated (e.g., the URL for discussion logs, which may be based on service-wide configuration), whereas other information is based on the more-stable room configuration, which is why any field defined for the <link url='#registrar-formtype-owner'>muc#roomconfig FORM_TYPE</link> can be included in the extended service discovery fields (as shown above for the "muc#roomconfig_changesubject" field).</p>
<p>Note: The foregoing extended service discovery fields for the 'http://jabber.org/protocol/muc#roominfo' FORM_TYPE are examples only and might be supplemented in the future via the mechanisms described in the <link url="#registrar-formtype">Field Standardization</link> section of this document.</p>
</section2>
@ -1396,7 +1396,7 @@
</presence>
]]></example>
<p>Note: The order of the presence stanzas sent to the new occupant is important. The service MUST first send the complete list of the existing occupants to the new occupant and only then send the new occupant's own presence to the new occupant. This helps the client know when it has received the complete "room roster". The room SHOULD also reflect the original 'id' value, if provided in the presence stanza sent by the user.</p>
<p>After sending the presence broadcast (and only after doing so), the service may then send discussion history, the room subject, live messages, presence updates, and other in-room traffic.</p>
<p>After sending the presence broadcast (and only after doing so), the service MAY then send discussion history, the room subject, live messages, presence updates, and other in-room traffic.</p>
</section3>
<section3 topic='Non-Anonymous Rooms' anchor='enter-nonanon'>
@ -1996,7 +1996,7 @@
]]></example>
<p>If the room is members-only, the service MAY also add the invitee to the member list. (Note: Invitation privileges in members-only rooms SHOULD be restricted to room admins; if a member without privileges to edit the member list attempts to invite another user, the service SHOULD return a &forbidden; error to the occupant; for details, see the <link url='#modifymember'>Modifying the Member List</link> section of this document.)</p>
<p>If the inviter supplies a non-existent JID, the room SHOULD return an &notfound; error to the inviter.</p>
<p>The invitee MAY choose to formally decline (as opposed to ignore) the invitation; and this is something that the sender may want to be informed about. In order to decline the invitation, the invitee MUST send a message of the following form to the &ROOM; itself:</p>
<p>The invitee MAY choose to formally decline (as opposed to ignore) the invitation; and this is something that the sender might want to be informed about. In order to decline the invitation, the invitee MUST send a message of the following form to the &ROOM; itself:</p>
<example caption='Invitee Declines Invitation'><![CDATA[
<message
from='hecate@shakespeare.lit/broom'
@ -2101,7 +2101,7 @@
stamp='2004-09-29T01:55:21Z'/>
</message>
]]></example>
<p>Note: Use of the <cite>Delayed Delivery</cite> protocol enables the room creator to specify the datetime of each message from the one-to-one chat history (via the 'stamp' attribute), as well as the JID of the original sender of each message (via the 'from' attribute); note well that the 'from' here is not the room itself, since the originator of the message is the delaying party. The room creator SHOULD send the complete one-to-one chat history before inviting additional users to the room, and SHOULD also send as history any messages appearing in the one-to-one chat interface after joining the room and before the second person joins the room; if the one-to-one history is especially large, the sending client may want to send the history over a few seconds rather than all at once (to avoid triggering rate limits). The service SHOULD NOT add its own delay elements (as described in the <link url='#enter-history'>Discussion History</link> section of this document) to prior chat history messages received from the room owner.</p>
<p>Note: Use of the <cite>Delayed Delivery</cite> protocol enables the room creator to specify the datetime of each message from the one-to-one chat history (via the 'stamp' attribute), as well as the JID of the original sender of each message (via the 'from' attribute); note well that the 'from' here is not the room itself, since the originator of the message is the delaying party. The room creator SHOULD send the complete one-to-one chat history before inviting additional users to the room, and SHOULD also send as history any messages appearing in the one-to-one chat interface after joining the room and before the second person joins the room; if the one-to-one history is especially large, the sending client might want to send the history over a few seconds rather than all at once (to avoid triggering rate limits). The service SHOULD NOT add its own delay elements (as described in the <link url='#enter-history'>Discussion History</link> section of this document) to prior chat history messages received from the room owner.</p>
<example caption='Continuing the Discussion III: Owner Sends Invitations, Including Continue Flag'><![CDATA[
<message
from='crone1@shakespeare.lit/desktop'
@ -2515,17 +2515,17 @@
</section1>
<section1 topic='Moderator Use Cases' anchor='moderator'>
<p>A moderator has privileges to perform certain actions within the room (e.g., to change the roles of some occupants) but does not have rights to change persistent information about affiliations (which may be changed only by an admin or owner) or defining information about the room. Exactly which actions may be performed by a moderator is subject to configuration. However, for the purposes of the MUC framework, moderators are stipulated to have privileges to perform the following actions:</p>
<p>A moderator has privileges to perform certain actions within the room (e.g., to change the roles of some occupants) but does not have rights to change persistent information about affiliations (which can be changed only by an admin or owner) or the room configuration. Exactly which actions can be performed by a moderator is subject to configuration. However, for the purposes of the MUC framework, moderators are stipulated to have privileges to perform the following actions:</p>
<ol start='1'>
<li>discover an occupant's full JID in a semi-anonymous room (occurs by default as shown above)</li>
<li>discover an occupant's full JID in a semi-anonymous room (occurs automatically through presence)</li>
<li>modify the subject</li>
<li>kick a participant or visitor from the room</li>
<li>grant or revoke voice in a moderated room</li>
<li>modify the list of occupants who have voice in a moderated room</li>
</ol>
<p>These features shall be implemented with a request/response exchange using &lt;iq/&gt; elements that contain children qualified by the 'http://jabber.org/protocol/muc#admin' namespace. The examples below illustrate the protocol interactions to implement the desired functionality. (Except where explicitly noted below, any of the following administrative requests MUST be denied if the &lt;user@host&gt; of the 'from' address of the request does not match the bare JID portion of one of the moderators; in this case, the service MUST return a &forbidden; error.)</p>
<p>These features are implemented with a request/response exchange using &lt;iq/&gt; elements that contain child elements qualified by the 'http://jabber.org/protocol/muc#admin' namespace. The examples below illustrate the protocol interactions to implement the desired functionality. (Except where explicitly noted below, any of the following administrative requests MUST be denied if the &lt;user@host&gt; of the 'from' address of the request does not match the bare JID portion of one of the moderators; in this case, the service MUST return a &forbidden; error.)</p>
<section2 topic='Modifying the Room Subject' anchor='subject-mod'>
<p>A common feature of multi-user chat rooms is the ability to change the subject within the room. By default, only users with a role of "moderator" SHOULD be allowed to change the subject in a room (although this SHOULD be configurable, with the result that a mere participant or even visitor may be allowed to change the subject if desired). The subject is changed by sending a message of type "groupchat" to the &ROOM;, where the &MESSAGE; MUST contain a &lt;subject/&gt; element that specifies the new subject but SHOULD NOT contain any other element (e.g., no &BODY; element or &THREAD; element).</p>
<p>A common feature of multi-user chat rooms is the ability to change the subject within the room. By default, only users with a role of "moderator" SHOULD be allowed to change the subject in a room (although this is configurable, with the result that a mere participant or even visitor might be allowed to change the subject, as controlled by the "muc#roomconfig_changesubject" option). The subject is changed by sending a message of type "groupchat" to the &ROOM;, where the &MESSAGE; MUST contain a &lt;subject/&gt; element that specifies the new subject but MUST NOT contain any other element (e.g., no &BODY; element or &THREAD; element).</p>
<example caption='Moderator Changes Subject'><![CDATA[
<message
from='wiccarocks@shakespeare.lit/laptop'
@ -2535,7 +2535,7 @@
<subject>Fire Burn and Cauldron Bubble!</subject>
</message>
]]></example>
<p>If a MUC service receives such a message, it MUST reflect the message to all other occupants with a 'from' address equal to the room JID that corresponds to the sender of the subject change:</p>
<p>The MUC service MUST reflect the message to all other occupants with a 'from' address equal to the room JID that corresponds to the sender of the subject change:</p>
<example caption='Service Informs All Occupants of Subject Change'><![CDATA[
<message
from='coven@chat.shakespeare.lit/secondwitch'
@ -2547,7 +2547,7 @@
[ ... ]
]]></example>
<p>In addition, the room SHOULD include the last subject change in the discussion history sent when a new occupant joins the room.</p>
<p>As explained under <link url='#enter-history'></link>, when a new occupant joins the room the room SHOULD include the last subject change after the discussion history.</p>
<p>A MUC client that receives such a message MAY choose to display an in-room message, such as the following:</p>
<example caption='Client Displays Room Subject Change Message'><![CDATA[
* secondwitch has changed the subject to: Fire Burn and Cauldron Bubble!
@ -2578,7 +2578,7 @@
</section2>
<section2 topic='Kicking an Occupant' anchor='kick'>
<p>A moderator has permissions kick certain kinds of occupants from a room (which occupants are "kickable" depends on service provisioning, room configuration, and the moderator's affiliation -- see below). The kick is normally performed based on the occupant's room nickname (though it MAY be based on the full JID) and is completed by setting the role of a participant or visitor to a value of "none".</p>
<p>A moderator has permissions kick certain kinds of occupants from a room (which occupants are "kickable" depends on service provisioning, room configuration, and the moderator's affiliation -- see below). The kick is performed based on the occupant's room nickname and is completed by setting the role of a participant or visitor to a value of "none".</p>
<example caption='Moderator Kicks Occupant'><![CDATA[
<iq from='fluellen@shakespeare.lit/pda'
id='kick1'
@ -2634,11 +2634,6 @@
id='kicktest'
to='wiccarocks@shakespeare.lit/laptop'
type='error'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='firstwitch' role='none'>
<reason>Be gone!</reason>
</item>
</query>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -2648,7 +2643,7 @@
</section2>
<section2 topic='Granting Voice to a Visitor' anchor='grantvoice'>
<p>In a moderated room, a moderator may want to manage who does and does not have "voice" in the room (i.e., the ability to send messages to all occupants). Voice is granted based on the visitor's room nickname, which the service will convert into the visitor's full JID internally. The moderator grants voice to a visitor by changing the visitor's role to "participant".</p>
<p>In a moderated room, a moderator might want to manage who does and does not have "voice" in the room (i.e., the ability to send messages to all occupants). Voice is granted based on the visitor's room nickname, which the service will convert into the visitor's full JID internally. The moderator grants voice to a visitor by changing the visitor's role to "participant".</p>
<example caption='Moderator Grants Voice to a Visitor'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='voice1'
@ -2700,7 +2695,7 @@
</section2>
<section2 topic='Revoking Voice from a Participant' anchor='revokevoice'>
<p>In a moderated room, a moderator may want to revoke a participant's privileges to speak. The moderator can revoke voice from a participant by changing the participant's role to "visitor":</p>
<p>In a moderated room, a moderator might want to revoke a participant's privileges to speak. The moderator can revoke voice from a participant by changing the participant's role to "visitor":</p>
<example caption='Moderator Revokes Voice from a Participant'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='voice2'
@ -2753,9 +2748,6 @@
id='voicetest'
to='crone1@shakespeare.lit/desktop'
type='error'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='secondwitch' role='visitor'/>
</query>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -2764,7 +2756,7 @@
</section2>
<section2 topic='Modifying the Voice List' anchor='modifyvoice'>
<p>A moderator in a moderated room may want to modify the voice list. To do so, the moderator first requests the voice list by querying the room for all occupants with a role of 'participant'.</p>
<p>A moderator in a moderated room might want to modify the voice list. To do so, the moderator first requests the voice list by querying the room for all occupants with a role of 'participant'.</p>
<example caption='Moderator Requests Voice List'><![CDATA[
<iq from='bard@shakespeare.lit/globe'
id='voice3'
@ -2831,11 +2823,6 @@
id='voicetest'
to='bard@shakespeare.lit/globe'
type='error'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item jid='hecate@shakespeare.lit'
nick='Hecate'
role='visitor'/>
</query>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -2844,7 +2831,7 @@
</section2>
<section2 topic='Approving Voice Requests' anchor='voiceapprove'>
<p>As noted in the <link url='#requestvoice'>Requesting Voice</link> section of this document, when a service receives a request for voice from an occupant it SHOULD forward that request to the room moderator(s). To do so, the service SHOULD send a &MESSAGE; stanza to the room moderator(s), where the &MESSAGE; stanza contains a data form asking for approval or denial of the request, as shown below.</p>
<p>As noted in the <link url='#requestvoice'>Requesting Voice</link> section of this document, when a service receives a request for voice from an occupant it SHOULD forward that request to the room moderator(s). To do so, the service sends a &MESSAGE; stanza to the room moderator(s), where the &MESSAGE; stanza contains a data form asking for approval or denial of the request, as shown below.</p>
<example caption='Voice Request Approval Form'><![CDATA[
<message from='coven@chat.shakespeare.lit'
id='approve'
@ -2866,7 +2853,7 @@
<value>participant</value>
</field>
<field var='muc#jid'
type='text-single'
type='jid-single'
label='User ID'>
<value>hag66@shakespeare.lit/pda</value>
</field>
@ -2913,16 +2900,16 @@
</section1>
<section1 topic='Admin Use Cases' anchor='admin'>
<p>A room administrator has privileges to modify persistent information about user affiliations (e.g., by banning users) and to grant and revoke moderator privileges, but does not have rights to change the defining features of the room, which are the sole province of the room owner(s). Exactly which actions may be performed by a room admin will be subject to configuration. However, for the purposes of the MUC framework, room admins are stipulated to at a minimum have privileges to perform the following actions:</p>
<p>A room administrator has privileges to modify persistent information about user affiliations (e.g., by banning users) and to grant and revoke moderator status, but does not have rights to change the room configuration, which is the sole province of the room owner(s). Exactly which actions can be performed by a room admin is subject to configuration. However, for the purposes of the MUC framework, room admins are stipulated to at a minimum have privileges to perform the following actions:</p>
<ol start='1'>
<li>ban a user from the room</li>
<li>modify the list of users who are banned from the room</li>
<li>grant or revoke membership</li>
<li>modify the member list</li>
<li>grant or revoke moderator privileges</li>
<li>grant or revoke moderator status</li>
<li>modify the list of moderators</li>
</ol>
<p>These features shall be implemented with a request/response exchange using &lt;iq/&gt; elements that contain children qualified by the 'http://jabber.org/protocol/muc#admin' namespace. The examples below illustrate the protocol interactions that implement the desired functionality. (Except where explicitly noted below, any of the following administrative requests MUST be denied if the &lt;user@host&gt; of the 'from' address of the request does not match the bare JID of one of the room admins; in this case, the service MUST return a &forbidden; error.)</p>
<p>These features are implemented with a request/response exchange using &lt;iq/&gt; elements that contain child elements qualified by the 'http://jabber.org/protocol/muc#admin' namespace. The examples below illustrate the protocol interactions that implement the desired functionality. (Except where explicitly noted below, any of the following administrative requests MUST be denied if the &lt;user@host&gt; of the 'from' address of the request does not match the bare JID of one of the room admins; in this case, the service MUST return a &forbidden; error.)</p>
<section2 topic='Banning a User' anchor='ban'>
<p>An admin or owner can ban one or more users from a room. The ban MUST be performed based on the occupant's bare JID. In order to ban a user, an admin MUST change the user's affiliation to "outcast".</p>
<example caption='Admin Bans User'><![CDATA[
@ -2950,7 +2937,7 @@
</query>
</iq>
]]></example>
<p>The service MUST add that bare JID to the ban list, SHOULD remove the outcast's nickname from the list of registered nicknames, and MUST inform the admin or owner of success:</p>
<p>The service MUST add that bare JID to the ban list, MUST remove the outcast's nickname from the list of registered nicknames, and MUST inform the admin or owner of success:</p>
<example caption='Service Informs Admin or Owner of Success'><![CDATA[
<iq from='southampton@henryv.shakespeare.lit'
id='ban1'
@ -2995,22 +2982,16 @@
id='ban1'
to='southampton@henryv.shakespeare.lit'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='outcast'
jid='earlofcambridge@shakespeare.lit'>
<reason>Treason</reason>
</item>
</query>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>If an admin or owner attempts to ban himself, the service MUST deny the request and return a &conflict; error to the sender. (Note: This is different from the recommended service behavior on kicking oneself, which a service may allow.)</p>
<p>If an admin or owner attempts to ban himself, the service MUST deny the request and return a &conflict; error to the sender. (Note: This is different from the recommended service behavior on kicking oneself.)</p>
</section2>
<section2 topic='Modifying the Ban List' anchor='modifyban'>
<p>A room admin may want to modify the ban list. Note: The ban list is always based on a user's bare JID. To modify the list of banned JIDs, the admin first requests the ban list by querying the room for all users with an affiliation of 'outcast'.</p>
<p>A room admin might want to modify the ban list. (Note: The ban list is always based on a user's bare JID.) To modify the list of banned JIDs, the admin first requests the ban list by querying the room for all users with an affiliation of 'outcast'.</p>
<example caption='Admin Requests Ban List'><![CDATA[
<iq from='kinghenryv@shakespeare.lit/throne'
id='ban2'
@ -3042,10 +3023,6 @@
to='southampton@henryv.shakespeare.lit'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='outcast'
jid='earlofcambridge@shakespeare.lit'>
<reason>Treason</reason>
</item>
<item affiliation='outcast'>
jid='lordscroop@shakespeare.lit'>
<reason>Treason</reason>
@ -3064,7 +3041,7 @@
to='kinghenryv@shakespeare.lit/throne'
type='result'/>
]]></example>
<p>The service MUST then remove the affected occupants (if they are in the room) and send updated presence (including the appropriate status code) from them to all the remaining occupants as described in the "Banning a User" use case. (The service SHOULD also remove each banned user's reserved nickname from the list of reserved roomnicks, if appropriate.)</p>
<p>The service MUST then remove the affected occupants (if they are in the room) and send updated presence (including the appropriate status code) from them to all the remaining occupants as described in the "Banning a User" use case. (The service MUST also remove each banned user's reserved nickname from the list of reserved roomnicks, if appropriate.)</p>
<p>When an entity is banned from a room, an implementation SHOULD match JIDs in the following order (these matching rules are the same as those defined for privacy lists in &xep0016;):</p>
<ol start='1'>
<li>&lt;user@domain/resource&gt; (only that resource matches)</li>
@ -3072,11 +3049,11 @@
<li>&lt;domain/resource&gt; (only that resource matches)</li>
<li>&lt;domain&gt; (the domain itself matches, as does any user@domain or domain/resource)</li>
</ol>
<p>Some administrators may wish to ban all users associated with a specific domain from all rooms hosted by a MUC service. Such functionality is a service-level feature and is therefore out of scope for this document, instead being defined in <cite>XEP-0133</cite>.</p>
<p>Some administrators might wish to ban all users associated with a specific domain from all rooms hosted by a MUC service. Such functionality is a service-level feature and is therefore out of scope for this document; see <cite>XEP-0133</cite>.</p>
</section2>
<section2 topic='Granting Membership' anchor='grantmember'>
<p>An admin can grant membership to a user; this is done by changing the user's affiliation to "member" (normally based on nick if the user is in the room, or on bare JID if not; in either case, if the nick is provided, that nick becomes the user's default nick in the room if that functionality is supported by the implementation):</p>
<p>An admin can grant membership to a user; this is done by changing the affiliation for the user's bare JID to "member" (if a nick is provided, that nick becomes the user's default nick in the room if that functionality is supported by the implementation):</p>
<example caption='Admin Grants Membership'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='member1'
@ -3084,7 +3061,8 @@
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='member'
jid='hag66@shakespeare.lit'/>
jid='hag66@shakespeare.lit'
nick='thirdwitch'/>
</query>
</iq>
]]></example>
@ -3096,7 +3074,8 @@
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='member'
jid='hag66@shakespeare.lit'>
jid='hag66@shakespeare.lit'
nick='thirdwitch'>
<reason>A worthy witch indeed!</reason>
</item>
</query>
@ -3117,31 +3096,17 @@
<x xmlns='http://jabber.org/protocol/muc#user'>
<item affiliation='member'
jid='hag66@shakespeare.lit/pda'
role='participant'/>
role='participant'
nick='thirdwitch'/>
</x>
</presence>
[ ... ]
]]></example>
<p>If the user is not in the room, the service MAY send a message from the room itself to the room occupants, indicating the granting of membership by including an &lt;x/&gt; element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an &lt;item/&gt; child with the 'affiliation' attribute set to a value of "member".</p>
<example caption="Service Sends Notice of Membership to All Occupants"><![CDATA[
<message
from='chat.shakespeare.lit'
id='2D2D0081-D8D5-43C8-9D13-980366BB2BCB'
to='crone1@shakespeare.lit/desktop'>
<x xmlns='http://jabber.org/protocol/muc#user'>
<item affiliation='member'
jid='hag66@shakespeare.lit'
role='none'/>
</x>
</message>
[ ... ]
]]></example>
</section2>
<section2 topic='Revoking Membership' anchor='revokemember'>
<p>An admin may want to revoke a user's membership; this is done by changing the user's affiliation to "none":</p>
<p>An admin might want to revoke a user's membership; this is done by changing the user's affiliation to "none":</p>
<example caption='Admin Revokes Membership'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='member2'
@ -3218,7 +3183,7 @@
<section2 topic='Modifying the Member List' anchor='modifymember'>
<p>In the context of a members-only room, the member list is essentially a "whitelist" of people who are allowed to enter the room. Anyone who is not a member is effectively banned from entering the room, even if their affiliation is not "outcast".</p>
<p>In the context of an open room, the member list is simply a list of users (bare JID and reserved nick) who are registered with the room. Such users may appear in a room roster, have their room nickname reserved, be returned in search results or FAQ queries, and the like.</p>
<p>In the context of an open room, the member list is simply a list of users (bare JID and reserved nick) who are registered with the room. Such users cacan appear in a room roster, have their room nickname reserved, be returned in search results or FAQ queries, and the like.</p>
<p>It is RECOMMENDED that only room admins have the privilege to modify the member list in members-only rooms. To do so, the admin first requests the member list by querying the room for all users with an affiliation of "member":</p>
<example caption='Admin Requests Member List'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
@ -3230,8 +3195,8 @@
</query>
</iq>
]]></example>
<p>Note: A service SHOULD also return the member list to any occupant in a members-only room; i.e., it SHOULD NOT generate a &forbidden; error when a member in the room requests the member list. This functionality may assist clients in showing all the existing members even if some of them are not in the room, e.g. to help a member determine if another user should be invited. A service SHOULD also allow any member to retrieve the member list even if not yet an occupant.</p>
<p>The service MUST then return the full member list to the admin qualified by the 'http://jabber.org/protocol/muc#admin' namespace; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for each members that is currently an occupant.</p>
<p>Note: A service SHOULD also return the member list to any occupant in a members-only room; i.e., it SHOULD NOT generate a &forbidden; error when a member in the room requests the member list. This functionality can assist clients in showing all the existing members even if some of them are not in the room, e.g. to help a member determine if another user should be invited. A service SHOULD also allow any member to retrieve the member list even if not yet an occupant.</p>
<p>The service MUST then return the full member list to the admin qualified by the 'http://jabber.org/protocol/muc#admin' namespace; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for each member that is currently an occupant.</p>
<example caption='Service Sends Member List to Admin'><![CDATA[
<iq from='coven@chat.shakespeare.lit'
id='member3'
@ -3245,7 +3210,7 @@
</query>
</iq>
]]></example>
<p>The admin MAY then modify the member list. In order to do so, the admin MUST send the changed items (i.e., only the "delta") to the service; each item MUST include the 'affiliation' attribute (normally set to a value of "member" or "none") and 'jid' attribute but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'role' attribute (which is used to manage roles such as participant rather than the member affiliation):</p>
<p>The admin MAY then modify the member list. In order to do so, the admin MUST send the changed items (i.e., only the "delta") to the service; each item MUST include the 'affiliation' attribute (normally set to a value of "member" or "none") and 'jid' attribute but SHOULD NOT include the 'nick' attribute (unless modifying the user's reserved nickname) and MUST NOT include the 'role' attribute (which is used to manage roles such as participant rather than the member affiliation):</p>
<example caption='Admin Sends Modified Member List to Service'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='member4'
@ -3267,7 +3232,7 @@
type='result'/>
]]></example>
<p>The service MUST change the affiliation of any affected user. If the user has been removed from the member list, the service MUST change the user's affiliation from "member" to "none". If the user has been added to the member list, the service MUST change the user's affiliation to "member".</p>
<p>If a removed member is currently in a members-only room, the service SHOULD kick the occupant by changing the removed member's role to "none" and send appropriate presence to the removed member as previously described. No matter whether the removed member was in or out of a members-only room, the service MUST subsequently refuse entry to the user.</p>
<p>If a removed member is currently in a members-only room, the service SHOULD kick the occupant by changing the removed member's role to "none" and send appropriate presence to the removed member as previously described. If the removed member is not currently in the room, the service SHOULD send a message to the user's bare JID indicating the change in affiliation. No matter whether the removed member was in or out of a members-only room, the service MUST subsequently refuse entry to the user.</p>
<p>For all room types, the service MUST send updated presence from this individual to all occupants, indicating the change in affiliation by including an &lt;x/&gt; element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an &lt;item/&gt; child with the 'affiliation' attribute set to a value of "none".</p>
<example caption="Service Sends Notice of Loss of Membership to All Occupants"><![CDATA[
<presence
@ -3282,7 +3247,7 @@
[ ... ]
]]></example>
<p>In addition, the service SHOULD send an invitation to any user who has been added to the member list of a members-only room if the user is not currently affiliated with the room, for example as an admin or owner (such a user would by definition not be in the room; note also that this example includes a password but not a reason -- both child elements are OPTIONAL):</p>
<p>In addition, the service SHOULD send an invitation to any user who has been added to the member list of a members-only room if the user is not currently affiliated with the room (note that the following example includes a password but not a reason -- both child elements are OPTIONAL):</p>
<example caption='Room Sends Invitation to New Member'><![CDATA[
<message
from='coven@chat.shakespeare.lit'
@ -3294,7 +3259,7 @@
</x>
</message>
]]></example>
<p>While only admins and owners SHOULD be allowed to modify the member list, an implementation MAY provide a configuration option that opens invitation privileges to any member of a members-only room. In such a situation, any invitation sent SHOULD automatically trigger the addition of the invitee to the member list. However, if invitation privileges are restricted to admins and a mere member attempts to a send an invitation, the service MUST deny the invitation request and return a &forbidden; error to the sender:</p>
<p>Although only admins and owners SHOULD be allowed to modify the member list, an implementation MAY provide a configuration option that opens invitation privileges to any member of a members-only room. In such a situation, any invitation sent SHOULD automatically trigger the addition of the invitee to the member list. However, if invitation privileges are restricted to admins and a mere member attempts to a send an invitation, the service MUST deny the invitation request and return a &forbidden; error to the sender:</p>
<example caption='Service Returns Error on Attempt by Mere Member to Invite Others to a Members-Only Room'><![CDATA[
<message
from='coven@chat.shakespeare.lit'
@ -3330,9 +3295,9 @@
]]></example>
</section2>
<section2 topic='Granting Moderator Privileges' anchor='grantmod'>
<p>An admin may want to grant moderator privileges to a participant or visitor; this is done by changing the user's role to "moderator":</p>
<example caption='Admin Grants Moderator Privileges'><![CDATA[
<section2 topic='Granting Moderator Status' anchor='grantmod'>
<p>An admin might want to grant moderator status to a participant or visitor; this is done by changing the user's role to "moderator":</p>
<example caption='Admin Grants Moderator Status'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='mod1'
to='coven@chat.shakespeare.lit'
@ -3344,7 +3309,7 @@
</iq>
]]></example>
<p>The &lt;reason/&gt; element is OPTIONAL.</p>
<example caption='Admin Grants Moderator Privileges (With a Reason)'><![CDATA[
<example caption='Admin Grants Moderator Status (With a Reason)'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='mod1'
to='coven@chat.shakespeare.lit'
@ -3364,8 +3329,8 @@
to='crone1@shakespeare.lit/desktop'
type='result'/>
]]></example>
<p>The service MUST then send updated presence from this individual to all occupants, indicating the addition of moderator privileges by including an &lt;x/&gt; element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an &lt;item/&gt; child with the 'role' attribute set to a value of "moderator".</p>
<example caption="Service Sends Notice of Moderator Privileges to All Occupants"><![CDATA[
<p>The service MUST then send updated presence from this individual to all occupants, indicating the addition of moderator status by including an &lt;x/&gt; element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an &lt;item/&gt; child with the 'role' attribute set to a value of "moderator".</p>
<example caption="Service Sends Notice of Moderator Status to All Occupants"><![CDATA[
<presence
from='coven@chat.shakespeare.lit/thirdwitch'
to='crone1@shakespeare.lit/desktop'>
@ -3380,9 +3345,9 @@
]]></example>
</section2>
<section2 topic='Revoking Moderator Privileges' anchor='revokemod'>
<p>An admin may want to revoke a user's moderator privileges. An admin MAY revoke moderator privileges only from a user whose affiliation is "member" or "none" (i.e., not from an owner or admin). The privilege is revoked by changing the user's role to "participant":</p>
<example caption='Admin Revokes Moderator Privileges'><![CDATA[
<section2 topic='Revoking Moderator Status' anchor='revokemod'>
<p>An admin might want to revoke a user's moderator status. An admin MAY revoke moderator status only from a user whose affiliation is "member" or "none" (i.e., not from an owner or admin). The status is revoked by changing the user's role to "participant":</p>
<example caption='Admin Revokes Moderator Status'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='mod2'
to='coven@chat.shakespeare.lit'
@ -3394,7 +3359,7 @@
</iq>
]]></example>
<p>The &lt;reason/&gt; element is OPTIONAL.</p>
<example caption='Admin Revokes Moderator Privileges (With a Reason)'><![CDATA[
<example caption='Admin Revokes Moderator Status (With a Reason)'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='mod2'
to='coven@chat.shakespeare.lit'
@ -3414,8 +3379,8 @@
to='crone1@shakespeare.lit/desktop'
type='result'/>
]]></example>
<p>The service MUST then send updated presence from this individual to all occupants, indicating the removal of moderator privileges by sending a presence element that contains an &lt;x/&gt; element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an &lt;item/&gt; child with the 'role' attribute set to a value of "participant".</p>
<example caption="Service Notes Loss of Moderator Privileges"><![CDATA[
<p>The service MUST then send updated presence from this individual to all occupants, indicating the removal of moderator status by sending a presence element that contains an &lt;x/&gt; element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an &lt;item/&gt; child with the 'role' attribute set to a value of "participant".</p>
<example caption="Service Notes Loss of Moderator Status"><![CDATA[
<presence
from='coven@chat.shakespeare.lit/thirdwitch'
to='crone1@shakespeare.lit/desktop'>
@ -3428,15 +3393,12 @@
[ ... ]
]]></example>
<p>As noted, an admin MUST NOT be allowed to revoke moderator privileges from a user whose affiliation is "owner" or "admin". If an admin attempts to revoke moderator privileges from such a user, the service MUST deny the request and return a &notallowed; error to the sender:</p>
<example caption='Service Returns Error on Attempt to Revoke Moderator Privileges from an Admin or Owner'><![CDATA[
<p>As noted, an admin MUST NOT be allowed to revoke moderator status from a user whose affiliation is "owner" or "admin". If an admin attempts to revoke moderator status from such a user, the service MUST deny the request and return a &notallowed; error to the sender:</p>
<example caption='Service Returns Error on Attempt to Revoke Moderator Status from an Admin or Owner'><![CDATA[
<iq from='coven@chat.shakespeare.lit'
id='modtest'
to='crone1@shakespeare.lit/desktop'
type='error'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='secondwitch' role='participant'/>
</query>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -3445,7 +3407,7 @@
</section2>
<section2 topic='Modifying the Moderator List' anchor='modifymod'>
<p>An admin may want to modify the moderator list. To do so, the admin first requests the moderator list by querying the room for all users with a role of 'moderator'.</p>
<p>An admin might want to modify the moderator list. To do so, the admin first requests the moderator list by querying the room for all users with a role of 'moderator'.</p>
<example caption='Admin Requests Moderator List'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='mod3'
@ -3470,7 +3432,7 @@
</query>
</iq>
]]></example>
<p>The admin MAY then modify the moderator list. In order to do so, the admin MUST send the changed items (i.e., only the "delta") back to the service; each item MUST include the 'jid' attribute and 'role' attribute (normally set to a value of "member" or "participant") but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'affiliation' attribute (which is used to manage affiliations such as admin rather than the moderator role):</p>
<p>The admin MAY then modify the moderator list. In order to do so, the admin MUST send the changed items (i.e., only the "delta") back to the service; each item MUST include the 'jid' attribute and 'role' attribute (set to a value of "moderator" to grant moderator status or "participant" to revoke moderator status) but SHOULD NOT include the 'nick' attribute and MUST NOT include the 'affiliation' attribute (which is used to manage affiliations such as admin rather than the moderator role):</p>
<example caption='Admin Sends Modified Moderator List to Service'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='mod4'
@ -3491,18 +3453,13 @@
to='crone1@shakespeare.lit/desktop'
type='result'/>
]]></example>
<p>The service MUST then send updated presence for any affected individuals to all occupants, indicating the change in moderator privileges by sending the appropriate extended presence stanzas as described in the foregoing use cases.</p>
<p>As noted, moderator privileges cannot be revoked from a room owner or room admin. If a room admin attempts to revoke moderator privileges from such a user by modifying the moderator list, the service MUST deny the request and return a &notallowed; error to the sender:</p>
<example caption='Service Returns Error on Attempt to Revoke Moderator Privileges from an Admin or Owner'><![CDATA[
<p>The service MUST then send updated presence for any affected individuals to all occupants, indicating the change in moderator status by sending the appropriate extended presence stanzas as described in the foregoing use cases.</p>
<p>As noted, moderator status cannot be revoked from a room owner or room admin. If a room admin attempts to revoke moderator status from such a user by modifying the moderator list, the service MUST deny the request and return a &notallowed; error to the sender:</p>
<example caption='Service Returns Error on Attempt to Revoke Moderator Status from an Admin or Owner'><![CDATA[
<iq from='coven@chat.shakespeare.lit'
id='modtest'
to='hag66@shakespeare.lit/pda'
type='error'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item jid='hecate@shakespeare.lit/broom'
nick='Hecate'
role='participant'/>
</query>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -3511,7 +3468,7 @@
</section2>
<section2 topic='Approving Registration Requests' anchor='regapprove'>
<p>If a service does not automatically accept requests to register with a room, it MAY provide a way for room admins to approve or deny registration requests over XMPP (alternatively, it could provide a web interface or some other admin tool). The simplest way to do so is for the service to send a &MESSAGE; stanza to the room admin(s) when the registration request is received, where the &MESSAGE; stanza contains a Data Form asking for approval or denial of the request. The following Data Form is RECOMMENDED but implementations MAY use a different form entirely, or supplement the following form with additional fields.</p>
<p>If a service does not automatically accept requests to register with a room, it MAY provide a way for room admins to approve or deny registration requests over XMPP (alternatively, it could provide a web interface or some other admin tool). The simplest way to do so is for the service to send a &MESSAGE; stanza to the room admin(s) when the registration request is received, where the &MESSAGE; stanza contains a Data Form asking for approval or denial of the request. The following Data Form is RECOMMENDED but implementations might use a different form entirely, or supplement the following form with additional fields.</p>
<example caption='Registration Request Approval Form'><![CDATA[
<message from='coven@chat.shakespeare.lit'
id='407665A9-E54E-4AD5-905F-9FD8864489B3'
@ -3947,7 +3904,7 @@
</section3>
<section3 topic='Requesting a Unique Room Name' anchor='createroom-unique'>
<p>In some situations (e.g., when <link url='#continue'>Converting a One-to-One Chat Into a Conference</link>), the room creator may want to request a unique room name before attempting to create the room (e.g., to avoid the possibility of a room conflict). In order to facilitate this, a service MAY support the feature described in this section. (If a service does support this feature, it MUST return a feature of "http://jabber.org/protocol/muc#unique" in its response to service discovery information requests.)</p>
<p>In some situations (e.g., when <link url='#continue'>Converting a One-to-One Chat Into a Conference</link>), the room creator might want to request a unique room name before attempting to create the room (e.g., to avoid the possibility of a room conflict). In order to facilitate this, a service MAY support the feature described in this section. (If a service does support this feature, it MUST return a feature of "http://jabber.org/protocol/muc#unique" in its response to service discovery information requests.)</p>
<p>The room creator requests a unique room name by sending an IQ-get to the service itself, containing an empty &lt;unique/&gt; element qualified by the 'http://jabber.org/protocol/muc#unique' namespace:</p>
<example caption='Entity Requests Unique Room Name'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
@ -3983,7 +3940,7 @@
</section2>
<section2 topic='Subsequent Room Configuration' anchor='roomconfig'>
<p>At any time after specifying the initial configuration of the room, a room owner may want to change the configuration. In order to initiate this process, a room owner MUST request a new configuration form from the room by sending an IQ to &ROOM; containing an empty &lt;query/&gt; element qualified by the 'http://jabber.org/protocol/muc#owner' namespace.</p>
<p>At any time after specifying the initial configuration of the room, a room owner might want to change the configuration. In order to initiate this process, a room owner MUST request a new configuration form from the room by sending an IQ to &ROOM; containing an empty &lt;query/&gt; element qualified by the 'http://jabber.org/protocol/muc#owner' namespace.</p>
<example caption='Owner Requests Configuration Form'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='config1'
@ -4417,7 +4374,7 @@
</section2>
<section2 topic='Modifying the Owner List' anchor='modifyowner'>
<p>If allowed by an implementation, a room owner may want to modify the owner list. To do so, the owner first requests the owner list by querying the room for all users with an affiliation of 'owner'.</p>
<p>If allowed by an implementation, a room owner might want to modify the owner list. To do so, the owner first requests the owner list by querying the room for all users with an affiliation of 'owner'.</p>
<example caption='Owner Requests Owner List'><![CDATA[
<iq from='bard@shakespeare.lit/globe'
id='owner3'
@ -4545,7 +4502,7 @@
</section2>
<section2 topic='Revoking Administrative Privileges' anchor='revokeadmin'>
<p>An owner may want to revoke a user's administrative privileges; this is done by changing the user's affiliation to something other than "admin" or "owner":</p>
<p>An owner might want to revoke a user's administrative privileges; this is done by changing the user's affiliation to something other than "admin" or "owner":</p>
<example caption='Owner Revokes Administrative Privileges'><![CDATA[
<iq from='crone1@shakespeare.lit/desktop'
id='admin2'
@ -4610,7 +4567,7 @@
</section2>
<section2 topic='Modifying the Admin List' anchor='modifyadmin'>
<p>A room owner may want to modify the admin list. To do so, the owner first requests the admin list by querying the room for all users with an affiliation of 'admin'.</p>
<p>A room owner might want to modify the admin list. To do so, the owner first requests the admin list by querying the room for all users with an affiliation of 'admin'.</p>
<example caption='Owner Requests Admin List'><![CDATA[
<iq from='bard@shakespeare.lit/desktop'
id='admin3'