Software /
code /
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 |
parent | 4807:62a65c52c3f5 |
child | 4809: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 |