Skip to content

Commit

Permalink
Check the MUC domain in the hook handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
jacekwegr committed Jan 25, 2023
1 parent dda03c1 commit c61862c
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 18 deletions.
1 change: 1 addition & 0 deletions .circleci/template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ executors:
otp_25:
docker:
- image: *OTP25
resource_class: medium+
otp_24_redis:
docker:
- image: *OTP24
Expand Down
61 changes: 61 additions & 0 deletions big_tests/tests/graphql_muc_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
get_coercion_err_msg/1, user_to_bin/1, user_to_full_bin/1, user_to_jid/1,
get_unauthorized/1, get_not_loaded/1]).

-import(config_parser_helper, [mod_config/2]).

-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("exml/include/exml.hrl").
Expand Down Expand Up @@ -88,6 +90,7 @@ user_muc_tests() ->

user_muc_with_mam_tests() ->
[user_get_room_messages,
user_shouldnt_store_messages_in_muc_light,
user_try_get_nonexistent_room_messages,
user_try_get_room_messages_without_permission].

Expand Down Expand Up @@ -287,6 +290,26 @@ ensure_muc_stopped() ->
muc_helper:unload_muc(),
muc_helper:unload_muc(SecondaryHostType).

ensure_muc_light_started(Config) ->
MucLightOpts = mod_config(mod_muc_light, #{rooms_in_rosters => true,
config_schema => custom_schema()}),
HostType = domain_helper:host_type(),
dynamic_modules:ensure_modules(HostType, [{mod_muc_light, MucLightOpts}]),
[{muc_light_host, muc_light_helper:muc_host()} | Config].

ensure_muc_light_stopped(Config) ->
HostType = domain_helper:host_type(),
dynamic_modules:ensure_modules(HostType, [{mod_muc_light, stopped}]),
[{muc_light_host, <<"NON_EXISTING">>} | Config].

custom_schema() ->
%% Should be sorted
[{<<"background">>, <<>>, background, binary},
{<<"music">>, <<>>, music, binary},
%% Default fields
{<<"roomname">>, <<>>, roomname, binary},
{<<"subject">>, <<"Test">>, subject, binary}].

end_per_group(Group, _Config) when Group =:= user;
Group =:= admin_http;
Group =:= domain_admin_muc;
Expand All @@ -295,9 +318,15 @@ end_per_group(Group, _Config) when Group =:= user;
end_per_group(_Group, _Config) ->
escalus_fresh:clean().

init_per_testcase(user_shouldnt_store_messages_in_muc_light = TC, Config) ->
Config1 = ensure_muc_light_started(Config),
escalus:init_per_testcase(TC, Config1);
init_per_testcase(TC, Config) ->
escalus:init_per_testcase(TC, Config).

end_per_testcase(user_shouldnt_store_messages_in_muc_light = TC, Config) ->
Config1 = ensure_muc_light_stopped(Config),
escalus:end_per_testcase(TC, Config1);
end_per_testcase(TC, Config) ->
escalus:end_per_testcase(TC, Config).

Expand Down Expand Up @@ -1387,6 +1416,26 @@ user_get_room_messages_story(Config, Alice, Bob) ->
get_ok_value(?GET_MESSAGES_PATH, Res),
?assertMatch({ok, #xmlel{name = <<"message">>}}, exml:parse(StanzaXML)).

user_shouldnt_store_messages_in_muc_light(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}],
fun user_shouldnt_store_messages_in_muc_light_story/2).

user_shouldnt_store_messages_in_muc_light_story(Config, Alice) ->
%% Create a MUC Light room
MUCServer = ?config(muc_light_host, Config),
AliceBin = escalus_client:short_jid(Alice),
{ok, #{jid := RoomJID}} =
create_muc_light_room(MUCServer, <<"first room">>, <<"subject">>, AliceBin),
%% Send a message
Message = <<"Hello friends">>,
send_message_to_muc_light_room(RoomJID, jid:from_binary(AliceBin), Message),
escalus:wait_for_stanza(Alice),
%% Try to get a MUC Light message
Limit = 1,
Res = user_get_muc_light_room_messages(Alice, jid:to_binary(RoomJID), Limit, null, Config),
#{<<"stanzas">> := [], <<"limit">> := Limit} =
get_ok_value([data, muc_light, getRoomMessages], Res).

user_try_get_nonexistent_room_messages(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}],
fun user_try_get_nonexistent_room_messages_story/2).
Expand Down Expand Up @@ -1881,6 +1930,11 @@ get_room_name() ->

