Skip to content

Commit

Permalink
Add remove_domain handler for MAM
Browse files Browse the repository at this point in the history
  • Loading branch information
arcusfelis committed Apr 22, 2021
1 parent 8cfa47c commit 41d460c
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 2 deletions.
1 change: 1 addition & 0 deletions big_tests/default.spec
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
{suites, "tests", websockets_SUITE}.
{suites, "tests", xep_0352_csi_SUITE}.
{suites, "tests", domain_isolation_SUITE}.
{suites, "tests", domain_removal_SUITE}.

{config, ["test.config"]}.
{logdir, "ct_report"}.
Expand Down
127 changes: 127 additions & 0 deletions big_tests/tests/domain_removal_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
-module(domain_removal_SUITE).

%% API
-export([all/0,
groups/0,
init_per_suite/1,
end_per_suite/1,
init_per_group/2,
end_per_group/2,
init_per_testcase/2,
end_per_testcase/2]).

-export([mam_pm_removal/1,
mam_muc_removal/1]).

-import(mam_helper,
[stanza_archive_request/2,
wait_archive_respond/1,
assert_respond_size/2,
respond_messages/1,
parse_forwarded_message/1]).

-import(distributed_helper, [mim/0,
require_rpc_nodes/1,
rpc/4]).

-include("mam_helper.hrl").
-include_lib("escalus/include/escalus.hrl").
-include_lib("escalus/include/escalus_xmlns.hrl").
-include_lib("common_test/include/ct.hrl").
-include_lib("exml/include/exml_stream.hrl").

all() ->
[{group, mam_removal}].

groups() ->
[
{mam_removal, [], [mam_pm_removal,
mam_muc_removal]}
].

domain() ->
ct:get_config({hosts, mim, domain}).

%%%===================================================================
%%% Overall setup/teardown
%%%===================================================================
init_per_suite(Config) ->
escalus:init_per_suite(Config).

end_per_suite(Config) ->
escalus:end_per_suite(Config).

%%%===================================================================
%%% Group specific setup/teardown
%%%===================================================================
init_per_group(Group, Config) ->
case mongoose_helper:is_rdbms_enabled(domain()) of
true ->
Config2 = dynamic_modules:save_modules(domain(), Config),
rpc(mim(), gen_mod_deps, start_modules, [domain(), group_to_modules(Group)]),
Config2;
false ->
{skip, require_rdbms}
end.

end_per_group(_Groupname, Config) ->
case mongoose_helper:is_rdbms_enabled(domain()) of
true ->
dynamic_modules:restore_modules(domain(), Config);
false ->
ok
end,
ok.

group_to_modules(mam_removal) ->
MH = muc_light_helper:muc_host(),
[{mod_mam_meta, [{backend, rdbms}, {pm, []}, {muc, [{host, MH}]}]},
{mod_muc_light, []}].

%%%===================================================================
%%% Testcase specific setup/teardown
%%%===================================================================

init_per_testcase(TestCase, Config) ->
escalus:init_per_testcase(TestCase, Config).

end_per_testcase(TestCase, Config) ->
escalus:end_per_testcase(TestCase, Config).

%%%===================================================================
%%% Test Cases
%%%===================================================================

mam_pm_removal(Config) ->
P = ?config(props, Config),
F = fun(Alice, Bob) ->
escalus:send(Alice, escalus_stanza:chat_to(Bob, <<"OH, HAI!">>)),
escalus:wait_for_stanza(Bob),
mam_helper:wait_for_archive_size(Alice, 1),
mam_helper:wait_for_archive_size(Bob, 1),
run_remove_domain(),
mam_helper:wait_for_archive_size(Alice, 0),
mam_helper:wait_for_archive_size(Bob, 0)
end,
escalus_fresh:story(Config, [{alice, 1}, {bob, 1}], F).

