Mercurial > prosody-modules
diff mod_muc_rtbl/mod_muc_rtbl.lua @ 4808:8a63a0daf129
mod_muc_rtbl: Sync existing list entries when first loaded
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 06 Dec 2021 10:36:02 +0000 |
parents | 62a65c52c3f5 |
children | 9e9ec0f0b128 |
line wrap: on
line diff
--- a/mod_muc_rtbl/mod_muc_rtbl.lua Sun Dec 05 18:22:47 2021 +0000 +++ b/mod_muc_rtbl/mod_muc_rtbl.lua Mon Dec 06 10:36:02 2021 +0000 @@ -1,5 +1,8 @@ +local array = require "util.array"; +local it = require "util.iterators"; local jid = require "util.jid"; local sha256 = require "util.hashes".sha256; +local set = require "util.set"; local st = require "util.stanza"; local rtbl_service_jid = assert(module:get_option_string("muc_rtbl_jid"), "No RTBL JID supplied"); @@ -26,7 +29,7 @@ local hash = event.item.attr.id; if not hash then return; end module:log("debug", "Received new hash: %s", hash); - banned_hashes[hash] = hash; + banned_hashes[hash] = true; end; on_retract = function (event) @@ -37,6 +40,57 @@ end; }); +function request_list() + local items_request = st.iq({ to = rtbl_service_jid, from = module.host, type = "get", id = "rtbl-request" }) + :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) + :tag("items", { node = rtbl_node }):up() + :up(); + + module:send(items_request); +end + +function update_list(event) + local from_jid = event.stanza.attr.from; + if from_jid ~= rtbl_service_jid then + module:log("debug", "Ignoring RTBL response from unknown sender"); + return; + end + local items_el = event.stanza:find("{http://jabber.org/protocol/pubsub}pubsub/items"); + if not items_el then + module:log("warn", "Invalid items response from RTBL service"); + return; + end + + local old_entries = set.new(array.collect(it.keys(banned_hashes))); + + local n_added, n_removed, n_total = 0, 0, 0; + for item in items_el:childtags("item") do + local hash = item.attr.id; + if hash then + n_total = n_total + 1; + if not old_entries:contains(hash) then + -- New entry + n_added = n_added + 1; + banned_hashes[hash] = true; + else + -- Entry already existed + old_entries:remove(hash); + end + end + end + + -- Remove old entries that weren't in the received list + for hash in old_entries do + n_removed = n_removed + 1; + banned_hashes[hash] = nil; + end + + module:log("info", "%d RTBL entries received from %s (%d added, %d removed)", n_total, from_jid, n_added, n_removed); + return true; +end + +module:hook("iq-result/host/rtbl-request", update_list); + module:hook("muc-occupant-pre-join", function (event) local from_bare = jid.bare(event.stanza.attr.from); local hash = sha256(jid.bare(event.stanza.attr.from), true); @@ -47,3 +101,9 @@ return true; end end); + +if prosody.start_time then + request_list(); +else + module:hook("server-started", request_list); +end