From 8e12c18d4a6ffcde0b0555ada124ea949d2b9be9 Mon Sep 17 00:00:00 2001 From: Alexander PapaTutuWawa Date: Fri, 19 Feb 2021 17:03:17 +0100 Subject: [PATCH] mod_mix: Various things --- mod_mix/mod_mix.lua | 93 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/mod_mix/mod_mix.lua b/mod_mix/mod_mix.lua index 2dda116..a36fec4 100644 --- a/mod_mix/mod_mix.lua +++ b/mod_mix/mod_mix.lua @@ -1,3 +1,7 @@ +-- Big TODOlist +-- TODO: Channel:is_subscribed could be replaced by get_pep_service(...):get_subscription +-- TODO: All channels[i] can probably safely be replaced with channel. + local host = module:get_host(); if module:get_host_type() ~= "component" then error("MIX should be loaded as a component", 0); @@ -20,9 +24,14 @@ Participant = mixlib.Participant; -- XML namespaces local mix_core_xmlns = "urn:xmpp:mix:core:1"; +--local mix_admin_xmlns = "urn:xmpp:mix:admin:0"; local mix_node_messages = "urn:xmpp:mix:nodes:messages"; local mix_node_participants = "urn:xmpp:mix:nodes:participants"; local mix_node_info = "urn:xmpp:mix:nodes:info"; +local mix_node_allowed = "urn:xmpp:mix:nodes:allowed"; +local mix_node_banned = "urn:xmpp:mix:nodes:banned"; +local mix_node_config = "urn:xmpp:mix:nodes:config"; + local mam_xmlns = "urn:xmpp:mam:2"; -- Persistent data @@ -43,8 +52,26 @@ local mam_query_form = dataforms.new({ { name = "end", type = "text-single" }, }); +-- MIX-ADMIN stuff +--[[ +local mix_config_form = dataforms.new({ + { name = "FORM_TYPE", type = "hidden", value = mix_admin_xmlns }, + { name = "Last Change Made By", type = "jid-single" }, + { name = "Owner", type = "jid-multi" }, + { name = "Administrator", type = "jid-multi" }, + { name = "End of Life", type = "text-single" }, + { name = "Nodes Present", type = "list-multi" }, + { name = "Message Node Subscription", type = "list-single" }, + { name = "Presence Node Subscription", type = "list-single" }, + { name = "Participants Node Subscription", type = "list-single" }, + { name = "Information Node Subscription", type = "list-single" }, + { name = "Allowed Node Subscription", type = "list-single" }, + { name = "Banned Node Subscription", type = "list-single" }, + { name = "Configuration Node Access", type = "list-single" }, +}); +]]-- + module:depends("disco"); --- module:depends("mam"); TODO: Once message sending works module:add_identity("conference", "mix", module:get_option("name", "Prosody MIX service")); module:add_feature("http://jabber.org/protocol/disco#info"); module:add_feature(mix_core_xmlns); @@ -78,8 +105,13 @@ function Channel:save_state() module:log("debug", "Saving state done.", self.jid); end -function publish_participant(service, spid, participant) +function publish_participant(service, channel, spid, participant) -- Publish a new participant on the service + -- NOTE: This function has be to called *after* the new participant + -- has been added to the channel.participants attay + service:set_node_config("urn:xmpp:mix:nodes:participants", + true, + { ["max_items"] = #channel.participants }); service:publish("urn:xmpp:mix:nodes:participants", true, spid, @@ -322,6 +354,7 @@ module:hook("iq-set/bare/"..mix_core_xmlns..":leave", function(event) -- Unsubscribing local srv = pep.get_pep_service(channel.jid); for _, node in pairs(channel.subscriptions[from]) do + srv:set_affiliation(node, true, from, "outcast"); srv:remove_subscription(node, true, from); module:log("debug", "Unsubscribed %s from %s on %s", from, node, channel.jid); end @@ -359,14 +392,23 @@ module:hook("iq-set/bare/"..mix_core_xmlns..":join", function(event) :tag("join", { xmlns = mix_core_xmlns, id = spid }); local srv = pep.get_pep_service(jid.node(stanza.attr.to)); local join = stanza:get_child("join", mix_core_xmlns); - local nick = join:get_child("nick"); - module:log("debug", "User joining as nick %s", nick:get_text()); + local nick_tag = join:get_child("nick"); + local nick; + if not join:get_child("nick") then + nick = jid.node(from); + else + nick = join:get_child("nick"):get_text(); + end + module:log("debug", "User joining as nick %s", nick); local nodes = {}; local has_subscribed_once = false; local first_error = nil; for subscribe in join:childtags("subscribe") do module:log("debug", "Subscribing user to node %s", subscribe.attr.node); + -- TODO: Once MIX-ADMIN is implemented, we should check here what + -- affiliation we set, e.g. if the JID is the owner, then set owner. + srv:set_affiliation(subscribe.attr.node, true, from, "member"); local ok, err = srv:add_subscription(subscribe.attr.node, true, from); if not ok then module:log("debug", "Error during subscription: %s", err); @@ -388,11 +430,11 @@ module:hook("iq-set/bare/"..mix_core_xmlns..":join", function(event) return true; end - local participant = Participant:new(jid.bare(from), nick:get_text()) + local participant = Participant:new(jid.bare(from), nick); channels[i].subscriptions[from] = nodes; table.insert(channels[i].participants, participant) channels[i]:set_spid(jid.bare(stanza.attr.from), spid); - publish_participant(srv, spid, participant); + publish_participant(srv, channel, spid, participant); channels[i]:save_state(); reply:add_child(nick); @@ -430,7 +472,7 @@ module:hook("iq-set/bare/"..mix_core_xmlns..":setnick", function(event) -- Inform all other members local srv = pep.get_pep_service(channel.jid); --local participant = channel.participants[participant_index]; - publish_participant(srv, channel:get_spid(participant.jid), participant); + publish_participant(srv, channel, channel:get_spid(participant.jid), participant); origin.send(st.reply(stanza) :tag("setnick", { xmlns = mix_core_xmlns }) @@ -466,17 +508,33 @@ function create_channel(node, creator, adhoc) -- Create the PEP nodes local srv = pep.get_pep_service(node); local timestamp = datetime.datetime(time.now()); - local access_model = adhoc and "whitelist" or "open"; + -- MIX-CORE for _, psnode in pairs({ mix_node_info, mix_node_participants, mix_node_messages }) do - srv:create(psnode, true, { ["access_model"] = access_model }); - - -- If the channel is an adhoc channel, then we need to make sure that - -- node affiliations are correct - if adhoc then - srv:set_affiliation(psnode, true, creator, "owner"); - end + srv:create(psnode, true, { + ["access_model"] = "whitelist", + ["persist_items"] = true, + }); end channel:publish_info(srv); + + --[[ + -- MIX-ADMIN + local admin_nodes = { mix_node_banned, mix_node_config }; + if adhoc then + table.insert(admin_nodes, mix_node_allowed); + end + for _, psnode in pairs(admin_nodes) do + srv:create(mix_node_allowed, true, { ["access_model"] = "whitelist" }); + srv:set_affiliation(mix_node_allowed, true, creator, "owner"); + end + if adhoc then + -- Allow the creator to join + srv:publish(mix_node_allowed, + true, + nil, + st.stanza("item", { id = creator })); + end + ]]-- table.insert(channels, channel); end @@ -593,9 +651,12 @@ module:hook("message/bare", function(event) -- NOTE: The spec says to do so msg.attr.from = channel.jid; message_archive:append(stanza.attr.to, mam_id, msg, time.now()); - module:log("debug", "Message put into MAM archive!"); msg.attr.from = channel.jid.."/"..channel:get_spid(from); + if module:fire_event("mix-broadcast-message", msg) then + return true; + end + for _, p in pairs(channel.participants) do -- Only users who subscribed to the messages node should receive -- messages