MUC: Allow modules a chance to act prior to room destruction
authorKim Alvefur <zash@zash.se>
Sun, 05 Dec 2021 14:49:06 +0100
changeset 12014 f995d62044fa
parent 12013 f6fff0658108
child 12015 9dc36fdbdba1
MUC: Allow modules a chance to act prior to room destruction
plugins/muc/mod_muc.lua
plugins/muc/muc.lib.lua
--- a/plugins/muc/mod_muc.lua	Sat Dec 04 17:46:37 2021 +0100
+++ b/plugins/muc/mod_muc.lua	Sun Dec 05 14:49:06 2021 +0100
@@ -538,10 +538,14 @@
 			end
 			return { status = "completed", error = { message = t_concat(errmsg, "\n") } };
 		end
-		for _, room in ipairs(fields.rooms) do
-			get_room_from_jid(room):destroy();
+		local destroyed = array();
+		for _, room_jid in ipairs(fields.rooms) do
+			local room = get_room_from_jid(room_jid);
+			if room and room:destroy() then
+				destroyed:push(room.jid);
+			end
 		end
-		return { status = "completed", info = "The following rooms were destroyed:\n"..t_concat(fields.rooms, "\n") };
+		return { status = "completed", info = "The following rooms were destroyed:\n"..t_concat(destroyed, "\n") };
 	end);
 	local destroy_rooms_desc = adhoc_new("Destroy Rooms",
 		"http://prosody.im/protocol/muc#destroy", destroy_rooms_handler, "admin");
--- a/plugins/muc/muc.lib.lua	Sat Dec 04 17:46:37 2021 +0100
+++ b/plugins/muc/muc.lib.lua	Sun Dec 05 14:49:06 2021 +0100
@@ -1018,8 +1018,12 @@
 end
 
 function room_mt:destroy(newjid, reason, password)
-	local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"})
-		:tag("destroy", {jid=newjid});
+	local x = st.stanza("x", { xmlns = "http://jabber.org/protocol/muc#user" });
+	local event = { room = self; newjid = newjid; reason = reason; password = password; x = x, allowed = true };
+	module:fire_event("muc-pre-room-destroy", event);
+	if not event.allowed then return false, event.error; end
+	newjid, reason, password = event.newjid, event.reason, event.password;
+	x:tag("destroy", { jid = newjid });
 	if reason then x:tag("reason"):text(reason):up(); end
 	if password then x:tag("password"):text(password):up(); end
 	x:up();
@@ -1172,8 +1176,12 @@
 		local newjid = child.attr.jid;
 		local reason = child:get_child_text("reason");
 		local password = child:get_child_text("password");
-		self:destroy(newjid, reason, password);
-		origin.send(st.reply(stanza));
+		local destroyed, err = self:destroy(newjid, reason, password);
+		if destroyed then
+			origin.send(st.reply(stanza));
+		else
+			origin.send(st.error_reply(stanza, err or "cancel", "not-allowed"));
+		end
 		return true;
 	elseif child.name == "x" and child.attr.xmlns == "jabber:x:data" then
 		return self:process_form(origin, stanza);