MUC: Record reason for affiliation changes and return in list (fixes #1227)
authorKim Alvefur <zash@zash.se>
Sun, 08 Aug 2021 18:07:17 +0200
changeset 13419 f34b33cb1383
parent 13418 d54364746a7c
child 13420 d8e885db9851
MUC: Record reason for affiliation changes and return in list (fixes #1227)
CHANGES
plugins/muc/muc.lib.lua
spec/scansion/muc_outcast_reason.scs
--- a/CHANGES	Tue Jan 23 13:00:58 2024 +0100
+++ b/CHANGES	Sun Aug 08 18:07:17 2021 +0200
@@ -24,6 +24,7 @@
   - Public rooms can only be created by local users (parent host) by default
     - muc_room_allow_public = false restricts to admins
 - Commands to show occupants and affiliations in the Shell
+- Save 'reason' text supplied with affiliation change
 
 ### Security and authentication
 
--- a/plugins/muc/muc.lib.lua	Tue Jan 23 13:00:58 2024 +0100
+++ b/plugins/muc/muc.lib.lua	Sun Aug 08 18:07:17 2021 +0200
@@ -1079,7 +1079,10 @@
 	local reason = item:get_child_text("reason");
 	local success, errtype, err
 	if item.attr.affiliation and item.attr.jid and not item.attr.role then
-		local registration_data;
+		local registration_data = self:get_affiliation_data(item.attr.jid) or {};
+		if reason then
+			registration_data.reason = reason;
+		end
 		if item.attr.nick then
 			local room_nick = self.jid.."/"..item.attr.nick;
 			local existing_occupant = self:get_occupant_by_nick(room_nick);
@@ -1088,7 +1091,7 @@
 				self:set_role(true, room_nick, nil, "This nickname is reserved");
 			end
 			module:log("debug", "Reserving %s for %s (%s)", item.attr.nick, item.attr.jid, item.attr.affiliation);
-			registration_data = { reserved_nickname = item.attr.nick };
+			registration_data.reserved_nickname = item.attr.nick;
 		end
 		success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, reason, registration_data);
 	elseif item.attr.role and item.attr.nick and not item.attr.affiliation then
@@ -1119,9 +1122,13 @@
 		if (affiliation_rank >= valid_affiliations.admin and affiliation_rank >= _aff_rank)
 		or (self:get_members_only() and self:get_whois() == "anyone" and affiliation_rank >= valid_affiliations.member) then
 			local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
-			for jid in self:each_affiliation(_aff or "none") do
+			for jid, _, data in self:each_affiliation(_aff or "none") do
 				local nick = self:get_registered_nick(jid);
-				reply:tag("item", {affiliation = _aff, jid = jid, nick = nick }):up();
+				reply:tag("item", {affiliation = _aff, jid = jid, nick = nick });
+				if data and data.reason then
+					reply:text_tag("reason", data.reason);
+				end
+				reply:up();
 			end
 			origin.send(reply:up());
 			return true;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/scansion/muc_outcast_reason.scs	Sun Aug 08 18:07:17 2021 +0200
@@ -0,0 +1,72 @@
+# Save ban reason
+
+[Client] Romeo
+	password: password
+	jid: user@localhost
+
+-----
+
+Romeo connects
+
+Romeo sends:
+	<presence to="muc-outcast-reason@conference.localhost/Romeo">
+		<x xmlns="http://jabber.org/protocol/muc"/>
+	</presence>
+
+Romeo receives:
+	<presence from="muc-outcast-reason@conference.localhost/Romeo">
+		<x xmlns="http://jabber.org/protocol/muc#user">
+			<status code="201"/>
+			<item jid="${Romeo's full JID}" role="moderator" affiliation="owner"/>
+			<status code="110"/>
+		</x>
+	</presence>
+
+Romeo receives:
+	<message type="groupchat" from="muc-outcast-reason@conference.localhost">
+		<subject/>
+	</message>
+
+Romeo sends:
+	<iq id="lx5" to="muc-outcast-reason@conference.localhost" type="set">
+		<query xmlns="http://jabber.org/protocol/muc#admin">
+			<item affiliation="outcast" jid="tybalt@localhost">
+				<reason>Hey calm down</reason>
+			</item>
+		</query>
+	</iq>
+
+Romeo receives:
+	<message from="muc-outcast-reason@conference.localhost">
+		<x xmlns="http://jabber.org/protocol/muc#user">
+			<status code="301"/>
+			<item jid="tybalt@localhost" affiliation="outcast">
+				<reason>Hey calm down</reason>
+			</item>
+		</x>
+	</message>
+
+Romeo receives:
+	<iq id="lx5" type="result" from="muc-outcast-reason@conference.localhost"/>
+
+Romeo sends:
+	<iq id="lx6" to="muc-outcast-reason@conference.localhost" type="get">
+		<query xmlns="http://jabber.org/protocol/muc#admin">
+			<item affiliation="outcast"/>
+		</query>
+	</iq>
+
+Romeo receives:
+	<iq id="lx6" type="result" from="muc-outcast-reason@conference.localhost">
+		<query xmlns="http://jabber.org/protocol/muc#admin">
+			<item jid="tybalt@localhost" affiliation="outcast">
+				<reason>Hey calm down</reason>
+			</item>
+		</query>
+	</iq>
+
+Romeo disconnects
+
+Romeo sends:
+	<presence type='unavailable'/>
+