2023-08-02 13:42:09 +02:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% File : mod_muc_occupantid.erl
|
|
|
|
%%% Author : Badlop <badlop@process-one.net>
|
|
|
|
%%% Purpose : Add Occupant Ids to stanzas in anonymous MUC rooms (XEP-0421)
|
|
|
|
%%% Created :
|
|
|
|
%%%
|
|
|
|
%%%
|
2024-01-22 16:40:01 +01:00
|
|
|
%%% ejabberd, Copyright (C) 2002-2024 ProcessOne
|
2023-08-02 13:42:09 +02:00
|
|
|
%%%
|
|
|
|
%%% This program is free software; you can redistribute it and/or
|
|
|
|
%%% modify it under the terms of the GNU General Public License as
|
|
|
|
%%% published by the Free Software Foundation; either version 2 of the
|
|
|
|
%%% License, or (at your option) any later version.
|
|
|
|
%%%
|
|
|
|
%%% This program is distributed in the hope that it will be useful,
|
|
|
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
%%% General Public License for more details.
|
|
|
|
%%%
|
|
|
|
%%% You should have received a copy of the GNU General Public License along
|
|
|
|
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
%%%
|
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
-module(mod_muc_occupantid).
|
|
|
|
|
|
|
|
-author('badlop@process-one.net').
|
|
|
|
|
2023-10-02 10:54:24 +02:00
|
|
|
-protocol({xep, 421, '0.1.0', '23.10', "", ""}).
|
2023-08-02 13:42:09 +02:00
|
|
|
|
|
|
|
-behaviour(gen_mod).
|
|
|
|
|
|
|
|
-include_lib("xmpp/include/xmpp.hrl").
|
|
|
|
-include("logger.hrl").
|
|
|
|
-include("translate.hrl").
|
|
|
|
-include("mod_muc_room.hrl").
|
|
|
|
|
|
|
|
-export([start/2, stop/1,
|
|
|
|
mod_options/1, mod_doc/0, depends/2]).
|
2023-08-14 17:57:54 +02:00
|
|
|
-export([filter_packet/3, remove_room/3]).
|
2023-08-02 13:42:09 +02:00
|
|
|
|
|
|
|
%%%
|
|
|
|
%%% gen_mod
|
|
|
|
%%%
|
|
|
|
|
2023-08-09 16:08:45 +02:00
|
|
|
start(_Host, _Opts) ->
|
2023-08-14 17:57:54 +02:00
|
|
|
create_table(),
|
2023-08-09 16:08:45 +02:00
|
|
|
{ok, [{hook, muc_filter_presence, filter_packet, 10},
|
2023-08-14 17:57:54 +02:00
|
|
|
{hook, muc_filter_message, filter_packet, 10},
|
|
|
|
{hook, remove_room, remove_room, 50}]}.
|
2023-08-02 13:42:09 +02:00
|
|
|
|
2023-08-09 16:08:45 +02:00
|
|
|
stop(_Host) ->
|
2023-08-02 13:42:09 +02:00
|
|
|
ok.
|
|
|
|
|
|
|
|
%%%
|
|
|
|
%%% Hooks
|
|
|
|
%%%
|
|
|
|
|
|
|
|
filter_packet(Packet, State, _Nick) ->
|
2023-08-04 13:45:19 +02:00
|
|
|
add_occupantid_packet(Packet, State#state.jid).
|
2023-08-02 13:42:09 +02:00
|
|
|
|
2023-08-14 17:57:54 +02:00
|
|
|
remove_room(_LServer, Name, Host) ->
|
|
|
|
delete_salt(jid:make(Name, Host)).
|
|
|
|
|
2023-08-02 13:42:09 +02:00
|
|
|
%%%
|
|
|
|
%%% XEP-0421 Occupant-id
|
|
|
|
%%%
|
|
|
|
|
|
|
|
add_occupantid_packet(Packet, RoomJid) ->
|
|
|
|
From = xmpp:get_from(Packet),
|
|
|
|
OccupantId = calculate_occupantid(From, RoomJid),
|
|
|
|
OccupantElement = #occupant_id{id = OccupantId},
|
|
|
|
xmpp:set_subtag(Packet, OccupantElement).
|
|
|
|
|
|
|
|
calculate_occupantid(From, RoomJid) ->
|
2023-08-14 17:57:54 +02:00
|
|
|
Term = {jid:remove_resource(From), get_salt(RoomJid)},
|
2023-08-02 13:42:09 +02:00
|
|
|
misc:term_to_base64(crypto:hash(sha256, io_lib:format("~p", [Term]))).
|
|
|
|
|
2023-08-14 17:57:54 +02:00
|
|
|
%%%
|
|
|
|
%%% Table storing rooms' salt
|
|
|
|
%%%
|
|
|
|
|
|
|
|
-record(muc_occupant_id, {room_jid, salt}).
|
|
|
|
|
|
|
|
create_table() ->
|
|
|
|
ejabberd_mnesia:create(?MODULE, muc_occupant_id,
|
|
|
|
[{ram_copies, [node()]},
|
|
|
|
{local_content, true},
|
|
|
|
{attributes, record_info(fields, muc_occupant_id)},
|
|
|
|
{type, set}]).
|
|
|
|
|
|
|
|
|
|
|
|
get_salt(RoomJid) ->
|
|
|
|
case mnesia:dirty_read(muc_occupant_id, RoomJid) of
|
|
|
|
[] ->
|
|
|
|
Salt = p1_rand:get_string(),
|
|
|
|
ok = write_salt(RoomJid, Salt),
|
|
|
|
Salt;
|
|
|
|
[#muc_occupant_id{salt = Salt}] ->
|
|
|
|
Salt
|
|
|
|
end.
|
|
|
|
|
|
|
|
write_salt(RoomJid, Salt) ->
|
|
|
|
mnesia:dirty_write(#muc_occupant_id{room_jid = RoomJid, salt = Salt}).
|
|
|
|
|
|
|
|
delete_salt(RoomJid) ->
|
|
|
|
mnesia:dirty_delete(muc_occupant_id, RoomJid).
|
|
|
|
|
2023-08-02 13:42:09 +02:00
|
|
|
%%%
|
|
|
|
%%% Doc
|
|
|
|
%%%
|
|
|
|
|
|
|
|
mod_options(_Host) ->
|
|
|
|
[].
|
|
|
|
|
|
|
|
mod_doc() ->
|
|
|
|
#{desc =>
|
|
|
|
[?T("This module implements "
|
|
|
|
"https://xmpp.org/extensions/xep-0421.html"
|
|
|
|
"[XEP-0421: Anonymous unique occupant identifiers for MUCs]."), "",
|
|
|
|
?T("When the module is enabled, the feature is enabled "
|
2024-03-28 03:24:28 +01:00
|
|
|
"in all semi-anonymous rooms.")],
|
|
|
|
note => "added in 23.10"
|
2023-08-02 13:42:09 +02:00
|
|
|
}.
|
|
|
|
|
|
|
|
depends(_, _) ->
|
|
|
|
[{mod_muc, hard}].
|