Comparison

plugins/muc/occupant_id.lib.lua @ 11215:9ce0a899ff07

MUC: Merge mod_muc_occupant_id into a sub-module (thanks pep.!)
author Matthew Wild <mwild1@gmail.com>
date Tue, 24 Nov 2020 10:38:56 +0000
child 12108:e9882c4c397f
comparison
equal deleted inserted replaced
11214:5fb6563eee1e 11215:9ce0a899ff07
1 -- Implementation of https://xmpp.org/extensions/inbox/occupant-id.html
2 -- XEP-0421: Anonymous unique occupant identifiers for MUCs
3
4 -- (C) 2020 Maxime “pep” Buquet <pep@bouah.net>
5 -- (C) 2020 Matthew Wild <mwild1@gmail.com>
6
7 local uuid = require "util.uuid";
8 local hmac_sha256 = require "util.hashes".hmac_sha256;
9 local b64encode = require "util.encodings".base64.encode;
10
11 local xmlns_occupant_id = "urn:xmpp:occupant-id:0";
12
13 local function get_occupant_id(room, occupant)
14 if occupant.stable_id then
15 return occupant.stable_id;
16 end
17
18 local salt = room._data.occupant_id_salt;
19 if not salt then
20 salt = uuid.generate();
21 room._data.occupant_id_salt = salt;
22 end
23
24 occupant.stable_id = b64encode(hmac_sha256(occupant.bare_jid, salt));
25
26 return occupant.stable_id;
27 end
28
29 local function update_occupant(event)
30 local stanza, room, occupant, dest_occupant = event.stanza, event.room, event.occupant, event.dest_occupant;
31
32 -- "muc-occupant-pre-change" provides "dest_occupant" but not "occupant".
33 if dest_occupant ~= nil then
34 occupant = dest_occupant;
35 end
36
37 -- strip any existing <occupant-id/> tags to avoid forgery
38 stanza:remove_children("occupant-id", xmlns_occupant_id);
39
40 local unique_id = get_occupant_id(room, occupant);
41 stanza:tag("occupant-id", { xmlns = xmlns_occupant_id, id = unique_id }):up();
42 end
43
44 local function muc_private(event)
45 local stanza, room = event.stanza, event.room;
46 local occupant = room._occupants[stanza.attr.from];
47
48 update_occupant({
49 stanza = stanza,
50 room = room,
51 occupant = occupant,
52 });
53 end
54
55 if module:get_option_boolean("muc_occupant_id", true) then
56 module:add_feature(xmlns_occupant_id);
57 module:hook("muc-disco#info", function (event)
58 event.reply:tag("feature", { var = xmlns_occupant_id }):up();
59 end);
60
61 module:hook("muc-broadcast-presence", update_occupant);
62 module:hook("muc-occupant-pre-join", update_occupant);
63 module:hook("muc-occupant-pre-change", update_occupant);
64 module:hook("muc-occupant-groupchat", update_occupant);
65 module:hook("muc-private-message", muc_private);
66 end
67
68 return {
69 get_occupant_id = get_occupant_id;
70 };