%% Commands

create_muc_light_room(Domain, Name, Subject, CreatorBin) ->
CreatorJID = jid:from_binary(CreatorBin),
Config = #{<<"roomname">> => Name, <<"subject">> => Subject},
rpc(mim(), mod_muc_light_api, create_room, [Domain, CreatorJID, Config]).

create_instant_room(Room, Owner, Nick, Config) ->
Vars = #{room => room_to_bin(Room), owner => user_to_bin(Owner), nick => Nick},
execute_command(<<"muc">>, <<"createInstantRoom">>, Vars, Config).
Expand All @@ -1903,6 +1957,9 @@ send_private_message(Room, From, ToNick, Body, Config) ->
toNick => ToNick, body => Body},
execute_command(<<"muc">>, <<"sendPrivateMessage">>, Vars, Config).

send_message_to_muc_light_room(RoomJID, SenderJID, Message) ->
rpc(mim(), mod_muc_light_api, send_message, [RoomJID, SenderJID, Message]).

enter_room(Room, User, Nick, Password, Config) ->
Vars = #{room => jid:to_binary(Room), user => user_to_full_bin(User),
nick => Nick, password => Password},
Expand Down Expand Up @@ -1964,6 +2021,10 @@ user_get_room_messages(User, RoomJID, PageSize, Before, Config) ->
<<"before">> => Before},
execute_user_command(<<"muc">>, <<"getRoomMessages">>, User, Vars, Config).

user_get_muc_light_room_messages(User, RoomJID, PageSize, Before, Config) ->
Vars = #{<<"room">> => RoomJID, <<"pageSize">> => PageSize, <<"before">> => Before},
execute_user_command(<<"muc_light">>, <<"getRoomMessages">>, User, Vars, Config).

user_delete_room(User, Room, Reason, Config) ->
Vars = #{room => jid:to_binary(Room), reason => Reason},
execute_user_command(<<"muc">>, <<"deleteRoom">>, User, Vars, Config).
Expand Down
51 changes: 49 additions & 2 deletions big_tests/tests/graphql_muc_light_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ user_muc_light_tests() ->
].

user_muc_light_with_mam_tests() ->
[user_get_room_messages].
[user_get_room_messages,
user_shouldnt_store_messages_in_muc].

