annotate mod_muc_mention_notifications/mod_muc_mention_notifications.lua @ 5381:32a9817c7516

mod_firewall: Initialize compiled chunk just once for all handlers This should fix a case where some stateful dependencies (such as throttles) produce separate instances for every call to new_handler(), leading to surprising behaviour (e.g. rules executed via JUMP CHAIN vs ::deliver would have separate rate limits). This also adds better error handling in case the compiled code fails to run for some reason.
author Matthew Wild <mwild1@gmail.com>
date Fri, 28 Apr 2023 13:27:06 +0100
parents fc5c53d9d340
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4280
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
1 local jid = require "util.jid";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
2 local st = require "util.stanza";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
3 local datetime = require "util.datetime";
4305
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4280
diff changeset
4 local jid_resource = require "util.jid".resource;
4280
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
5
4307
af7297e49885 muc_mention_notifications: Rename module
JC Brand <jc@opkode.com>
parents: 4306
diff changeset
6 local notify_unaffiliated_users = module:get_option("muc_mmn_notify_unaffiliated_users", false)
4280
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
7
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
8 local muc_affiliation_store = module:open_store("config", "map");
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
9
4306
747a14017d00 muc_room_mention_notifications: Set xmlns to what's used in the protoXEP
JC Brand <jc@opkode.com>
parents: 4305
diff changeset
10 local mmn_xmlns = "urn:xmpp:mmn:0";
4280
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
11 local reference_xmlns = "urn:xmpp:reference:0";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
12 local forwarded_xmlns = "urn:xmpp:forward:0";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
13 local deplay_xmlns = "urn:xmpp:delay";
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
14
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
15
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
16 -- Returns a set of rooms the user is affiliated to
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
17 local function get_user_rooms(user_bare_jid)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
18 return muc_affiliation_store:get_all(user_bare_jid);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
19 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
20
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
21 local function is_eligible(user_bare_jid, room)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
22 if notify_unaffiliated_users then return true; end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
23
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
24 local user_rooms, err = get_user_rooms(user_bare_jid);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
25 if not user_rooms then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
26 if err then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
27 return false, err;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
28 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
29 return false;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
30 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
31
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
32 local room_node = jid.node(room.jid)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
33 if user_rooms[room_node] then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
34 return true;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
35 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
36
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
37 return false
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
38 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
39
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
40 -- Send a single notification for a room, updating data structures as needed
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
41 local function send_single_notification(user_bare_jid, room_jid, mention_stanza)
4313
fc5c53d9d340 mod_muc_mention_notifications: Send mention notifications from the MUC JID
JC Brand <jc@opkode.com>
parents: 4308
diff changeset
42 local notification = st.message({ to = user_bare_jid, from = room_jid })
4306
747a14017d00 muc_room_mention_notifications: Set xmlns to what's used in the protoXEP
JC Brand <jc@opkode.com>
parents: 4305
diff changeset
43 :tag("mentions", { xmlns = mmn_xmlns })
4280
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
44 :tag("forwarded", {xmlns = forwarded_xmlns})
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
45 :tag("delay", {xmlns = deplay_xmlns, stamp = datetime.datetime()}):up()
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
46 :add_child(mention_stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
47 :reset();
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
48 module:log("debug", "Sending mention notification from %s to %s", room_jid, user_bare_jid);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
49 return module:send(notification);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
50 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
51
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
52 local function notify_mentioned_users(room, client_mentions, mention_stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
53 module:log("debug", "NOTIFYING FOR %s", room.jid)
4305
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4280
diff changeset
54 for mentioned_jid in pairs(client_mentions) do
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4280
diff changeset
55 local user_bare_jid = mentioned_jid;
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4280
diff changeset
56 if (string.match(mentioned_jid, room.jid)) then
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4280
diff changeset
57 local nick = jid_resource(mentioned_jid);
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4280
diff changeset
58 user_bare_jid = room:get_registered_jid(nick);
2ca55a4da3ea muc_room_mention_notifications: Handle referenced JID being a MUC nickname JID
JC Brand <jc@opkode.com>
parents: 4280
diff changeset
59 end
4280
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
60 if is_eligible(user_bare_jid, room) then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
61 send_single_notification(user_bare_jid, room.jid, mention_stanza);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
62 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
63 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
64 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
65
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
66 local function get_mentions(stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
67 local has_mentions = false
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
68 local client_mentions = {}
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
69
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
70 for element in stanza:childtags("reference", reference_xmlns) do
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
71 if element.attr.type == "mention" then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
72 local user_bare_jid = element.attr.uri:match("^xmpp:(.+)$");
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
73 if user_bare_jid then
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
74 client_mentions[user_bare_jid] = user_bare_jid;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
75 has_mentions = true
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
76 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
77 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
78 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
79
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
80 return has_mentions, client_mentions
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
81 end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
82
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
83 module:hook("muc-broadcast-message", function (event)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
84 local room, stanza = event.room, event.stanza;
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
85 local body = stanza:get_child_text("body")
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
86 if not body or #body < 1 then return; end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
87 local correction = stanza:get_child("replace", "urn:xmpp:message-correct:0");
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
88 if correction then return; end -- Do not notify on message corrections
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
89
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
90 local has_mentions, client_mentions = get_mentions(stanza)
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
91 if not has_mentions then return; end
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
92
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
93 -- Notify any users that need to be notified
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
94 notify_mentioned_users(room, client_mentions, stanza);
278f2998ce49 mod_muc_room_mention_notifications: Publish module
Seve Ferrer <seve@delape.net>
parents:
diff changeset
95 end, -1);