comparison mod_muc_rtbl/mod_muc_rtbl.lua @ 5173:460f78654864

mod_muc_rtbl: also filter messages This was a bit tricky because we don't want to run the JIDs through SHA256 on each message. Took a while to come up with this simple plan of just caching the SHA256 of the JIDs on the occupants. This will leave some dirt in the occupants after unloading the module, but that should be ok; once they cycle the room, the hashes will be gone. This is direly needed, otherwise, there is a tight race between the moderation activities and the actors joining the room.
author Jonas Schäfer <jonas@wielicki.name>
date Tue, 21 Feb 2023 21:37:27 +0100
parents 0a257d1402c3
children 354832098f2f
comparison
equal deleted inserted replaced
5172:dc6a10629670 5173:460f78654864
89 return true; 89 return true;
90 end 90 end
91 91
92 module:hook("iq-result/host/rtbl-request", update_list); 92 module:hook("iq-result/host/rtbl-request", update_list);
93 93
94 function update_hashes(occupant)
95 if not occupant.mod_muc_rtbl_bare_hash then
96 local bare_hash = sha256(jid.bare(event.stanza.attr.from), true);
97 occupant.mod_muc_rtbl_bare_hash = bare_hash;
98 end
99 if not occupant.mod_muc_rtbl_host_hash then
100 local host_hash = sha256(jid.host(event.stanza.attr.from), true);
101 event.occupant.mod_muc_rtbl_host_hash = host_hash;
102 end
103 end
104
94 module:hook("muc-occupant-pre-join", function (event) 105 module:hook("muc-occupant-pre-join", function (event)
95 if next(banned_hashes) == nil then return end 106 if next(banned_hashes) == nil then return end
96 107
97 local from_bare = jid.bare(event.stanza.attr.from); 108 local from_bare = jid.bare(event.stanza.attr.from);
98 109
100 if affiliation and affiliation ~= "none" then 111 if affiliation and affiliation ~= "none" then
101 -- Skip check for affiliated users 112 -- Skip check for affiliated users
102 return; 113 return;
103 end 114 end
104 115
105 local bare_hash = sha256(jid.bare(event.stanza.attr.from), true); 116 update_hashes(event.occupant);
106 local host_hash = sha256(jid.host(event.stanza.attr.from), true); 117 if banned_hashes[event.occupant.mod_muc_rtbl_bare_hash] or banned_hashes[event.occupant.mod_muc_rtbl_host_hash] then
107 if banned_hashes[bare_hash] or banned_hashes[host_hash] then
108 module:log("info", "Blocked user <%s> from room <%s> due to RTBL match", from_bare, event.stanza.attr.to); 118 module:log("info", "Blocked user <%s> from room <%s> due to RTBL match", from_bare, event.stanza.attr.to);
119 local error_reply = st.error_reply(event.stanza, "cancel", "forbidden", "You are banned from this service", event.room.jid);
120 event.origin.send(error_reply);
121 return true;
122 end
123 end);
124
125 module:hook("muc-occupant-groupchat", function(event)
126 update_hashes(event.occupant);
127 if banned_hashes[event.occupant.mod_muc_rtbl_bare_hash] or banned_hashes[event.occupant.mod_muc_rtbl_host_hash] then
128 module:log("debug", "Blocked message from user <%s> to room <%s> due to RTBL match", event.stanza.attr.from, event.stanza.attr.to);
129 local error_reply = st.error_reply(event.stanza, "cancel", "forbidden", "You are banned from this service", event.room.jid);
130 event.origin.send(error_reply);
131 return true;
132 end
133 end);
134
135 module:hook("muc-private-message", function(event)
136 local occupant = event.room:get_occupant_by_nick(event.stanza.attr.from);
137 update_hashes(occupant);
138 if banned_hashes[occupant.mod_muc_rtbl_bare_hash] or banned_hashes[occupant.mod_muc_rtbl_host_hash] then
139 module:log("debug", "Blocked private message from user <%s> from room <%s> due to RTBL match", occupant.bare_jid, event.stanza.attr.to);
109 local error_reply = st.error_reply(event.stanza, "cancel", "forbidden", "You are banned from this service", event.room.jid); 140 local error_reply = st.error_reply(event.stanza, "cancel", "forbidden", "You are banned from this service", event.room.jid);
110 event.origin.send(error_reply); 141 event.origin.send(error_reply);
111 return true; 142 return true;
112 end 143 end
113 end); 144 end);