Mercurial > prosody-modules
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 4807:62a65c52c3f5 | 4808:8a63a0daf129 |
|---|---|
| 1 local array = require "util.array"; | |
| 2 local it = require "util.iterators"; | |
| 1 local jid = require "util.jid"; | 3 local jid = require "util.jid"; |
| 2 local sha256 = require "util.hashes".sha256; | 4 local sha256 = require "util.hashes".sha256; |
| 5 local set = require "util.set"; | |
| 3 local st = require "util.stanza"; | 6 local st = require "util.stanza"; |
| 4 | 7 |
| 5 local rtbl_service_jid = assert(module:get_option_string("muc_rtbl_jid"), "No RTBL JID supplied"); | 8 local rtbl_service_jid = assert(module:get_option_string("muc_rtbl_jid"), "No RTBL JID supplied"); |
| 6 local rtbl_node = module:get_option_string("muc_rtbl_node", "muc_bans_sha256"); | 9 local rtbl_node = module:get_option_string("muc_rtbl_node", "muc_bans_sha256"); |
| 7 | 10 |
| 24 | 27 |
| 25 on_item = function(event) | 28 on_item = function(event) |
| 26 local hash = event.item.attr.id; | 29 local hash = event.item.attr.id; |
| 27 if not hash then return; end | 30 if not hash then return; end |
| 28 module:log("debug", "Received new hash: %s", hash); | 31 module:log("debug", "Received new hash: %s", hash); |
| 29 banned_hashes[hash] = hash; | 32 banned_hashes[hash] = true; |
| 30 end; | 33 end; |
| 31 | 34 |
| 32 on_retract = function (event) | 35 on_retract = function (event) |
| 33 local hash = event.item.attr.id; | 36 local hash = event.item.attr.id; |
| 34 if not hash then return; end | 37 if not hash then return; end |
| 35 module:log("debug", "Retracted hash: %s", hash); | 38 module:log("debug", "Retracted hash: %s", hash); |
| 36 banned_hashes[hash] = nil; | 39 banned_hashes[hash] = nil; |
| 37 end; | 40 end; |
| 38 }); | 41 }); |
| 42 | |
| 43 function request_list() | |
| 44 local items_request = st.iq({ to = rtbl_service_jid, from = module.host, type = "get", id = "rtbl-request" }) | |
| 45 :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) | |
| 46 :tag("items", { node = rtbl_node }):up() | |
| 47 :up(); | |
| 48 | |
| 49 module:send(items_request); | |
| 50 end | |
| 51 | |
| 52 function update_list(event) | |
| 53 local from_jid = event.stanza.attr.from; | |
| 54 if from_jid ~= rtbl_service_jid then | |
| 55 module:log("debug", "Ignoring RTBL response from unknown sender"); | |
| 56 return; | |
| 57 end | |
| 58 local items_el = event.stanza:find("{http://jabber.org/protocol/pubsub}pubsub/items"); | |
| 59 if not items_el then | |
| 60 module:log("warn", "Invalid items response from RTBL service"); | |
| 61 return; | |
| 62 end | |
| 63 | |
| 64 local old_entries = set.new(array.collect(it.keys(banned_hashes))); | |
| 65 | |
| 66 local n_added, n_removed, n_total = 0, 0, 0; | |
| 67 for item in items_el:childtags("item") do | |
| 68 local hash = item.attr.id; | |
| 69 if hash then | |
| 70 n_total = n_total + 1; | |
| 71 if not old_entries:contains(hash) then | |
| 72 -- New entry | |
| 73 n_added = n_added + 1; | |
| 74 banned_hashes[hash] = true; | |
| 75 else | |
| 76 -- Entry already existed | |
| 77 old_entries:remove(hash); | |
| 78 end | |
| 79 end | |
| 80 end | |
| 81 | |
| 82 -- Remove old entries that weren't in the received list | |
| 83 for hash in old_entries do | |
| 84 n_removed = n_removed + 1; | |
| 85 banned_hashes[hash] = nil; | |
| 86 end | |
| 87 | |
| 88 module:log("info", "%d RTBL entries received from %s (%d added, %d removed)", n_total, from_jid, n_added, n_removed); | |
| 89 return true; | |
| 90 end | |
| 91 | |
| 92 module:hook("iq-result/host/rtbl-request", update_list); | |
| 39 | 93 |
| 40 module:hook("muc-occupant-pre-join", function (event) | 94 module:hook("muc-occupant-pre-join", function (event) |
| 41 local from_bare = jid.bare(event.stanza.attr.from); | 95 local from_bare = jid.bare(event.stanza.attr.from); |
| 42 local hash = sha256(jid.bare(event.stanza.attr.from), true); | 96 local hash = sha256(jid.bare(event.stanza.attr.from), true); |
| 43 if banned_hashes[hash] then | 97 if banned_hashes[hash] then |
| 45 local error_reply = st.error_reply(event.stanza, "cancel", "forbidden", "You are banned from this service", event.room.jid); | 99 local error_reply = st.error_reply(event.stanza, "cancel", "forbidden", "You are banned from this service", event.room.jid); |
| 46 event.origin.send(error_reply); | 100 event.origin.send(error_reply); |
| 47 return true; | 101 return true; |
| 48 end | 102 end |
| 49 end); | 103 end); |
| 104 | |
| 105 if prosody.start_time then | |
| 106 request_list(); | |
| 107 else | |
| 108 module:hook("server-started", request_list); | |
| 109 end |
