Mercurial > prosody-hg
diff plugins/muc/gc3.lib.lua @ 13908:356c8ec22e9a
MUC: Add basic "GC3" participant (affiliation) list fetch
RSM version currently held back until a planned restructuring of how we
store affiliations in MUC. This is because RSM needs a stable ordered list,
which we don't currently have.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Thu, 26 Jun 2025 15:17:57 +0100 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/muc/gc3.lib.lua Thu Jun 26 15:17:57 2025 +0100 @@ -0,0 +1,57 @@ + +local jid_bare = require "prosody.util.jid".bare; + +local st = require "prosody.util.stanza"; + +local muc_util = module:require "muc/util"; +local valid_affiliations = muc_util.valid_affiliations; + +local xmlns_gc3 = "urn:xmpp:gc3:tmp" + +--luacheck: ignore 113/get_room_from_jid + +function fetch_participant_list(room, stanza, origin) + local from_jid = stanza.attr.from; + local from_aff = room:get_affiliation(from_jid); + local from_rank = valid_affiliations[from_aff or "none"]; + + local required_aff_rank = valid_affiliations[room:get_members_only() and "member" or "none"]; + if from_rank < required_aff_rank then + origin.send(st.error_reply(stanza, "auth", "forbidden")); + return true; + end + + local can_see_real_jids = not room:is_anonymous_for(from_jid); + + local reply = st.reply(stanza) + :tag("participants", { xmlns = xmlns_gc3 }); + + for jid, aff in room:each_affiliation() do + local nick = room:get_registered_nick(jid); + local visible_jid = can_see_real_jids and jid or nil; + reply:text_tag("item", nil, { + affiliation = aff; + jid = visible_jid; + nick = nick; + id = room:get_occupant_id_from_jid(jid); + }); + end + + origin.send(reply); + return true; +end + +local function room_event_handler(handler, allow_nonexistent) + return function (event) + local origin, stanza = event.origin, event.stanza; + local room_jid = jid_bare(stanza.attr.to); + local room = get_room_from_jid(room_jid); + if not room and allow_nonexistent ~= true then + origin.send(st.error_reply(stanza, "cancel", "item-not-found")); + return true; + end + return handler(room, stanza, origin); + end; +end + +module:hook("iq-get/bare/"..xmlns_gc3..":participants", room_event_handler(fetch_participant_list));
