From 3820ff1b954b01ae9d5c42c08480d4df7a0b24d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Tue, 7 Sep 2021 12:29:43 +0200 Subject: [PATCH 1/5] Add support for dynamic domains in mod_register --- big_tests/dynamic_domains.spec | 2 + big_tests/tests/accounts_SUITE.erl | 8 +- rel/mim1.vars-toml.config | 4 + src/mod_register.erl | 186 +++++++++++++++++------------ src/mongoose_hooks.erl | 2 +- 5 files changed, 122 insertions(+), 80 deletions(-) diff --git a/big_tests/dynamic_domains.spec b/big_tests/dynamic_domains.spec index e0916a26db..e5297bcca5 100644 --- a/big_tests/dynamic_domains.spec +++ b/big_tests/dynamic_domains.spec @@ -9,6 +9,8 @@ %% http://www.erlang.org/doc/apps/common_test/run_test_chapter.html#test_specifications {include, "tests"}. +{suites, "tests", accounts_SUITE}. + {suites, "tests", acc_e2e_SUITE}. {suites, "tests", carboncopy_SUITE}. diff --git a/big_tests/tests/accounts_SUITE.erl b/big_tests/tests/accounts_SUITE.erl index 6798b4dd0b..c555ac8644 100644 --- a/big_tests/tests/accounts_SUITE.erl +++ b/big_tests/tests/accounts_SUITE.erl @@ -66,8 +66,8 @@ change_password_tests() -> %%-------------------------------------------------------------------- init_per_suite(Config1) -> - Host = ct:get_config({hosts, mim, domain}), - ok = dynamic_modules:ensure_modules(Host, required_modules()), + %Host = ct:get_config({hosts, mim, domain}), + ok = dynamic_modules:ensure_modules(host_type(), required_modules()), Config2 = [{mod_register_options, mod_register_options()} | Config1], escalus:init_per_suite([{escalus_user_db, xmpp} | Config2]). @@ -461,5 +461,9 @@ enable_watcher(Config, Watcher) -> disable_watcher(Config) -> restore_mod_register_options(Config). +host_type() -> + <<"test type">>. + %domain_helper:host_type(mim). + domain() -> ct:get_config({hosts, mim, domain}). diff --git a/rel/mim1.vars-toml.config b/rel/mim1.vars-toml.config index 1310cd335a..5e295787bf 100644 --- a/rel/mim1.vars-toml.config +++ b/rel/mim1.vars-toml.config @@ -35,6 +35,10 @@ [host_config.modules.mod_disco] + {{#mod_register}} + [host_config.modules.mod_register] + {{{mod_register}}} + {{/mod_register}} {{#mod_last}} [host_config.modules.mod_last] {{{mod_last}}} diff --git a/src/mod_register.erl b/src/mod_register.erl index 9f75995798..6c17c8e225 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -29,32 +29,36 @@ -behaviour(gen_mod). -behaviour(mongoose_module_metrics). +%% Gen_mod callbacks -export([start/2, stop/1, config_spec/0, - c2s_stream_features/3, - unauthenticated_iq_register/4, - try_register/5, - process_iq/4, + supported_features/0]). + +%% IQ and hook handlers +-export([c2s_stream_features/3, + unauthenticated_iq_register/5, + process_iq/5]). + +%% API +-export([try_register/6, process_ip_access/1, process_welcome_message/1]). --ignore_xref([c2s_stream_features/3, process_iq/4, try_register/5, unauthenticated_iq_register/4]). +-ignore_xref([c2s_stream_features/3, process_iq/5, try_register/6, unauthenticated_iq_register/4]). -include("mongoose.hrl"). -include("jlib.hrl"). -include("mongoose_config_spec.hrl"). -start(Host, Opts) -> +-spec start(mongooseim:host_type(), list()) -> ok. +start(HostType, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER, - ?MODULE, process_iq, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_REGISTER, - ?MODULE, process_iq, IQDisc), - ejabberd_hooks:add(c2s_stream_features, Host, - ?MODULE, c2s_stream_features, 50), - ejabberd_hooks:add(c2s_unauthenticated_iq, Host, - ?MODULE, unauthenticated_iq_register, 50), + + [gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_REGISTER, Component, Fn, #{}, IQDisc) || + {Component, Fn} <- iq_handlers()], + ejabberd_hooks:add(hooks(HostType)), + mnesia:create_table(mod_register_ip, [{ram_copies, [node()]}, {local_content, true}, @@ -62,13 +66,24 @@ start(Host, Opts) -> mnesia:add_table_copy(mod_register_ip, node(), ram_copies), ok. -stop(Host) -> - ejabberd_hooks:delete(c2s_stream_features, Host, - ?MODULE, c2s_stream_features, 50), - ejabberd_hooks:delete(c2s_unauthenticated_iq, Host, - ?MODULE, unauthenticated_iq_register, 50), - gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_REGISTER), - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_REGISTER). +-spec stop(mongooseim:host_type()) -> ok. +stop(HostType) -> + ejabberd_hooks:delete(hooks(HostType)), + [gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_REGISTER, Component) || + {Component, _Fn} <- iq_handlers()], + ok. + +iq_handlers() -> + [{ejabberd_local, fun ?MODULE:process_iq/5}, {ejabberd_sm, fun ?MODULE:process_iq/5}]. + +hooks(HostType) -> + %FIXME handle host_type in hooks + [{c2s_stream_features, HostType, ?MODULE, c2s_stream_features, 50}, + {c2s_unauthenticated_iq, HostType, ?MODULE, unauthenticated_iq_register, 50}]. + +%%% +%%% config_spec +%%% -spec config_spec() -> mongoose_config_spec:config_section(). config_spec() -> @@ -103,6 +118,12 @@ ip_access_spec() -> process = fun ?MODULE:process_ip_access/1 }. +supported_features() -> [dynamic_domains]. + +%%% +%%% api +%%% + process_ip_access(KVs) -> {[[{address, Address}], [{policy, Policy}]], []} = proplists:split(KVs, [address, policy]), {Policy, Address}. @@ -118,13 +139,16 @@ c2s_stream_features(Acc, _HostType, _LServer) -> [#xmlel{name = <<"register">>, attrs = [{<<"xmlns">>, ?NS_FEATURE_IQREGISTER}]} | Acc]. -unauthenticated_iq_register(_Acc, - Server, #iq{xmlns = ?NS_REGISTER} = IQ, IP) -> +-spec unauthenticated_iq_register(empty, mongooseim:host_type(), jid:server(), jlib:iq(), + {inet:ip_address(), inet:port_number()} | undefined) -> + exml:element() | empty. +unauthenticated_iq_register(_Acc, HostType, Server, #iq{xmlns = ?NS_REGISTER} = IQ, IP) -> Address = case IP of {A, _Port} -> A; _ -> undefined end, - ResIQ = process_unauthenticated_iq(no_JID, + ResIQ = process_unauthenticated_iq(HostType, + no_JID, %% For the above: the client is %% not registered (no JID), at %% least not yet, so they can @@ -133,38 +157,43 @@ unauthenticated_iq_register(_Acc, IQ, Address), set_sender(jlib:iq_to_xml(ResIQ), make_host_only_jid(Server)); -unauthenticated_iq_register(Acc, _Server, _IQ, _IP) -> + +unauthenticated_iq_register(Acc, _HostType, _Server, _IQ, _IP) -> Acc. %% Clients must register before being able to authenticate. -process_unauthenticated_iq(From, To, #iq{type = set} = IQ, IPAddr) -> - process_iq_set(From, To, IQ, IPAddr); -process_unauthenticated_iq(From, To, #iq{type = get} = IQ, IPAddr) -> - process_iq_get(From, To, IQ, IPAddr). - -process_iq(From, To, Acc, #iq{type = set} = IQ) -> - Res = process_iq_set(From, To, IQ, jid:to_lower(From)), +process_unauthenticated_iq(HostType, From, To, #iq{type = set} = IQ, IPAddr) -> + process_iq_set(HostType, From, To, IQ, IPAddr); +process_unauthenticated_iq(HostType, From, To, #iq{type = get} = IQ, IPAddr) -> + process_iq_get(HostType, From, To, IQ, IPAddr). + +-spec process_iq(mongoose_acc:t(), jid:jid(), jid:jid(), jlib:iq(), map()) + -> {mongoose_acc:t(), jlib:iq()}. +process_iq(Acc, From, To, #iq{type = set} = IQ, _Extra) -> + HostType = mongoose_acc:host_type(Acc), + Res = process_iq_set(HostType, From, To, IQ, jid:to_lower(From)), {Acc, Res}; -process_iq(From, To, Acc, #iq{type = get} = IQ) -> - Res = process_iq_get(From, To, IQ, jid:to_lower(From)), +process_iq(Acc, From, To, #iq{type = get} = IQ, _Extra) -> + HostType = mongoose_acc:host_type(Acc), + Res = process_iq_get(HostType, From, To, IQ, jid:to_lower(From)), {Acc, Res}. -process_iq_set(From, To, #iq{sub_el = Child} = IQ, Source) -> +process_iq_set(HostType, From, To, #iq{sub_el = Child} = IQ, Source) -> true = is_query_element(Child), - handle_set(IQ, From, To, Source). + handle_set(HostType, IQ, From, To, Source). -handle_set(IQ, ClientJID, ServerJID, Source) -> +handle_set(HostType, IQ, ClientJID, ServerJID, Source) -> #iq{sub_el = Query} = IQ, case which_child_elements(Query) of bad_request -> error_response(IQ, mongoose_xmpp_errors:bad_request()); only_remove_child -> - attempt_cancelation(ClientJID, ServerJID, IQ); + attempt_cancelation(HostType, ClientJID, ServerJID, IQ); various_elements_present -> case has_username_and_password_children(Query) of true -> Credentials = get_username_and_password_values(Query), - register_or_change_password(Credentials, ClientJID, ServerJID, IQ, Source); + register_or_change_password(HostType, Credentials, ClientJID, ServerJID, IQ, Source); false -> error_response(IQ, mongoose_xmpp_errors:bad_request()) end @@ -196,20 +225,21 @@ get_username_and_password_values(Q) -> {exml_query:path(Q, [{element, <<"username">>}, cdata]), exml_query:path(Q, [{element, <<"password">>}, cdata])}. -register_or_change_password(Credentials, ClientJID, #jid{lserver = ServerDomain}, IQ, IPAddr) -> +register_or_change_password(HostType, Credentials, ClientJID, #jid{lserver = ServerDomain}, IQ, IPAddr) -> {Username, Password} = Credentials, - case inband_registration_and_cancelation_allowed(ServerDomain, ClientJID) of + case inband_registration_and_cancelation_allowed(HostType, ServerDomain, ClientJID) of true -> #iq{sub_el = Children, lang = Lang} = IQ, - try_register_or_set_password(Username, ServerDomain, Password, + try_register_or_set_password(HostType, Username, ServerDomain, Password, ClientJID, IQ, Children, IPAddr, Lang); false -> %% This is not described in XEP 0077. error_response(IQ, mongoose_xmpp_errors:forbidden()) end. -attempt_cancelation(#jid{} = ClientJID, #jid{lserver = ServerDomain}, #iq{} = IQ) -> - case inband_registration_and_cancelation_allowed(ServerDomain, ClientJID) of +attempt_cancelation(HostType, #jid{} = ClientJID, #jid{lserver = ServerDomain}, #iq{} = IQ) -> + %Is replacing server lserver with passed hostname ok? + case inband_registration_and_cancelation_allowed(HostType, ServerDomain, ClientJID) of true -> %% The response must be sent *before* the %% XML stream is closed (the call to @@ -228,13 +258,13 @@ attempt_cancelation(#jid{} = ClientJID, #jid{lserver = ServerDomain}, #iq{} = IQ error_response(IQ, mongoose_xmpp_errors:not_allowed()) end. -inband_registration_and_cancelation_allowed(_, no_JID) -> +inband_registration_and_cancelation_allowed(_HostType, _ServerDomain, no_JID) -> true; -inband_registration_and_cancelation_allowed(Server, JID) -> - Rule = gen_mod:get_module_opt(Server, ?MODULE, access, none), - allow =:= acl:match_rule(Server, Rule, JID). +inband_registration_and_cancelation_allowed(HostType, ServerDomain, JID) -> + Rule = gen_mod:get_module_opt(HostType, ?MODULE, access, none), + allow =:= acl:match_rule_for_host_type(HostType, ServerDomain, Rule, JID). -process_iq_get(From, _To, #iq{lang = Lang, sub_el = Child} = IQ, _Source) -> +process_iq_get(_HostType, From, _To, #iq{lang = Lang, sub_el = Child} = IQ, _Source) -> true = is_query_element(Child), {_IsRegistered, UsernameSubels, QuerySubels} = case From of @@ -261,13 +291,15 @@ process_iq_get(From, _To, #iq{lang = Lang, sub_el = Child} = IQ, _Source) -> #xmlel{name = <<"password">>} | QuerySubels]}]}. -try_register_or_set_password(User, Server, Password, #jid{user = User, lserver = Server} = UserJID, +try_register_or_set_password(HostType, User, Server, Password, #jid{user = User, lserver = Server} = UserJID, IQ, SubEl, _Source, Lang) -> - try_set_password(UserJID, Password, IQ, SubEl, Lang); -try_register_or_set_password(User, Server, Password, _From, IQ, SubEl, Source, Lang) -> + try_set_password(HostType, UserJID, Password, IQ, SubEl, Lang); +try_register_or_set_password(HostType, User, Server, Password, _From, IQ, SubEl, Source, Lang) -> + ?LOG_DEBUG(#{what => user_data_info, + host=> HostType, reason => #{user => User, server => Server, password => Password}}), case check_timeout(Source) of true -> - case try_register(User, Server, Password, Source, Lang) of + case try_register(HostType, User, Server, Password, Source, Lang) of ok -> IQ#iq{type = result, sub_el = [SubEl]}; {error, Error} -> @@ -279,8 +311,8 @@ try_register_or_set_password(User, Server, Password, _From, IQ, SubEl, Source, L end. %% @doc Try to change password and return IQ response -try_set_password(#jid{lserver = LServer} = UserJID, Password, IQ, SubEl, Lang) -> - case is_strong_password(LServer, Password) of +try_set_password(HostType, #jid{} = UserJID, Password, IQ, SubEl, Lang) -> + case is_strong_password(HostType, Password) of true -> case ejabberd_auth:set_password(UserJID, Password) of ok -> @@ -297,27 +329,27 @@ try_set_password(#jid{lserver = LServer} = UserJID, Password, IQ, SubEl, Lang) - error_response(IQ, [SubEl, mongoose_xmpp_errors:not_acceptable(Lang, ErrText)]) end. -try_register(User, Server, Password, SourceRaw, Lang) -> +try_register(HostType, User, Server, Password, SourceRaw, Lang) -> case jid:is_nodename(User) of false -> {error, mongoose_xmpp_errors:bad_request()}; _ -> JID = jid:make(User, Server, <<>>), - Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), - IPAccess = get_ip_access(Server), - case {acl:match_rule(Server, Access, JID), + Access = gen_mod:get_module_opt(HostType, ?MODULE, access, all), + IPAccess = get_ip_access(HostType), + case {acl:match_rule_for_host_type(HostType, Server, Access, JID), check_ip_access(SourceRaw, IPAccess)} of {deny, _} -> {error, mongoose_xmpp_errors:forbidden()}; {_, deny} -> {error, mongoose_xmpp_errors:forbidden()}; {allow, allow} -> - verify_password_and_register(JID, Password, SourceRaw, Lang) + verify_password_and_register(HostType, JID, Password, SourceRaw, Lang) end end. -verify_password_and_register(#jid{lserver = LServer} = JID, Password, SourceRaw, Lang) -> - case is_strong_password(LServer, Password) of +verify_password_and_register(HostType, #jid{} = JID, Password, SourceRaw, Lang) -> + case is_strong_password(HostType, Password) of true -> case ejabberd_auth:try_register(JID, Password) of {error, exists} -> @@ -329,8 +361,8 @@ verify_password_and_register(#jid{lserver = LServer} = JID, Password, SourceRaw, {error, null_password} -> {error, mongoose_xmpp_errors:not_acceptable()}; _ -> - send_welcome_message(JID), - send_registration_notifications(JID, SourceRaw), + send_welcome_message(HostType, JID), + send_registration_notifications(HostType, JID, SourceRaw), ok end; false -> @@ -338,13 +370,13 @@ verify_password_and_register(#jid{lserver = LServer} = JID, Password, SourceRaw, {error, mongoose_xmpp_errors:not_acceptable(Lang, ErrText)} end. -send_welcome_message(#jid{lserver = Host} = JID) -> - case gen_mod:get_module_opt(Host, ?MODULE, welcome_message, {"", ""}) of +send_welcome_message(HostType, #jid{lserver = Server} = JID) -> + case gen_mod:get_module_opt(HostType, ?MODULE, welcome_message, {"", ""}) of {"", ""} -> ok; {Subj, Body} -> ejabberd_router:route( - jid:make_noprep(<<>>, Host, <<>>), + jid:make_noprep(<<>>, Server, <<>>), JID, #xmlel{name = <<"message">>, attrs = [{<<"type">>, <<"normal">>}], children = [#xmlel{name = <<"subject">>, @@ -355,8 +387,8 @@ send_welcome_message(#jid{lserver = Host} = JID) -> ok end. -send_registration_notifications(#jid{lserver = Host} = UJID, Source) -> - case gen_mod:get_module_opt(Host, ?MODULE, registration_watchers, []) of +send_registration_notifications(HostType, #jid{lserver = Domain} = UJID, Source) -> + case gen_mod:get_module_opt(HostType, ?MODULE, registration_watchers, []) of [] -> ok; JIDs when is_list(JIDs) -> Body = lists:flatten( @@ -365,12 +397,12 @@ send_registration_notifications(#jid{lserver = Host} = UJID, Source) -> "on node ~w using ~p.", [get_time_string(), jid:to_binary(UJID), ip_to_string(Source), node(), ?MODULE])), - lists:foreach(fun(S) -> send_registration_notification(S, Host, Body) end, JIDs); + lists:foreach(fun(S) -> send_registration_notification(S, Domain, Body) end, JIDs); _ -> ok end. -send_registration_notification(JIDBin, Host, Body) -> +send_registration_notification(JIDBin, Domain, Body) -> case jid:from_binary(JIDBin) of error -> ok; JID -> @@ -378,7 +410,7 @@ send_registration_notification(JIDBin, Host, Body) -> attrs = [{<<"type">>, <<"chat">>}], children = [#xmlel{name = <<"body">>, children = [#xmlcdata{content = Body}]}]}, - ejabberd_router:route(jid:make_noprep(<<>>, Host, <<>>), JID, Message) + ejabberd_router:route(jid:make_noprep(<<>>, Domain, <<>>), JID, Message) end. check_timeout(undefined) -> @@ -446,15 +478,15 @@ write_time({{Y, Mo, D}, {H, Mi, S}}) -> io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Y, Mo, D, H, Mi, S]). -is_strong_password(LServer, Password) -> - case gen_mod:get_module_opt(LServer, ?MODULE, password_strength, 0) of +is_strong_password(HostType, Password) -> + case gen_mod:get_module_opt(HostType, ?MODULE, password_strength, 0) of Entropy when is_number(Entropy), Entropy == 0 -> true; Entropy when is_number(Entropy), Entropy > 0 -> ejabberd_auth:entropy(Password) >= Entropy; Wrong -> ?LOG_WARNING(#{what => reg_wrong_password_strength, - host => LServer, value => Wrong}), + host => HostType, value => Wrong}), true end. @@ -462,8 +494,8 @@ is_strong_password(LServer, Password) -> %%% ip_access management %%% -get_ip_access(Host) -> - IPAccess = gen_mod:get_module_opt(Host, ?MODULE, ip_access, []), +get_ip_access(HostType) -> + IPAccess = gen_mod:get_module_opt(HostType, ?MODULE, ip_access, []), lists:flatmap( fun({Access, {IP, Mask}}) -> [{Access, IP, Mask}]; diff --git a/src/mongoose_hooks.erl b/src/mongoose_hooks.erl index b3ae6d840c..599163570e 100644 --- a/src/mongoose_hooks.erl +++ b/src/mongoose_hooks.erl @@ -574,7 +574,7 @@ c2s_stream_features(HostType, LServer) -> IP :: {inet:ip_address(), inet:port_number()} | undefined, Result :: exml:element() | empty. c2s_unauthenticated_iq(HostType, Server, IQ, IP) -> - run_hook_for_host_type(c2s_unauthenticated_iq, HostType, empty, [Server, IQ, IP]). + run_hook_for_host_type(c2s_unauthenticated_iq, HostType, empty, [HostType, Server, IQ, IP]). -spec c2s_update_presence(HostType, Acc) -> Result when HostType :: mongooseim:host_type(), From d22fef3fb8fcfc6c8bb95bfbe6aec2cfa8fb225a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Tue, 7 Sep 2021 16:56:26 +0200 Subject: [PATCH 2/5] Fix tests for dynamic domains --- big_tests/tests/accounts_SUITE.erl | 22 ++++++++++------------ big_tests/tests/mongoose_helper.erl | 5 +++++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/big_tests/tests/accounts_SUITE.erl b/big_tests/tests/accounts_SUITE.erl index c555ac8644..8b17446de2 100644 --- a/big_tests/tests/accounts_SUITE.erl +++ b/big_tests/tests/accounts_SUITE.erl @@ -33,7 +33,7 @@ all() -> ]. groups() -> - G = [{register, [parallel], [register, + [{register, [parallel], [register, already_registered, registration_conflict, check_unregistered]}, @@ -52,8 +52,7 @@ groups() -> count_users, count_selected_users]}, {users_number_estimate, [], [count_users_estimate]} - ], - ct_helper:repeat_all_until_all_ok(G). + ]. suite() -> require_rpc_nodes([mim]) ++ escalus:suite(). @@ -91,7 +90,7 @@ init_per_group(change_account_details, Config) -> [{escalus_user_db, {module, escalus_ejabberd}} |Config]; init_per_group(change_account_details_store_plain, Config) -> Config1 = mongoose_helper:backup_auth_config(Config), - mongoose_helper:set_store_password(plain), + mongoose_helper:set_store_password(host_type(), plain), [{escalus_user_db, {module, escalus_ejabberd}} |Config1]; init_per_group(registration_timeout, Config) -> set_registration_timeout(Config); @@ -126,12 +125,12 @@ end_per_group(_GroupName, Config) -> Config. get_auth_opts() -> - rpc(mim(), ejabberd_config, get_local_option, [{auth_opts, domain()}]). + rpc(mim(), ejabberd_config, get_local_option, [{auth_opts, host_type()}]). set_auth_opts(AuthOpts) -> - rpc(mim(), ejabberd_auth, stop, [domain()]), - rpc(mim(), ejabberd_config, add_local_option, [{auth_opts, domain()}, AuthOpts]), - rpc(mim(), ejabberd_auth, start, [domain()]). + rpc(mim(), ejabberd_auth, stop, [host_type()]), + rpc(mim(), ejabberd_config, add_local_option, [{auth_opts, host_type()}, AuthOpts]), + rpc(mim(), ejabberd_auth, start, [host_type()]). init_per_testcase(admin_notify, Config) -> [{_, AdminSpec}] = escalus_users:get_users([admin]), @@ -445,13 +444,13 @@ user_exists(Name, Config) -> rpc(mim(), ejabberd_auth, does_user_exist, [mongoose_helper:make_jid(Username, Server)]). reload_mod_register_option(Config, Key, Value) -> - Host = domain(), + Host = host_type(), Args = proplists:get_value(mod_register_options, Config), Args1 = lists:keyreplace(Key, 1, Args, {Key, Value}), dynamic_modules:restart(Host, mod_register, Args1). restore_mod_register_options(Config) -> - Host = domain(), + Host = host_type(), Args = proplists:get_value(mod_register_options, Config), dynamic_modules:restart(Host, mod_register, Args). @@ -462,8 +461,7 @@ disable_watcher(Config) -> restore_mod_register_options(Config). host_type() -> - <<"test type">>. - %domain_helper:host_type(mim). + domain_helper:host_type(mim). domain() -> ct:get_config({hosts, mim, domain}). diff --git a/big_tests/tests/mongoose_helper.erl b/big_tests/tests/mongoose_helper.erl index 63a3af7daa..92b52ee424 100644 --- a/big_tests/tests/mongoose_helper.erl +++ b/big_tests/tests/mongoose_helper.erl @@ -41,6 +41,7 @@ -export([backup_sasl_mechanisms_config/1, restore_sasl_mechanisms_config/1]). -export([set_sasl_mechanisms/2]). -export([set_store_password/1]). +-export([set_store_password/2]). -export([get_listener_opts/2]). -export([restart_listener_with_opts/3]). -export([should_minio_be_running/1]). @@ -478,6 +479,10 @@ restore_sasl_mechanisms_config(Config) -> set_sasl_mechanisms(GlobalOrHostSASLMechanisms, Mechanisms) -> rpc(mim(), ejabberd_config, add_local_option, [GlobalOrHostSASLMechanisms, Mechanisms]). +set_store_password(HostType, Type) -> + AuthOpts = rpc(mim(), ejabberd_config, get_local_option, [{auth_opts, HostType}]), + NewAuthOpts = build_new_auth_opts(Type, AuthOpts), + rpc(mim(), ejabberd_config, add_local_option, [{auth_opts, HostType}, NewAuthOpts]). set_store_password(Type) -> XMPPDomain = escalus_ejabberd:unify_str_arg( From 89bc64d5e6c8f00f7153769094dea42968350559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Wed, 8 Sep 2021 09:30:17 +0200 Subject: [PATCH 3/5] Formatting --- src/mod_register.erl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/mod_register.erl b/src/mod_register.erl index 6c17c8e225..17958df070 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -45,7 +45,7 @@ process_ip_access/1, process_welcome_message/1]). --ignore_xref([c2s_stream_features/3, process_iq/5, try_register/6, unauthenticated_iq_register/4]). +-ignore_xref([c2s_stream_features/3, process_iq/5, try_register/6, unauthenticated_iq_register/5]). -include("mongoose.hrl"). -include("jlib.hrl"). @@ -120,10 +120,6 @@ ip_access_spec() -> supported_features() -> [dynamic_domains]. -%%% -%%% api -%%% - process_ip_access(KVs) -> {[[{address, Address}], [{policy, Policy}]], []} = proplists:split(KVs, [address, policy]), {Policy, Address}. @@ -133,6 +129,10 @@ process_welcome_message(KVs) -> Subject = proplists:get_value(subject, KVs, ""), {Subject, Body}. +%%% +%%% Hooks and IQ handlers +%%% + -spec c2s_stream_features([exml:element()], mongooseim:host_type(), jid:lserver()) -> [exml:element()]. c2s_stream_features(Acc, _HostType, _LServer) -> @@ -200,12 +200,12 @@ handle_set(HostType, IQ, ClientJID, ServerJID, Source) -> end. which_child_elements(#xmlel{children = C} = Q) when length(C) =:= 1 -> - case Q#xmlel.children of - [#xmlel{name = <<"remove">>}] -> - only_remove_child; - [_] -> - bad_request - end; + case Q#xmlel.children of + [#xmlel{name = <<"remove">>}] -> + only_remove_child; + [_] -> + bad_request + end; which_child_elements(#xmlel{children = C} = Q) when length(C) > 1 -> case exml_query:subelement(Q, <<"remove">>) of #xmlel{name = <<"remove">>} -> From e9e14113400af5042e027b371d6b9e65d906e533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Wed, 8 Sep 2021 12:40:08 +0200 Subject: [PATCH 4/5] Remove old comments --- big_tests/tests/accounts_SUITE.erl | 1 - src/mod_register.erl | 4 ---- 2 files changed, 5 deletions(-) diff --git a/big_tests/tests/accounts_SUITE.erl b/big_tests/tests/accounts_SUITE.erl index 8b17446de2..eb71668b5f 100644 --- a/big_tests/tests/accounts_SUITE.erl +++ b/big_tests/tests/accounts_SUITE.erl @@ -65,7 +65,6 @@ change_password_tests() -> %%-------------------------------------------------------------------- init_per_suite(Config1) -> - %Host = ct:get_config({hosts, mim, domain}), ok = dynamic_modules:ensure_modules(host_type(), required_modules()), Config2 = [{mod_register_options, mod_register_options()} | Config1], escalus:init_per_suite([{escalus_user_db, xmpp} | Config2]). diff --git a/src/mod_register.erl b/src/mod_register.erl index 17958df070..72fa588f91 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -77,7 +77,6 @@ iq_handlers() -> [{ejabberd_local, fun ?MODULE:process_iq/5}, {ejabberd_sm, fun ?MODULE:process_iq/5}]. hooks(HostType) -> - %FIXME handle host_type in hooks [{c2s_stream_features, HostType, ?MODULE, c2s_stream_features, 50}, {c2s_unauthenticated_iq, HostType, ?MODULE, unauthenticated_iq_register, 50}]. @@ -238,7 +237,6 @@ register_or_change_password(HostType, Credentials, ClientJID, #jid{lserver = Ser end. attempt_cancelation(HostType, #jid{} = ClientJID, #jid{lserver = ServerDomain}, #iq{} = IQ) -> - %Is replacing server lserver with passed hostname ok? case inband_registration_and_cancelation_allowed(HostType, ServerDomain, ClientJID) of true -> %% The response must be sent *before* the @@ -295,8 +293,6 @@ try_register_or_set_password(HostType, User, Server, Password, #jid{user = User, IQ, SubEl, _Source, Lang) -> try_set_password(HostType, UserJID, Password, IQ, SubEl, Lang); try_register_or_set_password(HostType, User, Server, Password, _From, IQ, SubEl, Source, Lang) -> - ?LOG_DEBUG(#{what => user_data_info, - host=> HostType, reason => #{user => User, server => Server, password => Password}}), case check_timeout(Source) of true -> case try_register(HostType, User, Server, Password, Source, Lang) of From 8cbc2c24ab34183ded81622449a111e3cc4d525e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Wojtasik?= Date: Wed, 8 Sep 2021 15:29:06 +0200 Subject: [PATCH 5/5] Small fixes and formatting --- big_tests/tests/accounts_SUITE.erl | 40 ++++++++++++++--------------- big_tests/tests/mongoose_helper.erl | 11 ++------ rel/mim1.vars-toml.config | 4 +-- src/mod_register.erl | 4 +-- 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/big_tests/tests/accounts_SUITE.erl b/big_tests/tests/accounts_SUITE.erl index eb71668b5f..d39dc0cfd2 100644 --- a/big_tests/tests/accounts_SUITE.erl +++ b/big_tests/tests/accounts_SUITE.erl @@ -34,25 +34,25 @@ all() -> groups() -> [{register, [parallel], [register, - already_registered, - registration_conflict, - check_unregistered]}, - {registration_watchers, [sequence], [admin_notify]}, - {bad_registration, [sequence], [null_password]}, - {bad_cancelation, [sequence], [bad_request_registration_cancelation, - not_allowed_registration_cancelation]}, - {registration_timeout, [sequence], [registration_timeout, - registration_failure_timeout]}, - {change_account_details, [parallel], change_password_tests()}, - {change_account_details_store_plain, [parallel], change_password_tests()}, - {utilities, [{group, user_info}, - {group, users_number_estimate}]}, - {user_info, [parallel], [list_users, - list_selected_users, - count_users, - count_selected_users]}, - {users_number_estimate, [], [count_users_estimate]} - ]. + already_registered, + registration_conflict, + check_unregistered]}, + {registration_watchers, [sequence], [admin_notify]}, + {bad_registration, [sequence], [null_password]}, + {bad_cancelation, [sequence], [bad_request_registration_cancelation, + not_allowed_registration_cancelation]}, + {registration_timeout, [sequence], [registration_timeout, + registration_failure_timeout]}, + {change_account_details, [parallel], change_password_tests()}, + {change_account_details_store_plain, [parallel], change_password_tests()}, + {utilities, [{group, user_info}, + {group, users_number_estimate}]}, + {user_info, [parallel], [list_users, + list_selected_users, + count_users, + count_selected_users]}, + {users_number_estimate, [], [count_users_estimate]} + ]. suite() -> require_rpc_nodes([mim]) ++ escalus:suite(). @@ -89,7 +89,7 @@ init_per_group(change_account_details, Config) -> [{escalus_user_db, {module, escalus_ejabberd}} |Config]; init_per_group(change_account_details_store_plain, Config) -> Config1 = mongoose_helper:backup_auth_config(Config), - mongoose_helper:set_store_password(host_type(), plain), + mongoose_helper:set_store_password(plain), [{escalus_user_db, {module, escalus_ejabberd}} |Config1]; init_per_group(registration_timeout, Config) -> set_registration_timeout(Config); diff --git a/big_tests/tests/mongoose_helper.erl b/big_tests/tests/mongoose_helper.erl index 92b52ee424..62afe9214d 100644 --- a/big_tests/tests/mongoose_helper.erl +++ b/big_tests/tests/mongoose_helper.erl @@ -41,7 +41,6 @@ -export([backup_sasl_mechanisms_config/1, restore_sasl_mechanisms_config/1]). -export([set_sasl_mechanisms/2]). -export([set_store_password/1]). --export([set_store_password/2]). -export([get_listener_opts/2]). -export([restart_listener_with_opts/3]). -export([should_minio_be_running/1]). @@ -479,18 +478,12 @@ restore_sasl_mechanisms_config(Config) -> set_sasl_mechanisms(GlobalOrHostSASLMechanisms, Mechanisms) -> rpc(mim(), ejabberd_config, add_local_option, [GlobalOrHostSASLMechanisms, Mechanisms]). -set_store_password(HostType, Type) -> +set_store_password(Type) -> + HostType = domain_helper:host_type(mim), AuthOpts = rpc(mim(), ejabberd_config, get_local_option, [{auth_opts, HostType}]), NewAuthOpts = build_new_auth_opts(Type, AuthOpts), rpc(mim(), ejabberd_config, add_local_option, [{auth_opts, HostType}, NewAuthOpts]). -set_store_password(Type) -> - XMPPDomain = escalus_ejabberd:unify_str_arg( - ct:get_config({hosts, mim, domain})), - AuthOpts = rpc(mim(), ejabberd_config, get_local_option, [{auth_opts, XMPPDomain}]), - NewAuthOpts = build_new_auth_opts(Type, AuthOpts), - rpc(mim(), ejabberd_config, add_local_option, [{auth_opts, XMPPDomain}, NewAuthOpts]). - build_new_auth_opts(scram, AuthOpts) -> NewAuthOpts0 = lists:keystore(password_format, 1, AuthOpts, {password_format, scram}), lists:keystore(password_format, 1, NewAuthOpts0, {scram_iterations, 64}); diff --git a/rel/mim1.vars-toml.config b/rel/mim1.vars-toml.config index 5e295787bf..ff994e13fb 100644 --- a/rel/mim1.vars-toml.config +++ b/rel/mim1.vars-toml.config @@ -35,10 +35,8 @@ [host_config.modules.mod_disco] - {{#mod_register}} [host_config.modules.mod_register] - {{{mod_register}}} - {{/mod_register}} + {{#mod_last}} [host_config.modules.mod_last] {{{mod_last}}} diff --git a/src/mod_register.erl b/src/mod_register.erl index 72fa588f91..dbe54aebf6 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -138,7 +138,8 @@ c2s_stream_features(Acc, _HostType, _LServer) -> [#xmlel{name = <<"register">>, attrs = [{<<"xmlns">>, ?NS_FEATURE_IQREGISTER}]} | Acc]. --spec unauthenticated_iq_register(empty, mongooseim:host_type(), jid:server(), jlib:iq(), +-spec unauthenticated_iq_register(exml:element() | empty, mongooseim:host_type(), + jid:server(), jlib:iq(), {inet:ip_address(), inet:port_number()} | undefined) -> exml:element() | empty. unauthenticated_iq_register(_Acc, HostType, Server, #iq{xmlns = ?NS_REGISTER} = IQ, IP) -> @@ -156,7 +157,6 @@ unauthenticated_iq_register(_Acc, HostType, Server, #iq{xmlns = ?NS_REGISTER} = IQ, Address), set_sender(jlib:iq_to_xml(ResIQ), make_host_only_jid(Server)); - unauthenticated_iq_register(Acc, _HostType, _Server, _IQ, _IP) -> Acc.