mod_muc_occupant_id/mod_muc_occupant_id.lua
author Maxime “pep” Buquet <pep@bouah.net>
Wed, 17 Jul 2019 13:23:23 +0200
changeset 3635 d6164ae6179c
parent 3634 c05e157d987c
child 3636 83a68f5fde1d
permissions -rw-r--r--
mod_muc_occupant_id: Update links to the XEP inbox.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3633
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     1
3635
d6164ae6179c mod_muc_occupant_id: Update links to the XEP inbox.
Maxime “pep” Buquet <pep@bouah.net>
parents: 3634
diff changeset
     2
-- Implementation of https://xmpp.org/extensions/inbox/occupant-id.html
3633
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     3
-- XEP-XXXX: Anonymous unique occupant identifiers for MUCs
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     4
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     5
local uuid = require "util.uuid";
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     6
local hmac_sha256 = require "util.hashes".hmac_sha256;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     7
local b64encode = require "util.encodings".base64.encode;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     8
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
     9
local xmlns_occupant_id = "urn:xmpp:occupant-id:0";
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    10
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    11
local function edit_occupant(event)
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    12
	local occupant, room = event.occupant, event.room;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    13
	local bare = occupant.bare_jid;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    14
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    15
	-- TODO: Move the salt on the MUC component. Setting the salt on the room
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    16
	-- can be problematic when the room is destroyed. Next time it's recreated
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    17
	-- the salt will be different and so will be the unique_id. Or maybe we want
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    18
	-- this anyway?
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    19
	if room._data.occupant_id_salt == nil then
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    20
		local salt = uuid.generate();
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    21
		room._data.occupant_id_salt = salt;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    22
	end
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    23
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    24
	local unique_id = b64encode(hmac_sha256(bare, room._data.occupant_id_salt));
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    25
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    26
	-- TODO: Store this only once per bare jid and not once per occupant?
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    27
	local stanza = event.stanza;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    28
	stanza:tag("occupant-id", { xmlns = xmlns_occupant_id })
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    29
		:text(unique_id)
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    30
		:up();
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    31
end
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    32
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    33
local function handle_stanza(event)
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    34
	local stanza, occupant = event.stanza, event.occupant;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    35
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    36
	if stanza.name == "presence" and stanza.attr.type == "unavailable" then -- not required here
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    37
		return;
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    38
	end
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    39
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    40
	-- strip any existing <occupant-id/> tags to avoid forgery
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    41
	stanza:remove_children("occupant-id", xmlns_occupant_id);
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    42
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    43
	local unique_id = occupant.sessions[stanza.attr.from]
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    44
		:get_child("occupant-id", xmlns_occupant_id)
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    45
		:get_text();
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    46
	stanza:tag("occupant-id", { xmlns = xmlns_occupant_id })
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    47
		:text(unique_id)
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    48
		:up();
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    49
end
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    50
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    51
module:add_feature(xmlns_occupant_id);
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    52
module:hook("muc-disco#info", function (event)
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    53
	event.reply:tag("feature", { var = xmlns_occupant_id }):up();
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    54
end);
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    55
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    56
module:hook("muc-occupant-pre-join", edit_occupant);
cfe0907808e1 mod_muc_occupant_id: initial commit
Maxime “pep” Buquet <pep@bouah.net>
parents:
diff changeset
    57
module:hook("muc-occupant-groupchat", handle_stanza);