Software /
code /
prosody-modules
Comparison
mod_anti_spam/rtbl.lib.lua @ 5883:259ffdbf8906
mod_anti_spam: New module for spam filtering (pre-alpha)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Tue, 05 Mar 2024 18:26:29 +0000 |
comparison
equal
deleted
inserted
replaced
5882:761142ee0ff2 | 5883:259ffdbf8906 |
---|---|
1 local array = require "util.array"; | |
2 local id = require "util.id"; | |
3 local it = require "util.iterators"; | |
4 local set = require "util.set"; | |
5 local st = require "util.stanza"; | |
6 | |
7 module:depends("pubsub_subscription"); | |
8 | |
9 local function new_rtbl_subscription(rtbl_service_jid, rtbl_node, handlers) | |
10 local items = {}; | |
11 | |
12 local function notify(event_type, hash) | |
13 local handler = handlers[event_type]; | |
14 if not handler then return; end | |
15 handler(hash); | |
16 end | |
17 | |
18 module:add_item("pubsub-subscription", { | |
19 service = rtbl_service_jid; | |
20 node = rtbl_node; | |
21 | |
22 -- Callbacks: | |
23 on_subscribed = function() | |
24 module:log("info", "RTBL active: %s:%s", rtbl_service_jid, rtbl_node); | |
25 end; | |
26 | |
27 on_error = function(err) | |
28 module:log( | |
29 "error", | |
30 "Failed to subscribe to RTBL: %s:%s %s::%s: %s", | |
31 rtbl_service_jid, | |
32 rtbl_node, | |
33 err.type, | |
34 err.condition, | |
35 err.text | |
36 ); | |
37 end; | |
38 | |
39 on_item = function(event) | |
40 local hash = event.item.attr.id; | |
41 if not hash then return; end | |
42 module:log("debug", "Received new hash from %s:%s: %s", rtbl_service_jid, rtbl_node, hash); | |
43 items[hash] = true; | |
44 notify("added", hash); | |
45 end; | |
46 | |
47 on_retract = function (event) | |
48 local hash = event.item.attr.id; | |
49 if not hash then return; end | |
50 module:log("debug", "Retracted hash from %s:%s: %s", rtbl_service_jid, rtbl_node, hash); | |
51 items[hash] = nil; | |
52 notify("removed", hash); | |
53 end; | |
54 | |
55 purge = function() | |
56 module:log("debug", "Purge all hashes from %s:%s", rtbl_service_jid, rtbl_node); | |
57 for hash in pairs(items) do | |
58 items[hash] = nil; | |
59 notify("removed", hash); | |
60 end | |
61 end; | |
62 }); | |
63 | |
64 local request_id = "rtbl-request-"..id.short(); | |
65 | |
66 local function request_list() | |
67 local items_request = st.iq({ to = rtbl_service_jid, from = module.host, type = "get", id = request_id }) | |
68 :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) | |
69 :tag("items", { node = rtbl_node }):up() | |
70 :up(); | |
71 module:send(items_request); | |
72 end | |
73 | |
74 local function update_list(event) | |
75 local from_jid = event.stanza.attr.from; | |
76 if from_jid ~= rtbl_service_jid then | |
77 module:log("debug", "Ignoring RTBL response from unknown sender: %s", from_jid); | |
78 return; | |
79 end | |
80 local items_el = event.stanza:find("{http://jabber.org/protocol/pubsub}pubsub/items"); | |
81 if not items_el then | |
82 module:log("warn", "Invalid items response from RTBL service %s:%s", rtbl_service_jid, rtbl_node); | |
83 return; | |
84 end | |
85 | |
86 local old_entries = set.new(array.collect(it.keys(items))); | |
87 | |
88 local n_added, n_removed, n_total = 0, 0, 0; | |
89 for item in items_el:childtags("item") do | |
90 local hash = item.attr.id; | |
91 if hash then | |
92 n_total = n_total + 1; | |
93 if not old_entries:contains(hash) then | |
94 -- New entry | |
95 n_added = n_added + 1; | |
96 items[hash] = true; | |
97 notify("added", hash); | |
98 else | |
99 -- Entry already existed | |
100 old_entries:remove(hash); | |
101 end | |
102 end | |
103 end | |
104 | |
105 -- Remove old entries that weren't in the received list | |
106 for hash in old_entries do | |
107 n_removed = n_removed + 1; | |
108 items[hash] = nil; | |
109 notify("removed", hash); | |
110 end | |
111 | |
112 module:log("info", "%d RTBL entries received from %s:%s (%d added, %d removed)", n_total, from_jid, rtbl_node, n_added, n_removed); | |
113 return true; | |
114 end | |
115 | |
116 module:hook("iq-result/host/"..request_id, update_list); | |
117 module:add_timer(0, request_list); | |
118 end | |
119 | |
120 return { | |
121 new_rtbl_subscription = new_rtbl_subscription; | |
122 } |