From 93283e12f968c16fc1f4e974e463990c37bf718f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Thu, 9 Sep 2021 13:52:05 +0200 Subject: [PATCH 1/5] Add support for dynamic domains in mod_adhoc --- src/mod_adhoc.erl | 147 ++++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 65 deletions(-) diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index cad139191c8..3a9256ab3ca 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -31,11 +31,15 @@ -type command_hook_acc() :: {error, exml:element()} | exml:element() | ignore | empty. -export_type([command_hook_acc/0]). +%% Gen_mod callbacks -export([start/2, stop/1, config_spec/0, - process_local_iq/4, - process_sm_iq/4, + supported_features/0]). + +%% IQ and hook handlers +-export([process_local_iq/5, + process_sm_iq/5, disco_local_items/1, disco_local_identity/1, disco_local_features/1, @@ -46,36 +50,41 @@ -ignore_xref([disco_local_features/1, disco_local_identity/1, disco_local_items/1, disco_sm_features/1, disco_sm_identity/1, disco_sm_items/1, - ping_command/4, process_local_iq/4, process_sm_iq/4]). + ping_command/4, process_local_iq/5, process_sm_iq/5]). -include("mongoose.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). -include("mongoose_config_spec.hrl"). -start(Host, Opts) -> +start(HostType, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS, - ?MODULE, process_local_iq, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS, - ?MODULE, process_sm_iq, IQDisc), - ejabberd_hooks:add(hooks(Host)). + [gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_COMMANDS, Component, Fn, #{}, IQDisc) || + {Component, Fn} <- iq_handlers()], + ejabberd_hooks:add(hooks(HostType)). + +stop(HostType) -> + ejabberd_hooks:delete(hooks(HostType)), + [gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_COMMANDS, Component) || + {Component, _Fn} <- iq_handlers()]. -stop(Host) -> - ejabberd_hooks:delete(hooks(Host)), +iq_handlers() -> + [{ejabberd_local, fun ?MODULE:process_local_iq/5}, + {ejabberd_sm, fun ?MODULE:process_sm_iq/5}]. - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS), - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS). +hooks(HostType) -> + [{disco_local_identity, HostType, ?MODULE, disco_local_identity, 99}, + {disco_local_features, HostType, ?MODULE, disco_local_features, 99}, + {disco_local_items, HostType, ?MODULE, disco_local_items, 99}, + {disco_sm_identity, HostType, ?MODULE, disco_sm_identity, 99}, + {disco_sm_features, HostType, ?MODULE, disco_sm_features, 99}, + {disco_sm_items, HostType, ?MODULE, disco_sm_items, 99}, + {adhoc_local_commands, HostType, ?MODULE, ping_command, 100}]. -hooks(Host) -> - [{disco_local_identity, Host, ?MODULE, disco_local_identity, 99}, - {disco_local_features, Host, ?MODULE, disco_local_features, 99}, - {disco_local_items, Host, ?MODULE, disco_local_items, 99}, - {disco_sm_identity, Host, ?MODULE, disco_sm_identity, 99}, - {disco_sm_features, Host, ?MODULE, disco_sm_features, 99}, - {disco_sm_items, Host, ?MODULE, disco_sm_items, 99}, - {adhoc_local_commands, Host, ?MODULE, ping_command, 100}]. +%%% +%%% config_spec +%%% -spec config_spec() -> mongoose_config_spec:config_section(). config_spec() -> @@ -84,11 +93,56 @@ config_spec() -> <<"iqdisc">> => mongoose_config_spec:iqdisc()} }. -%%------------------------------------------------------------------------- +-spec supported_features() -> [atom()]. +supported_features() -> [dynamic_domains]. + +%%% +%%% IQ handlers +%%% + +-spec process_local_iq(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), map()) + -> {mongoose_acc:t(), ignore | jlib:iq()}. +process_local_iq(Acc, From, To, IQ, _Extra) -> + {Acc, process_adhoc_request(Acc, From, To, IQ, adhoc_local_commands)}. + +-spec process_sm_iq(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), map()) -> + {mongoose_acc:t(), ignore | jlib:iq()}. +process_sm_iq(Acc, From, To, IQ, _Extra) -> + {Acc, process_adhoc_request(Acc, From, To, IQ, adhoc_sm_commands)}. + +-spec process_adhoc_request(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), + Hook :: atom()) -> ignore | jlib:iq(). +process_adhoc_request(Acc, From, To, #iq{sub_el = SubEl} = IQ, Hook) -> + ?LOG_DEBUG(#{what => adhoc_parse_request, iq => IQ, hook => Hook}), + case adhoc:parse_request(IQ) of + {error, Error} -> + IQ#iq{type = error, sub_el = [SubEl, Error]}; + #adhoc_request{} = AdhocRequest -> + HostType = mongoose_acc:host_type(Acc), + case run_request_hook(Hook, HostType, From, To, AdhocRequest) of + ignore -> + ignore; + empty -> + IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:item_not_found()]}; + {error, Error} -> + IQ#iq{type = error, sub_el = [SubEl, Error]}; + Command -> + IQ#iq{type = result, sub_el = [Command]} + end + end. + +run_request_hook(adhoc_local_commands, HostType, From, To, AdhocRequest) -> + mongoose_hooks:adhoc_local_commands(HostType, From, To, AdhocRequest); +run_request_hook(adhoc_sm_commands, HostType, From, To, AdhocRequest) -> + mongoose_hooks:adhoc_sm_commands(HostType, From, To, AdhocRequest). + +%%% +%%% Hooks handlers +%%% -spec disco_local_items(mongoose_disco:item_acc()) -> mongoose_disco:item_acc(). -disco_local_items(Acc = #{to_jid := #jid{lserver = LServer}, node := <<>>, lang := Lang}) -> - Items = case are_commands_visible(LServer) of +disco_local_items(Acc = #{host_type := HostType, to_jid := #jid{lserver = LServer}, node := <<>>, lang := Lang}) -> + Items = case are_commands_visible(HostType) of false -> []; _ -> @@ -106,8 +160,8 @@ disco_local_items(Acc) -> %%------------------------------------------------------------------------- -spec disco_sm_items(mongoose_disco:item_acc()) -> mongoose_disco:item_acc(). -disco_sm_items(Acc = #{to_jid := #jid{lserver = LServer} = To, node := <<>>, lang := Lang}) -> - Items = case are_commands_visible(LServer) of +disco_sm_items(Acc = #{host_type := HostType, to_jid := To, node := <<>>, lang := Lang}) -> + Items = case are_commands_visible(HostType) of false -> []; _ -> @@ -117,8 +171,8 @@ disco_sm_items(Acc = #{to_jid := #jid{lserver = LServer} = To, node := <<>>, lan disco_sm_items(Acc) -> Acc. -are_commands_visible(LServer) -> - gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false). +are_commands_visible(HostType) -> + gen_mod:get_module_opt(HostType, ?MODULE, report_commands_node, false). item(LServer, Node, Name, Lang) -> #{jid => LServer, node => Node, name => translate:translate(Lang, Name)}. @@ -180,43 +234,6 @@ disco_sm_features(Acc) -> %%------------------------------------------------------------------------- --spec process_local_iq(jid:jid(), jid:jid(), mongoose_acc:t(), jlib:iq()) -> - {mongoose_acc:t(), ignore | jlib:iq()}. -process_local_iq(From, To, Acc, IQ) -> - {Acc, process_adhoc_request(From, To, IQ, adhoc_local_commands)}. - --spec process_sm_iq(jid:jid(), jid:jid(), mongoose_acc:t(), jlib:iq()) -> - {mongoose_acc:t(), ignore | jlib:iq()}. -process_sm_iq(From, To, Acc, IQ) -> - {Acc, process_adhoc_request(From, To, IQ, adhoc_sm_commands)}. - --spec process_adhoc_request(jid:jid(), jid:jid(), jlib:iq(), - Hook :: atom()) -> ignore | jlib:iq(). -process_adhoc_request(From, To, #iq{sub_el = SubEl} = IQ, Hook) -> - ?LOG_DEBUG(#{what => adhoc_parse_request, iq => IQ, hook => Hook}), - case adhoc:parse_request(IQ) of - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]}; - #adhoc_request{} = AdhocRequest -> - Host = To#jid.lserver, - case run_request_hook(Hook, Host, From, To, AdhocRequest) of - ignore -> - ignore; - empty -> - IQ#iq{type = error, sub_el = [SubEl, mongoose_xmpp_errors:item_not_found()]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]}; - Command -> - IQ#iq{type = result, sub_el = [Command]} - end - end. - -run_request_hook(adhoc_local_commands, Host, From, To, AdhocRequest) -> - mongoose_hooks:adhoc_local_commands(Host, From, To, AdhocRequest); -run_request_hook(adhoc_sm_commands, Host, From, To, AdhocRequest) -> - mongoose_hooks:adhoc_sm_commands(Host, From, To, AdhocRequest). - - -spec ping_command(Acc :: command_hook_acc(), From :: jid:jid(), To :: jid:jid(), From 872380722359c7d416f2ccb2eed7412056fd3661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Thu, 9 Sep 2021 13:52:57 +0200 Subject: [PATCH 2/5] Adapts adhoc hooks wrappers for dynamic domains --- src/mongoose_hooks.erl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mongoose_hooks.erl b/src/mongoose_hooks.erl index c4f5ac86f27..8584d406a4c 100644 --- a/src/mongoose_hooks.erl +++ b/src/mongoose_hooks.erl @@ -175,24 +175,24 @@ c2s_remote_hook(HostType, Tag, Args, HandlerState, C2SState) -> run_hook_for_host_type(c2s_remote_hook, HostType, HandlerState, [Tag, Args, C2SState]). --spec adhoc_local_commands(LServer, From, To, AdhocRequest) -> Result when - LServer :: jid:lserver(), +-spec adhoc_local_commands(HostType, From, To, AdhocRequest) -> Result when + HostType :: mongooseim:host_type(), From :: jid:jid(), To :: jid:jid(), AdhocRequest :: adhoc:request(), Result :: mod_adhoc:command_hook_acc(). -adhoc_local_commands(LServer, From, To, AdhocRequest) -> - run_hook_for_host_type(adhoc_local_commands, LServer, empty, +adhoc_local_commands(HostType, From, To, AdhocRequest) -> + run_hook_for_host_type(adhoc_local_commands, HostType, empty, [From, To, AdhocRequest]). --spec adhoc_sm_commands(LServer, From, To, AdhocRequest) -> Result when - LServer :: jid:lserver(), +-spec adhoc_sm_commands(HostType, From, To, AdhocRequest) -> Result when + HostType :: mongooseim:host_type(), From :: jid:jid(), To :: jid:jid(), AdhocRequest :: adhoc:request(), Result :: mod_adhoc:command_hook_acc(). -adhoc_sm_commands(LServer, From, To, AdhocRequest) -> - run_hook_for_host_type(adhoc_sm_commands, LServer, empty, [From, To, AdhocRequest]). +adhoc_sm_commands(HostType, From, To, AdhocRequest) -> + run_hook_for_host_type(adhoc_sm_commands, HostType, empty, [From, To, AdhocRequest]). %%% @doc The `anonymous_purge_hook' hook is called when anonymous user's data is removed. -spec anonymous_purge_hook(LServer, Acc, LUser) -> Result when From 2d81cec37fb48f066393ef2ef982b6960c5cef6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Thu, 9 Sep 2021 13:53:23 +0200 Subject: [PATCH 3/5] Enable mod_adhoc for dynamic domains --- rel/mim1.vars-toml.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rel/mim1.vars-toml.config b/rel/mim1.vars-toml.config index 980e4e78876..59173fd936d 100644 --- a/rel/mim1.vars-toml.config +++ b/rel/mim1.vars-toml.config @@ -23,6 +23,8 @@ [[host_config]] host_type = \"test type\" + [host_config.modules.mod_adhoc] + [host_config.modules.mod_bosh] [host_config.modules.mod_cache_users] From 3b6e763c74f339d1049eec789468883cb0485b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Thu, 9 Sep 2021 13:53:45 +0200 Subject: [PATCH 4/5] Adapts mod_adhoc tests for dynamic domains --- big_tests/tests/adhoc_SUITE.erl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/big_tests/tests/adhoc_SUITE.erl b/big_tests/tests/adhoc_SUITE.erl index dba7a7137f8..f65a84e9c55 100644 --- a/big_tests/tests/adhoc_SUITE.erl +++ b/big_tests/tests/adhoc_SUITE.erl @@ -20,19 +20,21 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). --define(NS_COMMANDS, <<"http://jabber.org/protocol/commands">>). +-import(domain_helper, [host_type/0]). %%-------------------------------------------------------------------- %% Suite configuration %%-------------------------------------------------------------------- + +-define(NS_COMMANDS, <<"http://jabber.org/protocol/commands">>). + all() -> [{group, disco_visible}, {group, adhoc}]. groups() -> - G = [{adhoc, [parallel], common_disco_cases() ++ hidden_disco_cases() ++ [ping]}, - {disco_visible, [parallel], common_disco_cases() ++ visible_disco_cases()}], - ct_helper:repeat_all_until_all_ok(G). + [{adhoc, [parallel], common_disco_cases() ++ hidden_disco_cases() ++ [ping]}, + {disco_visible, [parallel], common_disco_cases() ++ visible_disco_cases()}]. common_disco_cases() -> [disco_info, @@ -75,15 +77,15 @@ end_per_testcase(CaseName, Config) -> escalus:end_per_testcase(CaseName, Config). init_modules(disco_visible, Config) -> - Config1 = escalus:init_per_suite(dynamic_modules:save_modules(domain(), Config)), - dynamic_modules:ensure_modules(domain(), [{mod_adhoc, [{report_commands_node, true}]}]), + Config1 = escalus:init_per_suite(dynamic_modules:save_modules(host_type(), Config)), + dynamic_modules:ensure_modules(host_type(), [{mod_adhoc, [{report_commands_node, true}]}]), Config1; init_modules(_, Config) -> Config. restore_modules(disco_visible, Config) -> - dynamic_modules:restore_modules(domain(), Config); -restore_modules(_, Config) -> + dynamic_modules:restore_modules(host_type(), Config); +restore_modules(_, _Config) -> ok. %%-------------------------------------------------------------------- From 10473f51ee5536bfa10d217e99bf1b666a057328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Thu, 9 Sep 2021 13:54:06 +0200 Subject: [PATCH 5/5] Enable mod_adhoc tests for dynamic domains --- big_tests/dynamic_domains.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/big_tests/dynamic_domains.spec b/big_tests/dynamic_domains.spec index e07d2842176..4e7d5081aec 100644 --- a/big_tests/dynamic_domains.spec +++ b/big_tests/dynamic_domains.spec @@ -13,6 +13,8 @@ {suites, "tests", acc_e2e_SUITE}. +{suites, "tests", adhoc_SUITE}. + {suites, "tests", bosh_SUITE}. {suites, "tests", carboncopy_SUITE}.