user_muc_light_not_configured_tests() ->
[user_create_room_muc_light_not_configured,
Expand Down Expand Up @@ -279,6 +280,13 @@ ensure_muc_light_stopped(Config) ->
dynamic_modules:ensure_modules(SecondaryHostType, [{mod_muc_light, stopped}]),
[{muc_light_host, <<"NON_EXISTING">>} | Config].

ensure_muc_started() ->
muc_helper:load_muc(),
mongoose_helper:ensure_muc_clean().

ensure_muc_stopped() ->
muc_helper:unload_muc().

end_per_group(Group, _Config) when Group =:= user;
Group =:= admin_http;
Group =:= admin_cli;
Expand All @@ -287,10 +295,16 @@ end_per_group(Group, _Config) when Group =:= user;
end_per_group(_Group, _Config) ->
escalus_fresh:clean().

init_per_testcase(user_shouldnt_store_messages_in_muc = TC, Config) ->
ensure_muc_started(),
rest_helper:maybe_skip_mam_test_cases(TC, [TC], Config);
init_per_testcase(TC, Config) ->
rest_helper:maybe_skip_mam_test_cases(TC, [user_get_room_messages,
admin_get_room_messages], Config).

end_per_testcase(user_shouldnt_store_messages_in_muc = TC, Config) ->
ensure_muc_stopped(),
escalus:end_per_testcase(TC, Config);
end_per_testcase(TC, Config) ->
escalus:end_per_testcase(TC, Config).

Expand Down Expand Up @@ -622,6 +636,24 @@ user_get_room_messages_story(Config, Alice, Bob) ->
Res5 = user_get_room_messages(Bob, jid:to_binary(RoomJID), Limit, null, Config),
?assertNotEqual(nomatch, binary:match(get_err_msg(Res5), <<"not occupy this room">>)).

user_shouldnt_store_messages_in_muc(Config) ->
muc_helper:story_with_room(Config, [], [{alice, 1}],
fun user_shouldnt_store_messages_in_muc_story/2).

user_shouldnt_store_messages_in_muc_story(Config, Alice) ->
%% Enter a MUC room
MUCRoomJID = jid:from_binary(?config(room_jid, Config)),
enter_muc_room(MUCRoomJID, Alice, <<"Ali">>),
escalus:wait_for_stanza(Alice),
%% Send a message
Message = <<"Hello friends">>,
send_message_to_muc_room(Alice, MUCRoomJID, Message, null, Config),
escalus:wait_for_stanza(Alice),
%% Try to get a MUC message
Limit = 1,
Res3 = user_get_muc_room_messages(Alice, jid:to_binary(MUCRoomJID), Limit, null, Config),
#{<<"stanzas">> := [], <<"limit">> := Limit} = get_ok_value([data, muc, getRoomMessages], Res3).

user_list_rooms(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_list_rooms_story/2).

Expand Down Expand Up @@ -1441,7 +1473,7 @@ admin_get_room_config_story(Config, Alice) ->
MUCServer = ?config(muc_light_host, Config),
RoomName = <<"first room">>,
RoomSubject = <<"Room about nothing">>,
{ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
{ok, #{jid := #jid{luser = _RoomID} = RoomJID}} =
create_room(MUCServer, RoomName, RoomSubject, AliceBin),
RoomJIDBin = jid:to_binary(RoomJID),
Res = get_room_config(RoomJIDBin, Config),
Expand Down Expand Up @@ -1825,3 +1857,18 @@ user_get_blocking(User, Config) ->
user_set_blocking(User, Items, Config) ->
Vars = #{<<"items">> => prepare_blocking_items_for_query(Items)},
execute_user_command(<<"muc_light">>, <<"setBlockingList">>, User, Vars, Config).

user_get_muc_room_messages(User, RoomJID, PageSize, Before, Config) ->
Vars = #{<<"room">> => jid:to_binary(RoomJID), <<"pageSize">> => PageSize,
<<"before">> => Before},
execute_user_command(<<"muc">>, <<"getRoomMessages">>, User, Vars, Config).

send_message_to_muc_room(User, Room, Body, Resource, Config) ->
Vars = #{room => jid:to_binary(Room), body => Body, resource => Resource},
execute_user_command(<<"muc">>, <<"sendMessageToRoom">>, User, Vars, Config).

enter_muc_room(RoomJID, User, Nick) ->
JID = jid:to_binary(jid:replace_resource(RoomJID, Nick)),
Pres = escalus_stanza:to(escalus_stanza:presence(<<"available">>, []), JID),
escalus:send(User, Pres),
escalus:wait_for_stanza(User).
1 change: 1 addition & 0 deletions src/mam/mod_mam_muc_cassandra_arch.erl
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ archive_message2(#{message_id := MessID,
remote_jid := FromJID = #jid{},
source_jid := #jid{lresource = BNick},
packet := Packet}, HostType) ->
mod_mam_utils:check_muc_domain(LocJID#jid.lserver, HostType),
BLocJID = mod_mam_utils:bare_jid(LocJID),
BFromJID = mod_mam_utils:bare_jid(FromJID),
BPacket = packet_to_stored_binary(HostType, Packet),
Expand Down
35 changes: 20 additions & 15 deletions src/mam/mod_mam_muc_elasticsearch_arch.erl
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,26 @@ archive_message(_Result, Params, #{host_type := HostType}) ->
remote_jid := FromJID,
source_jid := SourceJid,
packet := Packet} = Params,
Room = mod_mam_utils:bare_jid(RoomJid),
SourceBinJid = mod_mam_utils:full_jid(SourceJid),
From = mod_mam_utils:bare_jid(FromJID),
DocId = make_document_id(Room, MessageId),
Doc = make_document(MessageId, Room, SourceBinJid, Packet, From),
case mongoose_elasticsearch:insert_document(?INDEX_NAME, ?TYPE_NAME, DocId, Doc) of
{ok, _} ->
{ok, ok};
{error, Reason} = Err ->
?LOG_ERROR(maps:merge(Params,
#{what => archive_muc_message_failed, reason => Reason,
server => HostType, room => Room, source => SourceBinJid,
message_id => MessageId})),
mongoose_metrics:update(HostType, modMamDropped, 1),
{ok, Err}
try
mod_mam_utils:check_muc_domain(RoomJid#jid.lserver, HostType),
Room = mod_mam_utils:bare_jid(RoomJid),
SourceBinJid = mod_mam_utils:full_jid(SourceJid),
From = mod_mam_utils:bare_jid(FromJID),
DocId = make_document_id(Room, MessageId),
Doc = make_document(MessageId, Room, SourceBinJid, Packet, From),
case mongoose_elasticsearch:insert_document(?INDEX_NAME, ?TYPE_NAME, DocId, Doc) of
{ok, _} ->
{ok, ok};
{error, Reason} = Err ->
?LOG_ERROR(maps:merge(Params,
#{what => archive_muc_message_failed, reason => Reason,
server => HostType, room => Room, source => SourceBinJid,
message_id => MessageId})),
mongoose_metrics:update(HostType, modMamDropped, 1),
{ok, Err}
end
catch _Type:ErrorReason ->
{ok, {error, ErrorReason}}
end.

-spec lookup_messages(Acc, Params, Extra) -> {ok, Acc} when
Expand Down
1 change: 1 addition & 0 deletions src/mam/mod_mam_muc_rdbms_arch.erl
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ extend_params_with_sender_id(HostType, Params = #{remote_jid := SenderJID}) ->
Extra :: gen_hook:extra().
archive_message(_Result, #{local_jid := ArcJID} = Params0, #{host_type := HostType}) ->
try
mod_mam_utils:check_muc_domain(ArcJID#jid.lserver, HostType),
Params = extend_params_with_sender_id(HostType, Params0),
Env = env_vars(HostType, ArcJID),
do_archive_message(HostType, Params, Env),
Expand Down
1 change: 1 addition & 0 deletions src/mam/mod_mam_riak_timed_arch_yz.erl
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ archive_message_muc(_Result,
#{host_type := HostType}) ->
RemJIDMuc = maybe_muc_jid(SrcJID),
try
mod_mam_utils:check_muc_domain(LocJID#jid.lserver, HostType),
{ok, archive_message(HostType, MessId, LocJID, RemJIDMuc, SrcJID, FromJID, Packet, muc)}
catch Class:Reason:StackTrace ->
?LOG_WARNING(maps:merge(Params,
Expand Down
10 changes: 9 additions & 1 deletion src/mam/mod_mam_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
calculate_msg_id_borders/4,
maybe_encode_compact_uuid/2,
wait_shaper/4,
check_for_item_not_found/3]).
check_for_item_not_found/3,
check_muc_domain/2]).

%% Ejabberd
-export([send_message/4,
Expand Down Expand Up @@ -1246,3 +1247,10 @@ is_removing_done({updated, N}, Limit) when N < Limit ->
{done, N};
is_removing_done({updated, N}, _)->
{remove_more, N}.

check_muc_domain(MucDomain, HostType) ->
{ok, {prefix, MamHost}} = mongoose_config:lookup_opt([{modules, HostType}, mod_mam_muc, host]),
case string:find(MucDomain, MamHost) of
nomatch -> throw(incorrect_muc_domain);
_ -> ok
end.

0 comments on commit c61862c

Please sign in to comment.