mam_muc_removal(Config0) ->
F = fun(Config, Alice) ->
Room = muc_helper:fresh_room_name(),
MucHost = muc_light_helper:muc_host(),
muc_light_helper:create_room(Room, MucHost, alice,
[alice], Config, muc_light_helper:ver(1)),
RoomAddr = <<Room/binary, "@", MucHost/binary>>,
escalus:send(Alice, escalus_stanza:groupchat_to(RoomAddr, <<"text">>)),
escalus:wait_for_stanza(Alice),
mam_helper:wait_for_room_archive_size(MucHost, Room, 1),
run_remove_domain(),
mam_helper:wait_for_room_archive_size(MucHost, Room, 0),
ok
end,
escalus_fresh:story_with_config(Config0, [{alice, 1}], F).

run_remove_domain() ->
Acc = #{},
rpc(mim(), ejabberd_hooks, run_fold,
[remove_domain, domain(), Acc, [domain(), domain()]]).
1 change: 1 addition & 0 deletions priv/mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ CREATE TABLE mam_config(
) CHARACTER SET utf8mb4
ROW_FORMAT=DYNAMIC;

-- The server field is a MUC host for MUC rooms
CREATE TABLE mam_server_user(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
server varchar(250) CHARACTER SET binary NOT NULL,
Expand Down
29 changes: 28 additions & 1 deletion src/mam/mod_mam_muc_rdbms_arch.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
-export([archive_size/4,
archive_message/3,
lookup_messages/3,
remove_archive/4]).
remove_archive/4,
remove_domain/3]).

-export([get_mam_muc_gdpr_data/2]).

Expand Down Expand Up @@ -86,6 +87,7 @@ start_hooks(Host, _Opts) ->
ejabberd_hooks:add(mam_muc_archive_size, Host, ?MODULE, archive_size, 50),
ejabberd_hooks:add(mam_muc_lookup_messages, Host, ?MODULE, lookup_messages, 50),
ejabberd_hooks:add(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 50),
ejabberd_hooks:add(remove_domain, Host, ?MODULE, remove_domain, 50),
ejabberd_hooks:add(get_mam_muc_gdpr_data, Host, ?MODULE, get_mam_muc_gdpr_data, 50),
ok.

Expand All @@ -101,6 +103,7 @@ stop_hooks(Host) ->
ejabberd_hooks:delete(mam_muc_archive_size, Host, ?MODULE, archive_size, 50),
ejabberd_hooks:delete(mam_muc_lookup_messages, Host, ?MODULE, lookup_messages, 50),
ejabberd_hooks:delete(mam_muc_remove_archive, Host, ?MODULE, remove_archive, 50),
ejabberd_hooks:delete(remove_domain, Host, ?MODULE, remove_domain, 50),
ejabberd_hooks:delete(get_mam_muc_gdpr_data, Host, ?MODULE, get_mam_muc_gdpr_data, 50),
ok.

Expand All @@ -112,6 +115,11 @@ register_prepared_queries() ->
mongoose_rdbms:prepare(mam_muc_archive_remove, mam_muc_message, [room_id],
<<"DELETE FROM mam_muc_message "
"WHERE room_id = ?">>),
mongoose_rdbms:prepare(mam_muc_remove_domain, mam_muc_message, ['mam_server_user.server'],
<<"DELETE FROM mam_muc_message "
"WHERE room_id IN (SELECT id FROM mam_server_user where server = ?)">>),
mongoose_rdbms:prepare(mam_muc_remove_domain_users, mam_muc_message, [server],
<<"DELETE FROM mam_server_user WHERE server = ?">>),
mongoose_rdbms:prepare(mam_muc_make_tombstone, mam_muc_message, [message, room_id, id],
<<"UPDATE mam_muc_message SET message = ?, search_body = '' "
"WHERE room_id = ? AND id = ?">>),
Expand Down Expand Up @@ -290,6 +298,25 @@ remove_archive(Acc, Host, ArcID, _ArcJID) ->
mongoose_rdbms:execute_successfully(Host, mam_muc_archive_remove, [ArcID]),
Acc.

-spec remove_domain(mongoose_acc:t(), binary(), jid:lserver()) -> mongoose_acc:t().
remove_domain(Acc, HostType, Domain) ->
SubHosts = get_subhosts(Domain),
{atomic, _} = mongoose_rdbms:sql_transaction(HostType, fun() ->
[remove_domain_trans(HostType, SubHost) || SubHost <- SubHosts]
end),
Acc.

