On 20.09.2010 13:53, Florian Zeitz wrote:
> I'll try to come up with a patch against xep-45 trying to catch all edge
> cases. If only to see how feasible this would be.
>
As promised I tried to change XEP-45 accordingly.
Taking into account my lack of experience with editing XEPs and not
being a native speaker this has the potentially to be horrible, but it's
hopefully still a good start.
The diff is attached.
You can find the html and PDF version at:
http://babelmonkeys.de/~florob/xep-0045.html
http://babelmonkeys.de/~florob/xep-0045.pdf
I'd still like to hear thought on whether you think this is a good idea
(since only 2 people have responded and I talked them into it ;) ).
Obviously I also welcome any comments/constructive criticism on the
attached patch.
--
Florian Zeitz
diff --git a/extensions/xep-0045.xml b/extensions/xep-0045.xml
index 0d1f33c..cfadd76 100644
--- a/extensions/xep-0045.xml
+++ b/extensions/xep-0045.xml
@@ -758,7 +758,13 @@
<li>None (the absence of an affiliation)</li>
</ol>
<p>Support for the owner affiliation is REQUIRED. Support for the admin, member, and outcast affiliations is RECOMMENDED. (The "None" affiliation is the absence of an affiliation.)</p>
- <p>These affiliations are long-lived in that they persist across a user's visits to the room and are not affected by happenings in the room. In addition, there is no one-to-one mapping between these affiliations and an occupant's role within the room. Affiliations are granted, revoked, and maintained based on the user's bare JID (not the full JID as with roles).</p>
+ <p>These affiliations are long-lived in that they persist across a user's visits to the room and are not affected by happenings in the room. In addition, there is no one-to-one mapping between these affiliations and an occupant's role within the room. When determining the affiliation of an entity, an implementation SHOULD match JIDs in the following order (these matching rules are the same as those defined for privacy lists in <cite>RFC 3921</cite>):</p>
+ <ol start='1'>
+ <li><u...@domain/resource> (only that resource matches)</li>
+ <li><u...@domain> (any resource matches)</li>
+ <li><domain/resource> (only that resource matches)</li>
+ <li><domain> (the domain itself matches, as does any u...@domain or domain/resource)</li>
+ </ol>
<p>If a user without a defined affiliation enters a room, the user's affiliation is defined as "none"; however, this affiliation does not persist across visits (i.e., a service does not maintain a "none list" across visits).</p>
<p>The member affiliation provides a way for a room owner or admin to specify a "whitelist" of users who are allowed to enter a members-only room. When a member enters a members-only room, his or her affiliation does not change, no matter what his or her role is. The member affiliation also provides a way for users to effectively register with an open room and thus be lastingly associated with that room in some way (one result may be that the user's nickname is reserved in the room).</p>
<p>An outcast is a user who has been banned from a room and who is not allowed to enter the room.</p>
@@ -918,6 +924,7 @@
<td>--</td>
</tr>
</table>
+ <p>Note: This table only offers a basic description of state changes. There are a lot of cases that may seem more complex. E.g. if <capulet.lit> is in the outcast list <[email protected]> may still be given the status of a member by adding her to the member list, while <[email protected]> and others remain outcasts. A table to completely describe all those cases would be rather large and is therefore not included in this document.</p>
</section3>
</section2>
</section1>
@@ -1035,7 +1042,7 @@
</iq>
]]></example>
<p>Note: The room SHOULD return the materially-relevant features it supports, such as password protection and room moderation (these are listed fully in the feature registry maintained by the XMPP Registrar; see also the <link url='#registrar'>XMPP Registrar</link> section of this document).</p>
- <p>A chatroom MAY return more detailed information in its disco#info response using &xep0128;, identified by inclusion of a hidden FORM_TYPE field whose value is "http://jabber.org/protocol/muc#roominfo". Such information might include a more verbose description of the room, the current room subject, and the current number of occupants in the room:</p>
+ <p>A chatroom MAY return more detailed information in its disco#info response using &xep0128;, identified by inclusion of a hidden FORM_TYPE field whose value is 'http://jabber.org/protocol/muc#roominfo'. Such information might include a more verbose description of the room, the current room subject, and the current number of occupants in the room:</p>
<example caption='Room Returns Extended Disco Info Results'><![CDATA[
<iq from='[email protected]'
id='ik3vs715'
@@ -2705,7 +2712,7 @@
</ol>
<p>These features shall be implemented with a request/response exchange using <iq/> 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 <u...@host> 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>
+ <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 or full JID. In order to ban a user, an admin MUST change the user's affiliation to "outcast".</p>
<example caption='Admin Bans User'><![CDATA[
<iq from='[email protected]/throne'
id='ban1'
@@ -2731,7 +2738,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 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>
<example caption='Service Informs Admin or Owner of Success'><![CDATA[
<iq from='[email protected]'
id='ban1'
@@ -2789,8 +2796,75 @@
]]></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>
</section2>
+ <section2 topic='Banning a Service' anchor='banserv'>
+ <p>An admin or owner can ban all users of a service. The ban MUST be performed based on the domain of that service. In order to ban all users that have a domainpart matching the service's domain, an admin MUST change the service's affiliation to "outcast".</p>
+ <example caption='Admin Bans Service'><![CDATA[
+<iq from='[email protected]/throne'
+ id='ban2'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='outcast'
+ jid='mozart.lit'/>
+ </query>
+</iq>
+ ]]></example>
+ <p>The <reason/> element is OPTIONAL.</p>
+ <example caption='Admin Bans Service (With a Reason)'><![CDATA[
+<iq from='[email protected]/throne'
+ id='ban2'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='outcast'
+ jid='mozart.lit'>
+ <reason>Treason</reason>
+ </item>
+ </query>
+</iq>
+ ]]></example>
+ <p>The service MUST add that domain to the ban list, SHOULD remove all nickname's of users with a matching domainpart 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='[email protected]'
+ id='ban2'
+ to='[email protected]/throne'
+ type='result'/>
+ ]]></example>
+ <p>The service MUST also remove any banned users who are in the room by sending a presence stanza of type "unavailable" to each banned occupant, including status code 301 in the extended presence information, optionally along with the reason (if provided) and the bare JID of the user who initiated the ban.</p>
+ <example caption='Service Removes Banned User'><![CDATA[
+<presence
+ from='[email protected]/musician'
+ to='[email protected]/piano'
+ type='unavailable'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='outcast' role='none'>
+ <actor jid='[email protected]'/>
+ <reason>Treason</reason>
+ </item>
+ <status code='301'/>
+ </x>
+</presence>
+ ]]></example>
+ <p>The inclusion of the status code assists clients in presenting their own notification messages (e.g., information appropriate to the user's locality). The optional inclusion of the reason and actor enable the banned user to understand why he or she was banned, and by whom if the banned user would like to discuss the matter.</p>
+ <p>The service MUST then inform all of the remaining occupants that the banned user is no longer in the room by sending presence stanzas of type "unavailable" from the banned user to all remaining occupants (just as it does when occupants exit the room of their own volition), including the status code and optionally the reason and actor:</p>
+ <example caption='Service Informs Remaining Occupants'><![CDATA[
+<presence
+ type='unavailable'
+ from='[email protected]/musician'
+ to='[email protected]/pda'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='outcast'
+ jid='[email protected]/piano'
+ role='none'/>
+ <status code='301'/>
+ </x>
+</presence>
+
+[ ... ]
+ ]]></example>
+ </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 may want to modify the ban list. To modify the list of banned JIDs, the admin first requests the ban list by querying the room for all entities with an affiliation of 'outcast'.</p>
<example caption='Admin Requests Ban List'><![CDATA[
<iq from='[email protected]/throne'
id='ban2'
@@ -2801,7 +2875,7 @@
</query>
</iq>
]]></example>
- <p>The service MUST then return the list of banned users to the admin; each item MUST include the 'affiliation' and 'jid' attributes but SHOULD NOT include the 'nick' and 'role' attributes:</p>
+ <p>The service MUST then return the list of banned entities to the admin; each item MUST include the 'affiliation' and 'jid' attributes but SHOULD NOT include the 'nick' and 'role' attributes:</p>
<example caption='Service Sends Ban List to Admin'><![CDATA[
<iq from='[email protected]'
id='ban2'
@@ -2845,17 +2919,9 @@
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>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 <cite>RFC 3921</cite>):</p>
- <ol start='1'>
- <li><u...@domain/resource> (only that resource matches)</li>
- <li><u...@domain> (any resource matches)</li>
- <li><domain/resource> (only that resource matches)</li>
- <li><domain> (the domain itself matches, as does any u...@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>
</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>
+ <section2 topic='Granting Membership to a User' 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 or full 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>
<example caption='Admin Grants Membership'><![CDATA[
<iq from='[email protected]/desktop'
id='member1'
@@ -2917,8 +2983,71 @@
[ ... ]
]]></example>
</section2>
+ <section2 topic='Granting Membership to a Service' anchor='grantservicemember'>
+ <p>An admin can grant membership to all users of a service; this is done by adding the service's domain to the member list. Even if a nick is provided the MUC service MUST NOT save a nick with the domain:</p>
+ <example caption='Admin Grants Membership'><![CDATA[
+<iq from='[email protected]/desktop'
+ id='member2'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='member'
+ jid='hamlet.lit'/>
+ </query>
+</iq>
+ ]]></example>
+ <p>The <reason/> element is OPTIONAL.</p>
+ <example caption='Admin Grants Membership (With a Reason)'><![CDATA[
+<iq from='[email protected]/desktop'
+ id='member2'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='member'
+ jid='hamlet.lit'>
+ <reason>A worthy witch indeed!</reason>
+ </item>
+ </query>
+</iq>
+ ]]></example>
+ <p>The service MUST add the domain to the member list and then inform the admin of success:</p>
+ <example caption='Service Informs Admin of Success'><![CDATA[
+<iq from='[email protected]'
+ id='member2'
+ to='[email protected]/desktop'
+ type='result'/>
+ ]]></example>
+ <p>If a user of the service is in the room, the MUC service MUST then send updated presence from this individual to all occupants, indicating the granting of membership by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "member".</p>
+ <example caption="Service Sends Notice of Membership to All Occupants"><![CDATA[
+<presence
+ from='[email protected]/thirdwitch'
+ to='[email protected]/desktop'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='member'
+ jid='[email protected]/book'
+ role='participant'/>
+ </x>
+</presence>
+
+[ ... ]
+ ]]></example>
+ <p>Additionally the service MAY send a message from the room itself to the room occupants, indicating the granting of membership by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> 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'
+ to='[email protected]/desktop'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='member'
+ jid='hamlet.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 may want to revoke an entity's membership; this is done by changing the entity's affiliation to "none":</p>
<example caption='Admin Revokes Membership'><![CDATA[
<iq from='[email protected]/desktop'
id='member2'
@@ -2944,14 +3073,14 @@
</query>
</iq>
]]></example>
- <p>The service MUST remove the user from the member list and then inform the moderator of success:</p>
+ <p>The service MUST remove the entity from the member list and then inform the moderator of success:</p>
<example caption='Service Informs Moderator of Success'><![CDATA[
<iq from='[email protected]'
id='member2'
to='[email protected]/desktop'
type='result'/>
]]></example>
- <p>The service MUST then send updated presence from this individual to all occupants, indicating the loss of membership by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "none".</p>
+ <p>The service MUST then send updated presence from all affected individuals to all occupants, indicating the loss of membership by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "none".</p>
<example caption="Service Notes Loss of Membership"><![CDATA[
<presence
from='[email protected]/thirdwitch'
@@ -2965,7 +3094,7 @@
[ ... ]
]]></example>
- <p>If the room is members-only, the service MUST remove the user from the room, including a status code of 321 to indicate that the user was removed because of an affiliation change, and inform all remaining occupants:</p>
+ <p>If the room is members-only, the service MUST remove the affected entities from the room, including a status code of 321 to indicate that the entity was removed because of an affiliation change, and inform all remaining occupants:</p>
<example caption='Service Removes Non-Member'><![CDATA[
<presence
from='[email protected]/thirdwitch'
@@ -2994,7 +3123,7 @@
</section2>
<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 entities (bare or full JID and reserved nick, or domain) who are registered with the room. Such entities may 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='[email protected]/desktop'
@@ -3691,7 +3820,7 @@
<p>If the room owner becomes unavailable for any reason before submitting the form (e.g., a lost connection), the service will receive a presence stanza of type "unavailable" from the owner to the owner's &ROOMJID; or to &ROOM; (or both). The service MUST then destroy the room, sending a presence stanza of type "unavailable" from the room to the owner including a <destroy/> element and reason (if provided) as defined in the <link url='#destroyroom'>Destroying a Room</link> section of this document.</p>
</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 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>The room creator requests a unique room name by sending an IQ-get to the service itself, containing an empty <unique/> element qualified by the 'http://jabber.org/protocol/muc#unique' namespace:</p>
<example caption='Entity Requests Unique Room Name'><![CDATA[
<iq from='[email protected]/desktop'
@@ -3966,7 +4095,7 @@
[ ... ]
]]></example>
- <p>A service MUST NOT allow an owner to revoke his or her own ownership privileges if there are no other owners; if an owner attempts to do this, the service MUST return a &conflict; error to the owner. However, a service SHOULD allow an owner to revoke his or her own ownership privileges if there are other owners.</p>
+ <p>A service MUST NOT allow an owner to revoke his or her own ownership privileges if there are no other owners; if an owner attempts to do this, the service MUST return a &conflict; error to the owner. However, a service SHOULD allow an owner to revoke his or her own ownership privileges if there are other owners. I.e. a service MUST NOT allow the owner list to become empty.</p>
<p>If as a result of a change in the room configuration a user gains ownership privileges while the user is in the room, the room MUST send updated presence for that individual to all occupants, denoting the change in status by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "owner" and the 'role' attribute set to an appropriate value given the affiliation and room type ("moderator" is recommended).</p>
<example caption="Service Notes Gain of Owner Affiliation to All Users"><![CDATA[
<presence
@@ -4004,7 +4133,7 @@
<p>For any other configuration change, the room SHOULD send status code 104 so that interested occupants can retrieve the updated room configuration if desired.</p>
</section3>
</section2>
- <section2 topic='Granting Ownership Privileges' anchor='grantowner'>
+ <section2 topic='Granting Ownership Privileges to a User' anchor='grantowner'>
<p>If allowed by an implementation, an owner MAY grant ownership privileges to another user; this is done by changing the user's affiliation to "owner":</p>
<example caption='Owner Grants Ownership Privileges'><![CDATA[
<iq from='[email protected]/desktop'
@@ -4067,8 +4196,71 @@
[ ... ]
]]></example>
</section2>
+ <section2 topic='Granting Ownership Privileges to a Service' anchor='grantownerservice'>
+ <p>If allowed by an implementation, an owner MAY grant ownership privileges all users of a service; this is done by adding the service's domain to the owner list:</p>
+ <example caption='Owner Grants Ownership Privileges'><![CDATA[
+<iq from='[email protected]/desktop'
+ id='owner2'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='owner'
+ jid='hamlet.lit'/>
+ </query>
+</iq>
+ ]]></example>
+ <p>The <reason/> element is OPTIONAL.</p>
+ <example caption='Owner Grants Ownership Privileges (With a Reason)'><![CDATA[
+<iq from='[email protected]/desktop'
+ id='owner2'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='owner'
+ jid='hamlet.lit'>
+ <reason>There is nothing either good or bad, but thinking makes it so.</reason>
+ </item>
+ </query>
+</iq>
+ ]]></example>
+ <p>The service MUST add the domain to the owner list and then inform the owner of success:</p>
+ <example caption='Service Informs Owner of Success'><![CDATA[
+<iq from='[email protected]'
+ id='owner2'
+ to='[email protected]/desktop'
+ type='result'/>
+ ]]></example>
+ <p>If an affected user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the granting of ownership privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "owner" and the 'role' attribute set to an appropriate value given the affiliation and room type ("moderator" is recommended).</p>
+ <example caption="Service Sends Notice of Ownership Privileges to All Occupants"><![CDATA[
+<presence
+ from='[email protected]/hecate'
+ to='[email protected]/desktop'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='owner'
+ jid='[email protected]'
+ role='moderator'/>
+ </x>
+</presence>
+
+[ ... ]
+ ]]></example>
+ <p>The service MAY send a message from the room itself to the room occupants, indicating the granting of ownership privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "owner".</p>
+ <example caption="Service Sends Notice of Ownership Privileges to All Occupants"><![CDATA[
+<message
+ from='chat.shakespeare.lit'
+ to='[email protected]/desktop'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='member'
+ jid='hamlet.lit'
+ role='none'/>
+ </x>
+</message>
+
+[ ... ]
+ ]]></example>
+ </section2>
<section2 topic='Revoking Ownership Privileges' anchor='revokeowner'>
- <p>An implementation MAY allow an owner to revoke another user's ownership privileges; this is done by changing the user's affiliation to something other than "owner":</p>
+ <p>An implementation MAY allow an owner to revoke an entity's ownership privileges; this is done by changing the entity's affiliation to something other than "owner":</p>
<example caption='Owner Revokes Ownership Privileges'><![CDATA[
<iq from='[email protected]/desktop'
id='owner2'
@@ -4097,14 +4289,14 @@
<p>A service MUST NOT allow an owner to revoke his or her own ownership privileges if there are no other owners; if an owner attempts to do this, the service MUST return a &conflict; error to the owner. However, a service SHOULD allow an owner to revoke his or her own ownership privileges if there are other owners.</p>
<p>If an implementation does not allow one owner to revoke another user's ownership privileges, the implementation MUST return a ¬authorized; error to the owner who made the request.</p>
<p>Note: Allowing an owner to remove another user's ownership privileges can compromise the control model for room management; therefore this feature is OPTIONAL, and implementations are encouraged to support owner removal through an interface that is open only to individuals with service-wide administrative privileges.</p>
- <p>In all other cases, the service MUST remove the user from the owner list and then inform the owner of success:</p>
+ <p>In all other cases, the service MUST remove the entity from the owner list and then inform the owner of success:</p>
<example caption='Service Informs Owner of Success'><![CDATA[
<iq from='[email protected]'
id='owner2'
to='[email protected]/desktop'
type='result'/>
]]></example>
- <p>If the user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the loss of ownership privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "owner" and the 'role' attribute set to an appropriate value:</p>
+ <p>If an affected user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the loss of ownership privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "owner" and the 'role' attribute set to an appropriate value:</p>
<example caption="Service Notes Loss of Owner Affiliation"><![CDATA[
<presence
from='[email protected]/secondwitch'
@@ -4118,7 +4310,7 @@
[ ... ]
]]></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 loss of ownership privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "owner".</p>
+ <p>If no affected user is in the room, or the entity is identified by a domain, the service MAY send a message from the room itself to the room occupants, indicating the loss of ownership privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "owner".</p>
<example caption="Service Notes Loss of Owner Affiliation"><![CDATA[
<message
from='chat.shakespeare.lit'
@@ -4134,7 +4326,7 @@
]]></example>
</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 may want to modify the owner list. To do so, the owner first requests the owner list by querying the room for all entities with an affiliation of 'owner'.</p>
<example caption='Owner Requests Owner List'><![CDATA[
<iq from='[email protected]/globe'
id='owner3'
@@ -4145,7 +4337,7 @@
</query>
</iq>
]]></example>
- <p>If the <u...@host> of the 'from' address does not match the bare JID of a room owner, the service MUST return a &forbidden; error to the sender.</p>
+ <p>If the 'from' address does not match the JID of a room owner, the service MUST return a &forbidden; error to the sender.</p>
<p>Otherwise, the service MUST then return the owner list to the owner; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for any owner that is currently an occupant:</p>
<example caption='Service Sends Owner List to Owner'><![CDATA[
<iq from='[email protected]'
@@ -4195,7 +4387,7 @@
]]></example>
<p>The service MUST also send presence notifications related to any affiliation changes that result from modifying the owner list as previously described.</p>
</section2>
- <section2 topic='Granting Administrative Privileges' anchor='grantadmin'>
+ <section2 topic='Granting Administrative Privileges to a User' anchor='grantadmin'>
<p>An owner can grant administrative privileges to a member or unaffiliated user; this is done by changing the user's affiliation to "admin":</p>
<example caption='Owner Grants Admin Privileges'><![CDATA[
<iq from='[email protected]/desktop'
@@ -4258,8 +4450,71 @@
[ ... ]
]]></example>
</section2>
+ <section2 topic='Granting Administrative Privileges to all Users of a Service' anchor='grantadminservice'>
+ <p>An owner can grant administrative privileges to all users of a service; this is done by changing the service's affiliation to "admin":</p>
+ <example caption='Owner Grants Admin Privileges'><![CDATA[
+<iq from='[email protected]/desktop'
+ id='admin1'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='admin'
+ jid='hamlet.lit'/>
+ </query>
+</iq>
+ ]]></example>
+ <p>The <reason/> element is OPTIONAL.</p>
+ <example caption='Owner Grants Admin Privileges (With a Reason)'><![CDATA[
+<iq from='[email protected]/desktop'
+ id='admin1'
+ to='[email protected]'
+ type='set'>
+ <query xmlns='http://jabber.org/protocol/muc#admin'>
+ <item affiliation='admin'
+ jid='hamlet.lit'>
+ <reason>There is nothing either good or bad, but thinking makes it so.</reason>
+ </item>
+ </query>
+</iq>
+ ]]></example>
+ <p>The service MUST add the service's domain to the admin list and then inform the owner of success:</p>
+ <example caption='Service Informs Owner of Success'><![CDATA[
+<iq from='[email protected]'
+ id='admin1'
+ to='[email protected]/desktop'
+ type='result'/>
+ ]]></example>
+ <p>If an affected user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the granting of administrative privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "admin" and the 'role' attribute set to an appropriate value given the affiliation and room type.</p>
+ <example caption="Service Sends Notice of Administrative Privileges to All Occupants"><![CDATA[
+<presence
+ from='[email protected]/secondwitch'
+ to='[email protected]/desktop'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='admin'
+ jid='[email protected]'
+ role='moderator'/>
+ </x>
+</presence>
+
+[ ... ]
+ ]]></example>
+ <p>The service MAY send a message from the room itself to the room occupants, indicating the granting of administrative privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value of "admin".</p>
+ <example caption="Service Sends Notice of Administrative Privileges to All Occupants"><![CDATA[
+<message
+ from='chat.shakespeare.lit'
+ to='[email protected]/desktop'>
+ <x xmlns='http://jabber.org/protocol/muc#user'>
+ <item affiliation='admin'
+ jid='hamlet.lit'
+ role='none'/>
+ </x>
+</message>
+
+[ ... ]
+ ]]></example>
+ </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 may want to revoke an entity's administrative privileges; this is done by changing the entity's affiliation to something other than "admin" or "owner":</p>
<example caption='Owner Revokes Administrative Privileges'><![CDATA[
<iq from='[email protected]/desktop'
id='admin2'
@@ -4285,14 +4540,14 @@
</query>
</iq>
]]></example>
- <p>The service MUST remove the user from the admin list and then inform the owner of success:</p>
+ <p>The service MUST remove the entity from the admin list and then inform the owner of success:</p>
<example caption='Service Informs Owner of Success'><![CDATA[
<iq from='[email protected]'
id='admin2'
to='[email protected]/desktop'
type='result'/>
]]></example>
- <p>If the user is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the loss of administrative privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "admin" or "owner" and the 'role' attribute set to an appropriate value given the affiliation level and the room type:</p>
+ <p>If an affected is in the room, the service MUST then send updated presence from this individual to all occupants, indicating the loss of administrative privileges by sending a presence element that contains an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "admin" or "owner" and the 'role' attribute set to an appropriate value given the affiliation level and the room type:</p>
<example caption="Service Notes Loss of Admin Affiliation"><![CDATA[
<presence
from='[email protected]/secondwitch'
@@ -4306,7 +4561,7 @@
[ ... ]
]]></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 loss of administrative privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "admin".</p>
+ <p>The service MAY send a message from the room itself to the room occupants, indicating the loss of administrative privileges by including an <x/> element qualified by the 'http://jabber.org/protocol/muc#user' namespace and containing an <item/> child with the 'affiliation' attribute set to a value other than "admin".</p>
<example caption="Service Notes Loss of Admin Affiliation"><![CDATA[
<message
from='chat.shakespeare.lit'
@@ -4322,7 +4577,7 @@
]]></example>
</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 may want to modify the admin list. To do so, the owner first requests the admin list by querying the room for all entities with an affiliation of 'admin'.</p>
<example caption='Owner Requests Admin List'><![CDATA[
<iq from='[email protected]/desktop'
id='admin3'
@@ -4333,7 +4588,7 @@
</query>
</iq>
]]></example>
- <p>If the <u...@host> of the 'from' address does not match the bare JID of a room owner, the service MUST return a &forbidden; error to the sender.</p>
+ <p>If the 'from' address does not match the JID of a room owner, the service MUST return a &forbidden; error to the sender.</p>
<p>Otherwise, the service MUST then return the admin list to the owner; each item MUST include the 'affiliation' and 'jid' attributes and MAY include the 'nick' and 'role' attributes for any admin that is currently an occupant:</p>
<example caption='Service Sends Admin List to Owner'><![CDATA[
<iq from='[email protected]'
@@ -4454,7 +4709,7 @@
to='[email protected]/desktop'
type='result'/>
]]></example>
- <p>If the <u...@host> of the 'from' address received on a destroy request does not match the bare JID of a room owner, the service MUST return a &forbidden; error to the sender:</p>
+ <p>If the 'from' address received on a destroy request does not match the JID of a room owner, the service MUST return a &forbidden; error to the sender:</p>
<example caption='Service Denies Destroy Request Submitted by Non-Owner'><![CDATA[
<iq from='[email protected]'
id='destroytest'