changeset 5170:4d6af8950016

mod_muc_moderation: Derive role from reserved nickname if occupant When using a different client to moderate than the one used to participate in the chat, e.g. a command line tool like clix, there's no occupant and no role to use in the permission check. Previously the default role based on affiliation was used. Now if you are present in the room using your reserved nick, the role you have there is used in the permission check instead of the default affiliation-derived role.
author Kim Alvefur <zash@zash.se>
date Sun, 19 Feb 2023 18:17:37 +0100
parents 1071a420ff6f
children 1682166171ff
files mod_muc_moderation/mod_muc_moderation.lua
diffstat 1 files changed, 11 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/mod_muc_moderation/mod_muc_moderation.lua	Sun Feb 19 17:51:45 2023 +0100
+++ b/mod_muc_moderation/mod_muc_moderation.lua	Sun Feb 19 18:17:37 2023 +0100
@@ -41,16 +41,10 @@
 	local room_node = jid.split(room_jid);
 	local room = mod_muc.get_room_from_jid(room_jid);
 
-	-- Permissions
+	-- Permissions is based on role, which is a property of a current occupant,
+	-- so check if the actor is an occupant, otherwise if they have a reserved
+	-- nickname that can be used to retrieve the role.
 	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
-		return false, "auth", "forbidden", "You need a role of at least 'moderator'";
-	end
-
 	if not actor_nick then
 		local reserved_nickname = room:get_affiliation_data(jid.bare(actor), "reserved_nickname");
 		if reserved_nickname then
@@ -58,6 +52,14 @@
 		end
 	end
 
+	-- Retrieve their current role, iff they are in the room, otherwise what they
+	-- would have based on affiliation.
+	local affiliation = room:get_affiliation(actor);
+	local role = room:get_role(actor_nick) or room:get_default_role(affiliation);
+	if valid_roles[role or "none"] < valid_roles.moderator then
+		return false, "auth", "forbidden", "You need a role of at least 'moderator'";
+	end
+
 	-- Original stanza to base tombstone on
 	local original, err;
 	if muc_log_archive.get then