remove_domain_trans(HostType, MucHost) ->
mongoose_rdbms:execute_successfully(HostType, mam_muc_remove_domain, [MucHost]),
mongoose_rdbms:execute_successfully(HostType, mam_muc_remove_domain_users, [MucHost]).

get_subhosts(Domain) ->
MucHost = gen_mod:get_module_opt_subhost(Domain, mod_muc_light,
mod_muc_light:default_host()),
LightHost = gen_mod:get_module_opt_subhost(Domain, mod_muc,
mod_muc:default_host()),
lists:usort([MucHost, LightHost]).

%% GDPR logic
extract_gdpr_messages(Host, SenderID) ->
mongoose_rdbms:execute_successfully(Host, mam_muc_extract_gdpr_messages, [SenderID]).
Expand Down
19 changes: 18 additions & 1 deletion src/mam/mod_mam_rdbms_arch.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
-export([archive_size/4,
archive_message/3,
lookup_messages/3,
remove_archive/4]).
remove_archive/4,
remove_domain/3]).

-export([get_mam_pm_gdpr_data/2]).

Expand Down Expand Up @@ -102,6 +103,7 @@ start_hooks(Host, _Opts) ->
ejabberd_hooks:add(mam_archive_size, Host, ?MODULE, archive_size, 50),
ejabberd_hooks:add(mam_lookup_messages, Host, ?MODULE, lookup_messages, 50),
ejabberd_hooks:add(mam_remove_archive, Host, ?MODULE, remove_archive, 50),
ejabberd_hooks:add(remove_domain, Host, ?MODULE, remove_domain, 50),
ejabberd_hooks:add(get_mam_pm_gdpr_data, Host, ?MODULE, get_mam_pm_gdpr_data, 50),
ok.

Expand All @@ -117,6 +119,7 @@ stop_hooks(Host) ->
ejabberd_hooks:delete(mam_archive_size, Host, ?MODULE, archive_size, 50),
ejabberd_hooks:delete(mam_lookup_messages, Host, ?MODULE, lookup_messages, 50),
ejabberd_hooks:delete(mam_remove_archive, Host, ?MODULE, remove_archive, 50),
ejabberd_hooks:delete(remove_domain, Host, ?MODULE, remove_domain, 50),
ejabberd_hooks:delete(get_mam_pm_gdpr_data, Host, ?MODULE, get_mam_pm_gdpr_data, 50),
ok.

Expand All @@ -128,6 +131,12 @@ register_prepared_queries() ->
mongoose_rdbms:prepare(mam_archive_remove, mam_message, [user_id],
<<"DELETE FROM mam_message "
"WHERE user_id = ?">>),
mongoose_rdbms:prepare(mam_remove_domain, mam_message, ['mam_server_user.server'],
<<"DELETE FROM mam_message "
"WHERE user_id IN "
"(SELECT id from mam_server_user WHERE server = ?)">>),
mongoose_rdbms:prepare(mam_remove_domain_users, mam_server_user, [server],
<<"DELETE FROM mam_server_user WHERE server = ?">>),
mongoose_rdbms:prepare(mam_make_tombstone, mam_message, [message, user_id, id],
<<"UPDATE mam_message SET message = ?, search_body = '' "
"WHERE user_id = ? AND id = ?">>),
Expand Down Expand Up @@ -314,6 +323,14 @@ remove_archive(Acc, Host, ArcID, _ArcJID) ->
mongoose_rdbms:execute_successfully(Host, mam_archive_remove, [ArcID]),
Acc.

-spec remove_domain(mongoose_acc:t(), binary(), jid:lserver()) -> mongoose_acc:t().
remove_domain(Acc, HostType, Domain) ->
{atomic, _} = mongoose_rdbms:sql_transaction(HostType, fun() ->
mongoose_rdbms:execute_successfully(HostType, mam_remove_domain, [Domain]),
mongoose_rdbms:execute_successfully(HostType, mam_remove_domain_users, [Domain])
end),
Acc.

%% GDPR logic
extract_gdpr_messages(Env, ArcID) ->
Filters = [{equal, user_id, ArcID}],
Expand Down

0 comments on commit 41d460c

Please sign in to comment.