changeset 5169:1071a420ff6f

mod_muc_moderation: Refactor to prepare for new version of XEP-0425 Plan is to add support for both versions concurrently for a transition period while clients upgrade.
author Kim Alvefur <zash@zash.se>
date Sun, 19 Feb 2023 17:51:45 +0100
parents e00dc913d965
children 4d6af8950016
files mod_muc_moderation/mod_muc_moderation.lua
diffstat 1 files changed, 35 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/mod_muc_moderation/mod_muc_moderation.lua	Sun Feb 19 17:39:04 2023 +0100
+++ b/mod_muc_moderation/mod_muc_moderation.lua	Sun Feb 19 17:51:45 2023 +0100
@@ -34,34 +34,21 @@
 	event.reply:tag("feature", { var = xmlns_moderate }):up();
 end);
 
--- Main handling
-module:hook("iq-set/bare/" .. xmlns_fasten .. ":apply-to", function (event)
-	local stanza, origin = event.stanza, event.origin;
+-- TODO error registry, requires Prosody 0.12+
 
-	-- Collect info we need
-	local apply_to = stanza.tags[1];
-	local moderate_tag = apply_to:get_child("moderate", xmlns_moderate);
-	if not moderate_tag then return end -- some other kind of fastening?
-
-	local reason = moderate_tag:get_child_text("reason");
-	local retract = moderate_tag:get_child("retract", xmlns_retract);
-
-	local room_jid = stanza.attr.to;
+-- moderate : function (string, string, string, boolean, string) : boolean, enum, enum, string
+local function moderate(actor, room_jid, stanza_id, retract, reason)
 	local room_node = jid.split(room_jid);
 	local room = mod_muc.get_room_from_jid(room_jid);
 
-	local stanza_id = apply_to.attr.id;
-
 	-- Permissions
-	local actor = stanza.attr.from;
 	local actor_nick = room:get_occupant_jid(actor);
 	local affiliation = room:get_affiliation(actor);
 	-- Retrieve their current role, iff they are in the room, otherwise what they
 	-- would have based on affiliation.
 	local role = room:get_role(actor_nick) or room:get_default_role(affiliation);
 	if valid_roles[role or "none"] < valid_roles.moderator then
-		origin.send(st.error_reply(stanza, "auth", "forbidden", "You need a role of at least 'moderator'"));
-		return true;
+		return false, "auth", "forbidden", "You need a role of at least 'moderator'";
 	end
 
 	if not actor_nick then
@@ -84,13 +71,13 @@
 			end
 		end
 	end
+
 	if not original then
 		if err == "item-not-found" then
-			origin.send(st.error_reply(stanza, "modify", "item-not-found"));
+			return false, "modify", "item-not-found";
 		else
-			origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
+			return false, "wait", "internal-server-error";
 		end
-		return true;
 	end
 
 
@@ -114,11 +101,11 @@
 		if reason then
 			tombstone:text_tag("reason", reason);
 		end
+		tombstone:reset();
 
 		local was_replaced = muc_log_archive:set(room_node, stanza_id, tombstone);
 		if not was_replaced then
-			origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
-			return true;
+			return false, "wait", "internal-server-error";
 		end
 	end
 
@@ -126,6 +113,32 @@
 	module:log("info", "Message with id '%s' in room %s moderated by %s, reason: %s", stanza_id, room_jid, actor, reason);
 	room:broadcast_message(announcement);
 
+	return true;
+end
+
+-- Main handling
+module:hook("iq-set/bare/" .. xmlns_fasten .. ":apply-to", function (event)
+	local stanza, origin = event.stanza, event.origin;
+
+	local actor = stanza.attr.from;
+	local room_jid = stanza.attr.to;
+
+	-- Collect info we need
+	local apply_to = stanza.tags[1];
+	local moderate_tag = apply_to:get_child("moderate", xmlns_moderate);
+	if not moderate_tag then return end -- some other kind of fastening?
+
+	local reason = moderate_tag:get_child_text("reason");
+	local retract = moderate_tag:get_child("retract", xmlns_retract);
+
+	local stanza_id = apply_to.attr.id;
+
+	local ok, error_type, error_condition, error_text = moderate(actor, room_jid, stanza_id, retract, reason);
+	if not ok then
+		origin.send(st.error_reply(stanza, error_type, error_condition, error_text));
+		return true;
+	end
+
 	origin.send(st.reply(stanza));
 	return true;
 end);