diff --git a/big_tests/dynamic_domains.config b/big_tests/dynamic_domains.config index ab4d0eb254..6ec6963722 100644 --- a/big_tests/dynamic_domains.config +++ b/big_tests/dynamic_domains.config @@ -5,6 +5,7 @@ {domain, <<"domain.example.com">>}, {secondary_domain, <<"domain.example.org">>}, {dynamic_domains, [<<"domain.example.com">>, <<"domain.example.org">>]}, + {host_type, <<"test type">>}, {vars, "mim1"}, {cluster, mim}, {s2s_port, 5269}, diff --git a/big_tests/dynamic_domains.spec b/big_tests/dynamic_domains.spec index 2b696a1328..a42a775e6d 100644 --- a/big_tests/dynamic_domains.spec +++ b/big_tests/dynamic_domains.spec @@ -9,7 +9,7 @@ %% http://www.erlang.org/doc/apps/common_test/run_test_chapter.html#test_specifications {include, "tests"}. -{suites, "tests", domain_isolation_SUITE}. +{suites, "tests", acc_e2e_SUITE}. {config, ["dynamic_domains.config", "test.config"]}. {logdir, "ct_report"}. diff --git a/big_tests/tests/acc_e2e_SUITE.erl b/big_tests/tests/acc_e2e_SUITE.erl index e19bcc86a5..9579aeb8ce 100644 --- a/big_tests/tests/acc_e2e_SUITE.erl +++ b/big_tests/tests/acc_e2e_SUITE.erl @@ -170,12 +170,13 @@ acc_test_helper_code(Config) -> binary_to_list(Code). add_handler(Hook, F, Seq) -> - rpc(mim(), ejabberd_hooks, add, [Hook, host(), acc_test_helper, F, Seq]). + rpc(mim(), ejabberd_hooks, add, handler(Hook, F, Seq)). remove_handler(Hook, F, Seq) -> - rpc(mim(), ejabberd_hooks, delete, [Hook, host(), acc_test_helper, F, Seq]). + rpc(mim(), ejabberd_hooks, delete, handler(Hook, F, Seq)). -host() -> <<"localhost">>. +handler(Hook, F, Seq) -> + [Hook, domain_helper:host_type(mim), acc_test_helper, F, Seq]. %% creates a temporary ets table keeping refs and some attrs of accumulators created in c2s recreate_table() -> diff --git a/big_tests/tests/domain_helper.erl b/big_tests/tests/domain_helper.erl index 916ad7647f..6f3c56a6c0 100644 --- a/big_tests/tests/domain_helper.erl +++ b/big_tests/tests/domain_helper.erl @@ -2,27 +2,35 @@ -export([insert_configured_domains/0, delete_configured_domains/0, - insert_domain/2, - delete_domain/2]). + insert_domain/3, + delete_domain/2, + host_type/1, + host_type/2]). -import(distributed_helper, [get_or_fail/1, rpc/4]). +host_type(NodeKey) -> + host_type(NodeKey, domain). + +host_type(NodeKey, DomainKey) -> + Node = #{node => get_or_fail({hosts, NodeKey, node})}, + Domain = get_or_fail({hosts, NodeKey, DomainKey}), + {ok, HostType} = rpc(Node, mongoose_domain_core, get_host_type, [Domain]), + HostType. + insert_configured_domains() -> - for_each_configured_domain(fun insert_domain/2). + for_each_configured_domain(fun insert_domain/3). delete_configured_domains() -> - for_each_configured_domain(fun delete_domain/2). + for_each_configured_domain(fun(Node, Domain, _) -> delete_domain(Node, Domain) end). -insert_domain(Node, Domain) -> - ok = rpc(Node, mongoose_domain_core, insert, [Domain, host_type(), dummy_source]). +insert_domain(Node, Domain, HostType) -> + ok = rpc(Node, mongoose_domain_core, insert, [Domain, HostType, dummy_source]). delete_domain(Node, Domain) -> ok = rpc(Node, mongoose_domain_core, delete, [Domain]). for_each_configured_domain(F) -> - [F(#{node => proplists:get_value(node, Opts)}, Domain) || + [F(#{node => proplists:get_value(node, Opts)}, Domain, proplists:get_value(host_type, Opts)) || {_, Opts} <- ct:get_config(hosts), Domain <- proplists:get_value(dynamic_domains, Opts, [])]. - -host_type() -> - <<"test type">>. %% preconfigured in the toml file diff --git a/big_tests/tests/dynamic_domains_SUITE.erl b/big_tests/tests/dynamic_domains_SUITE.erl index 81accb21ce..501cfdb4fb 100644 --- a/big_tests/tests/dynamic_domains_SUITE.erl +++ b/big_tests/tests/dynamic_domains_SUITE.erl @@ -200,7 +200,7 @@ iq_handling_for_subdomain(Config) -> %% helper functions insert_domains(Nodes, Domains) -> - [domain_helper:insert_domain(Node, Domain) || Node <- Nodes, Domain <- Domains]. + [domain_helper:insert_domain(Node, Domain, ?HOST_TYPE) || Node <- Nodes, Domain <- Domains]. remove_domains(Nodes, Domains) -> [domain_helper:delete_domain(Node, Domain) || Node <- Nodes, Domain <- Domains]. diff --git a/big_tests/tests/ejabberdctl_SUITE.erl b/big_tests/tests/ejabberdctl_SUITE.erl index 7a7c8c7dad..0c49544411 100644 --- a/big_tests/tests/ejabberdctl_SUITE.erl +++ b/big_tests/tests/ejabberdctl_SUITE.erl @@ -245,6 +245,7 @@ end_per_group(Rosters, Config) when (Rosters == roster) or (Rosters == roster_ad Acc = rpc(mim(), mongoose_acc, new, [#{ location => {?MODULE, ?FUNCTION_NAME, ?LINE}, lserver => SB, + host_type => SB, element => undefined }]), rpc(mim(), mongoose_hooks, remove_user, [SB, Acc, UB]); _ -> diff --git a/src/admin_extra/service_admin_extra_gdpr.erl b/src/admin_extra/service_admin_extra_gdpr.erl index e611fe41cf..502587926a 100644 --- a/src/admin_extra/service_admin_extra_gdpr.erl +++ b/src/admin_extra/service_admin_extra_gdpr.erl @@ -65,7 +65,7 @@ get_data_from_modules(Username, Domain) -> -spec get_data_from_modules(jid:jid()) -> gdpr:personal_data(). get_data_from_modules(JID) -> - {ok, HostType} = mongoose_domain_api:get_host_type(JID#jid.lserver), + {ok, HostType} = mongoose_domain_api:get_domain_host_type(JID#jid.lserver), mongoose_hooks:get_personal_data(HostType, JID). -spec to_csv_file(CsvFilename :: binary(), gdpr:schema(), gdpr:entities(), file:name()) -> ok. diff --git a/src/admin_extra/service_admin_extra_roster.erl b/src/admin_extra/service_admin_extra_roster.erl index 934be7887e..38e379a766 100644 --- a/src/admin_extra/service_admin_extra_roster.erl +++ b/src/admin_extra/service_admin_extra_roster.erl @@ -248,7 +248,9 @@ unsubscribe(LocalJID, RemoteJID) -> [jids_nick_subs_ask_grp()]. get_roster(User, Server) -> UserJID = jid:make(User, Server, <<>>), + {ok, HostType} = mongoose_domain_api:get_domain_host_type(UserJID#jid.lserver), Acc = mongoose_acc:new(#{location => ?LOCATION, + host_type => HostType, lserver => UserJID#jid.lserver, element => undefined}), Acc2 = mongoose_hooks:roster_get(Acc, UserJID), diff --git a/src/auth/ejabberd_auth.erl b/src/auth/ejabberd_auth.erl index 83b0f63993..29f25b7f66 100644 --- a/src/auth/ejabberd_auth.erl +++ b/src/auth/ejabberd_auth.erl @@ -396,7 +396,7 @@ entropy(IOList) -> %% use auth_modules_for_host_type/1 function instead. -spec auth_modules(Server :: jid:lserver()) -> [authmodule()]. auth_modules(LServer) -> - case mongoose_domain_api:get_host_type(LServer) of + case mongoose_domain_api:get_domain_host_type(LServer) of {ok, HostType} -> auth_modules_for_host_type(HostType); {error, not_found} -> [] end. @@ -476,7 +476,7 @@ get_type_information(_IOContent, [Digit, Printable, LowLetter, HiLetter, _Other] -spec call_auth_modules_for_domain(jid:lserver(), host_type_mod_fun(), call_opts()) -> mod_res() | [mod_res()]. call_auth_modules_for_domain(Domain, F, Opts = #{default := Default}) -> - case mongoose_domain_api:get_host_type(Domain) of + case mongoose_domain_api:get_domain_host_type(Domain) of {ok, HostType} -> StepF = bind_host_type(HostType, F), case maps:take(metric, Opts) of diff --git a/src/auth/ejabberd_auth_rdbms.erl b/src/auth/ejabberd_auth_rdbms.erl index 20b5589405..bb54258cbb 100644 --- a/src/auth/ejabberd_auth_rdbms.erl +++ b/src/auth/ejabberd_auth_rdbms.erl @@ -324,7 +324,7 @@ scram_passwords(Server, ScramIterationCount) -> ScramIterationCount :: pos_integer(). scram_passwords(Server, Count, Interval, ScramIterationCount) -> LServer = jid:nameprep(Server), - {ok, HostType} = mongoose_domain_api:get_host_type(LServer), + {ok, HostType} = mongoose_domain_api:get_domain_host_type(LServer), ?LOG_INFO(#{what => scram_passwords, server => Server, text => <<"Converting the stored passwords into SCRAM bits">>}), Selected = execute_count_users_without_scram(HostType, LServer), diff --git a/src/domain/mongoose_domain_api.erl b/src/domain/mongoose_domain_api.erl index d0e5d6b69b..4757b714f5 100644 --- a/src/domain/mongoose_domain_api.erl +++ b/src/domain/mongoose_domain_api.erl @@ -118,7 +118,17 @@ get_domain_host_type(Domain) -> -spec get_subdomain_host_type(domain()) -> {ok, host_type()} | {error, not_found}. get_subdomain_host_type(Subdomain) -> - mongoose_subdomain_core:get_host_type(Subdomain). + case mongoose_subdomain_core:get_host_type(Subdomain) of + {error, not_found} -> + case mongoose_subhosts:get_host(Subdomain) of + {ok, Domain} -> + get_domain_host_type(Domain); + undefined -> + {error, not_found} + end; + {ok, HostType} -> + {ok, HostType} + end. %% Subdomain should be nameprepped using `jid:nameprep' -spec get_subdomain_info(domain()) -> diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 1711ec8ef6..1ee3bc4b86 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -287,7 +287,7 @@ handle_stream_start({xmlstreamstart, _Name, Attrs}, #state{} = S0) -> Lang = get_xml_lang(Attrs), S = S0#state{server = Server, lang = Lang, stream_mgmt = StreamMgmtConfig}, case {xml:get_attr_s(<<"xmlns:stream">>, Attrs), - mongoose_domain_api:get_host_type(Server)} of + mongoose_domain_api:get_domain_host_type(Server)} of {?NS_STREAM, {ok, HostType}} -> change_shaper(S, jid:make_noprep(<<>>, Server, <<>>)), Version = xml:get_attr_s(<<"version">>, Attrs), diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index da381281f6..cf55b7986d 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -100,7 +100,7 @@ start_link() -> %% and implement two functions: %% filter/3 - should return either 'drop' atom or its args %% route/3, which should either: -%% - deliver the message locally by calling mongoose_local_delivery:do_local_route/3 +%% - deliver the message locally by calling mongoose_local_delivery:do_route/5 %% and return 'done' %% - deliver the message it its own way and return 'done' %% - return its args diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index a71a3b5ec3..34a64538ad 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -583,7 +583,7 @@ send_element(StateData, El) -> -spec stream_features(binary()) -> [exml:element()]. stream_features(Domain) -> - case mongoose_domain_api:get_host_type(Domain) of + case mongoose_domain_api:get_domain_host_type(Domain) of {ok, HostType} -> mongoose_hooks:s2s_stream_features(HostType, Domain); {error, not_found} -> [] end. diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 62339a31b6..47063b9df8 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -141,27 +141,35 @@ start_link() -> Packet :: exml:element() | mongoose_acc:t() | ejabberd_c2s:broadcast(), Acc :: mongoose_acc:t(). route(From, To, #xmlel{} = Packet) -> - Acc = mongoose_acc:new(#{ location => ?LOCATION, - lserver => To#jid.lserver, - element => Packet, - from_jid => From, - to_jid => To }), + Acc = new_acc(From, To, Packet), route(From, To, Acc); route(From, To, {broadcast, #xmlel{} = Payload}) -> - Acc = mongoose_acc:new(#{ location => ?LOCATION, - from_jid => From, - to_jid => To, - lserver => To#jid.lserver, - element => Payload }), + Acc = new_acc(From, To, Payload), route(From, To, Acc, {broadcast, Payload}); route(From, To, {broadcast, Payload}) -> - Acc = mongoose_acc:new(#{ location => ?LOCATION, - lserver => To#jid.lserver, - element => undefined }), + Acc = new_acc(To), route(From, To, Acc, {broadcast, Payload}); route(From, To, Acc) -> route(From, To, Acc, mongoose_acc:element(Acc)). +-spec new_acc(jid:jid(), jid:jid(), exml:element()) -> mongoose_acc:t(). +new_acc(From, To = #jid{lserver = LServer}, Packet) -> + {ok, HostType} = mongoose_domain_api:get_domain_host_type(To#jid.lserver), + mongoose_acc:new(#{location => ?LOCATION, + host_type => HostType, + lserver => LServer, + element => Packet, + from_jid => From, + to_jid => To}). + +-spec new_acc(jid:jid()) -> mongoose_acc:t(). +new_acc(To = #jid{lserver = LServer}) -> + {ok, HostType} = mongoose_domain_api:get_domain_host_type(To#jid.lserver), + mongoose_acc:new(#{location => ?LOCATION, + host_type => HostType, + lserver => LServer, + element => undefined}). + route(From, To, Acc, {broadcast, Payload}) -> try do_route(Acc, From, To, {broadcast, Payload}) diff --git a/src/ejabberd_sm_mnesia.erl b/src/ejabberd_sm_mnesia.erl index 442ae44b0a..a529a4705f 100644 --- a/src/ejabberd_sm_mnesia.erl +++ b/src/ejabberd_sm_mnesia.erl @@ -103,20 +103,19 @@ cleanup(Node) -> [{#session{sid = {'_', '$1'}, _ = '_'}, [{'==', {node, '$1'}, Node}], ['$_']}]), - lists:foreach(fun(#session{ usr = {U, S, R}, sid = SID }) -> - mnesia:delete({session, SID}), - Acc = mongoose_acc:new( - #{location => ?LOCATION, - lserver => S, - element => undefined}), - mongoose_hooks:session_cleanup(S, - Acc, - U, R, SID) - end, Es) - + lists:foreach(fun cleanup_session/1, Es) end, mnesia:async_dirty(F). +cleanup_session(#session{usr = {U, S, R}, sid = SID}) -> + {ok, HostType} = mongoose_domain_api:get_domain_host_type(S), + mnesia:delete({session, SID}), + Acc = mongoose_acc:new( + #{location => ?LOCATION, + host_type => HostType, + lserver => S, + element => undefined}), + mongoose_hooks:session_cleanup(S, Acc, U, R, SID). -spec total_count() -> integer(). total_count() -> diff --git a/src/ejabberd_sm_redis.erl b/src/ejabberd_sm_redis.erl index a607e45b99..277e12119b 100644 --- a/src/ejabberd_sm_redis.erl +++ b/src/ejabberd_sm_redis.erl @@ -141,8 +141,10 @@ cleanup(Node) -> %% Add possible removed ":" from encoded SID SID = binary_to_term(mongoose_bin:join(SIDEncoded, <<":">>)), delete_session(SID, U, S, R), + {ok, HostType} = mongoose_domain_api:get_domain_host_type(S), Acc = mongoose_acc:new( #{location => ?LOCATION, + host_type => HostType, lserver => S, element => undefined}), mongoose_hooks:session_cleanup(S, diff --git a/src/ejabberd_users.erl b/src/ejabberd_users.erl index e29b6dfad9..ba5d5c7e9b 100644 --- a/src/ejabberd_users.erl +++ b/src/ejabberd_users.erl @@ -173,7 +173,7 @@ code_change(_OldVsn, State, _Extra) -> -spec does_stored_user_exist(jid:jid()) -> boolean(). does_stored_user_exist(JID = #jid{lserver = LServer}) -> - case mongoose_domain_api:get_host_type(LServer) of + case mongoose_domain_api:get_domain_host_type(LServer) of {ok, HostType} -> case ejabberd_auth:does_stored_user_exist(HostType, JID) of true -> true; diff --git a/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl b/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl index a1e33100ac..58e20f4316 100644 --- a/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl +++ b/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl @@ -139,8 +139,11 @@ publish_via_hook(Acc0, Host, To, {PubsubJID, Node, Form}, PushPayload) -> any(). publish_via_pubsub(Host, To, {PubsubJID, Node, Form}, PushPayload) -> Stanza = push_notification_iq(Node, Form, PushPayload), + %% TODO host type should be provided to this function + {ok, HostType} = mongoose_domain_api:get_domain_host_type(Host), Acc = mongoose_acc:new(#{ location => ?LOCATION, - lserver => To#jid.lserver, + host_type => HostType, + lserver => Host, element => jlib:iq_to_xml(Stanza), from_jid => To, to_jid => PubsubJID }), diff --git a/src/inbox/mod_inbox.erl b/src/inbox/mod_inbox.erl index df95a43ad3..fd93f2e3af 100644 --- a/src/inbox/mod_inbox.erl +++ b/src/inbox/mod_inbox.erl @@ -215,10 +215,12 @@ forward_messages(Acc, List, QueryId, To) when is_list(List) -> [send_message(Acc, To, Msg) || Msg <- Msgs]. -spec send_message(mongoose_acc:t(), jid:jid(), exml:element()) -> mongoose_acc:t(). -send_message(Acc, To, Msg) -> +send_message(Acc, To = #jid{lserver = LServer}, Msg) -> BareTo = jid:to_bare(To), + {ok, HostType} = mongoose_domain_api:get_domain_host_type(LServer), NewAcc0 = mongoose_acc:new(#{location => ?LOCATION, - lserver => To#jid.lserver, + host_type => HostType, + lserver => LServer, element => Msg, from_jid => BareTo, to_jid => To}), diff --git a/src/inbox/mod_inbox_muc.erl b/src/inbox/mod_inbox_muc.erl index 531a1725fa..58c882d630 100644 --- a/src/inbox/mod_inbox_muc.erl +++ b/src/inbox/mod_inbox_muc.erl @@ -93,7 +93,7 @@ direction(From, To) -> Packet :: packet(). handle_outgoing_message(Host, Room, To, Packet) -> maybe_reset_unread_count(Host, To, Room, Packet), - Acc = mongoose_acc:new(#{location => ?LOCATION, lserver => Host, host_type => undefined}), + Acc = mongoose_acc:new(#{location => ?LOCATION, lserver => Host}), maybe_write_to_inbox(Host, To, Room, Packet, Acc, fun write_to_sender_inbox/5). -spec handle_incoming_message(Host, Room, To, Packet) -> term() when @@ -102,7 +102,7 @@ handle_outgoing_message(Host, Room, To, Packet) -> To :: receiver_bare_user_jid(), Packet :: packet(). handle_incoming_message(Host, Room, To, Packet) -> - Acc = mongoose_acc:new(#{location => ?LOCATION, lserver => Host, host_type => undefined}), + Acc = mongoose_acc:new(#{location => ?LOCATION, lserver => Host}), maybe_write_to_inbox(Host, Room, To, Packet, Acc, fun write_to_receiver_inbox/5). maybe_reset_unread_count(Host, User, Room, Packet) -> diff --git a/src/mod_commands.erl b/src/mod_commands.erl index 0b4c5c451c..568c9d061a 100644 --- a/src/mod_commands.erl +++ b/src/mod_commands.erl @@ -286,38 +286,21 @@ unregister(Host, User) -> send_message(From, To, Body) -> case parse_from_to(From, To) of - {ok, F, T} -> + {ok, FromJID, ToJID} -> Packet = build_message(From, To, Body), - Acc0 = mongoose_acc:new(#{location => ?LOCATION, - lserver => F#jid.lserver, - element => Packet}), - - mongoose_hooks:user_send_packet(F#jid.lserver, - Acc0, - F, T, Packet), - - %% privacy check is missing, but is it needed? - ejabberd_router:route(F, T, Packet), - ok; - E -> - E + do_send_packet(FromJID, ToJID, Packet); + Error -> + Error end. send_stanza(BinStanza) -> case exml:parse(BinStanza) of {ok, Packet} -> - F = exml_query:attr(Packet, <<"from">>), - T = exml_query:attr(Packet, <<"to">>), - case parse_from_to(F, T) of - {ok, From, To} -> - Acc0 = mongoose_acc:new(#{location => ?LOCATION, - lserver => From#jid.lserver, - element => Packet}), - mongoose_hooks:user_send_packet(From#jid.lserver, - Acc0, - From, To, Packet), - ejabberd_router:route(From, To, Packet), - ok; + From = exml_query:attr(Packet, <<"from">>), + To = exml_query:attr(Packet, <<"to">>), + case parse_from_to(From, To) of + {ok, FromJID, ToJID} -> + do_send_packet(FromJID, ToJID, Packet); {error, missing} -> {error, bad_request, "both from and to are required"}; {error, type_error, E} -> @@ -327,6 +310,22 @@ send_stanza(BinStanza) -> {error, bad_request, io_lib:format("Malformed stanza: ~p", [Reason])} end. +do_send_packet(From, To, Packet) -> + case mongoose_domain_api:get_domain_host_type(From#jid.lserver) of + {ok, HostType} -> + Acc0 = mongoose_acc:new(#{location => ?LOCATION, + host_type => HostType, + lserver => From#jid.lserver, + element => Packet}), + mongoose_hooks:user_send_packet(From#jid.lserver, + Acc0, + From, To, Packet), + ejabberd_router:route(From, To, Packet), + ok; + {error, not_found} -> + {error, unknown_domain} + end. + -spec parse_from_to(jid:jid() | binary() | undefined, jid:jid() | binary() | undefined) -> {ok, jid:jid(), jid:jid()} | {error, missing} | {error, type_error, string()}. parse_from_to(F, T) when F == undefined; T == undefined -> @@ -339,7 +338,9 @@ parse_from_to(F, T) -> list_contacts(Caller) -> CallerJID = #jid{lserver = LServer} = jid:from_binary(Caller), + {ok, HostType} = mongoose_domain_api:get_domain_host_type(LServer), Acc0 = mongoose_acc:new(#{ location => ?LOCATION, + host_type => HostType, lserver => LServer, element => undefined }), Acc1 = mongoose_acc:set(roster, show_full_roster, true, Acc0), @@ -497,9 +498,11 @@ run_subscription(Type, CallerJid, OtherJid) -> StanzaType = atom_to_binary(Type, latin1), El = #xmlel{name = <<"presence">>, attrs = [{<<"type">>, StanzaType}]}, LServer = CallerJid#jid.lserver, + {ok, HostType} = mongoose_domain_api:get_domain_host_type(LServer), Acc1 = mongoose_acc:new(#{ location => ?LOCATION, from_jid => CallerJid, to_jid => OtherJid, + host_type => HostType, lserver => LServer, element => El }), % set subscription to diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 471000bf03..cc4cdfccea 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -405,7 +405,9 @@ get_sm_items(empty, From, To, _Node, _Lang) -> -spec is_presence_subscribed(jid:jid(), jid:jid()) -> boolean(). is_presence_subscribed(#jid{luser = LFromUser, lserver = LFromServer} = FromJID, #jid{luser = LToUser, lserver = LToServer} = _To) -> + {ok, HostType} = mongoose_domain_api:get_domain_host_type(LFromServer), A = mongoose_acc:new(#{ location => ?LOCATION, + host_type => HostType, lserver => LFromServer, element => undefined }), A2 = mongoose_hooks:roster_get(A, FromJID), diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 11943e6b87..184d0b2a98 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -1095,8 +1095,11 @@ get_roster_old(#jid{lserver = LServer} = JID) -> get_roster_old(LServer, JID). get_roster_old(DestServer, JID) -> + %% TODO host type should be passed to this function + {ok, HostType} = mongoose_domain_api:get_domain_host_type(DestServer), A = mongoose_acc:new(#{ location => ?LOCATION, lserver => DestServer, + host_type => HostType, element => undefined }), A2 = mongoose_hooks:roster_get(A, JID), mongoose_acc:get(roster, items, [], A2). diff --git a/src/mongoose_acc.erl b/src/mongoose_acc.erl index c78ffe0eac..b448f95d5e 100644 --- a/src/mongoose_acc.erl +++ b/src/mongoose_acc.erl @@ -307,11 +307,8 @@ strip(#{ lserver := NewLServer } = Params, Acc) -> -spec get_host_type(new_acc_params() | strip_params()) -> binary() | undefined. get_host_type(#{host_type := HostType}) -> HostType; -get_host_type(#{lserver := LServer}) -> - case mongoose_domain_api:get_host_type(LServer) of - {error, not_found} -> undefined; - {ok, HostType} -> HostType - end. +get_host_type(_) -> + undefined. -spec stanza_from_params(Params :: stanza_params() | strip_params()) -> stanza_metadata(). diff --git a/src/mongoose_client_api/mongoose_client_api.erl b/src/mongoose_client_api/mongoose_client_api.erl index f193b1d6d1..2b064b9311 100644 --- a/src/mongoose_client_api/mongoose_client_api.erl +++ b/src/mongoose_client_api/mongoose_client_api.erl @@ -117,7 +117,7 @@ check_password(error, _) -> false; check_password(JID, Password) -> {LUser, LServer} = jid:to_lus(JID), - case mongoose_domain_api:get_host_type(LServer) of + case mongoose_domain_api:get_domain_host_type(LServer) of {ok, HostType} -> Creds0 = mongoose_credentials:new(LServer, HostType), Creds1 = mongoose_credentials:set(Creds0, username, LUser), diff --git a/src/mongoose_client_api/mongoose_client_api_rooms_messages.erl b/src/mongoose_client_api/mongoose_client_api_rooms_messages.erl index 7a64ebbdca..1d5f0684d0 100644 --- a/src/mongoose_client_api/mongoose_client_api_rooms_messages.erl +++ b/src/mongoose_client_api/mongoose_client_api_rooms_messages.erl @@ -92,9 +92,11 @@ from_json(Req, #{user := User, jid := JID, room := Room} = State) -> prepare_message_and_route_to_room(User, JID, Room, State, Req, JSONData) -> RoomJID = #jid{lserver = _} = maps:get(jid, Room), UUID = uuid:uuid_to_string(uuid:get_v4(), binary_standard), + {ok, HostType} = mongoose_domain_api:get_domain_host_type(JID#jid.lserver), case build_message_from_json(User, RoomJID, UUID, JSONData) of {ok, Message} -> Acc = mongoose_acc:new(#{ location => ?LOCATION, + host_type => HostType, lserver => JID#jid.lserver, from_jid => JID, to_jid => RoomJID, diff --git a/src/mongoose_client_api/mongoose_client_api_sse.erl b/src/mongoose_client_api/mongoose_client_api_sse.erl index 303f7d0420..af7f3be36f 100644 --- a/src/mongoose_client_api/mongoose_client_api_sse.erl +++ b/src/mongoose_client_api/mongoose_client_api_sse.erl @@ -51,7 +51,7 @@ handle_error(Msg, Reason, State) -> ?LOG_WARNING(#{what => sse_handle_error, msg => Msg, reason => Reason}), {nosend, State}. -terminate(_Reson, _Req, State) -> +terminate(_Reason, _Req, #{creds := Creds} = State) -> case maps:get(sid, State, undefined) of undefined -> ok; @@ -60,6 +60,7 @@ terminate(_Reson, _Req, State) -> Acc = mongoose_acc:new( #{location => ?LOCATION, lserver => S, + host_type => mongoose_credentials:host_type(Creds), element => undefined}), ejabberd_sm:close_session(Acc, SID, JID, normal) end, diff --git a/src/mongoose_hooks.erl b/src/mongoose_hooks.erl index c4c61eeb0d..db88964c51 100644 --- a/src/mongoose_hooks.erl +++ b/src/mongoose_hooks.erl @@ -16,7 +16,7 @@ auth_failed/3, ejabberd_ctl_process/2, failed_to_store_message/1, - filter_local_packet/2, + filter_local_packet/1, filter_packet/1, inbox_unread_count/3, local_send_to_resource_hook/4, @@ -263,12 +263,12 @@ failed_to_store_message(Acc) -> To :: jid:jid(), Acc :: mongoose_acc:t(), Packet :: exml:element()}. --spec filter_local_packet(Server, Acc) -> Result when - Server :: jid:server(), - Acc :: filter_packet_acc(), +-spec filter_local_packet(FilterAcc) -> Result when + FilterAcc :: filter_packet_acc(), Result :: drop | filter_packet_acc(). -filter_local_packet(Server, Acc) -> - ejabberd_hooks:run_for_host_type(filter_local_packet, Server, Acc, []). +filter_local_packet(FilterAcc = {_From, _To, Acc, _Packet}) -> + HostType = mongoose_acc:host_type(Acc), + ejabberd_hooks:run_for_host_type(filter_local_packet, HostType, FilterAcc, []). %%% @doc The `filter_packet' hook is called to filter out %%% stanzas routed with `mongoose_router_global'. diff --git a/src/mongoose_local_delivery.erl b/src/mongoose_local_delivery.erl index 49fbee78c9..6b0c0ee12f 100644 --- a/src/mongoose_local_delivery.erl +++ b/src/mongoose_local_delivery.erl @@ -11,23 +11,36 @@ -include("jlib.hrl"). %% API --export([do_route/6]). +-export([do_route/5]). -do_route(OrigFrom, OrigTo, OrigAcc, OrigPacket, LDstDomain, Handler) -> +do_route(OrigFrom, OrigTo, OrigAcc, OrigPacket, Handler) -> % strip acc from all sender-related values, from now on we are interested in the recipient - Acc0 = mongoose_acc:strip(#{lserver => OrigTo#jid.lserver, - from_jid => OrigFrom, - to_jid => OrigTo, - element => OrigPacket}, - OrigAcc), - %% Filter locally - case mongoose_hooks:filter_local_packet(LDstDomain, {OrigFrom, OrigTo, Acc0, OrigPacket}) of - {From, To, Acc, Packet} -> - Acc1 = mongoose_acc:update_stanza(#{from_jid => From, to_jid => To, element => Packet}, Acc), - mongoose_packet_handler:process(Handler, Acc1, From, To, Packet); - drop -> - mongoose_hooks:xmpp_stanza_dropped(mongoose_acc:host_type(Acc0), OrigFrom, - OrigTo, OrigPacket), - ok + LDstDomain = OrigTo#jid.lserver, + case mongoose_domain_api:get_host_type(LDstDomain) of + {error, not_found} -> + %% This can happen e.g. for external components + %% No handlers can be registered for filter_local_packet in this case + Acc = mongoose_acc:strip(#{lserver => LDstDomain, + from_jid => OrigFrom, + to_jid => OrigTo, + element => OrigPacket}, OrigAcc), + mongoose_packet_handler:process(Handler, Acc, OrigFrom, OrigTo, OrigPacket); + {ok, HostType} -> + Acc0 = mongoose_acc:strip(#{lserver => LDstDomain, + host_type => HostType, + from_jid => OrigFrom, + to_jid => OrigTo, + element => OrigPacket}, OrigAcc), + case mongoose_hooks:filter_local_packet({OrigFrom, OrigTo, Acc0, OrigPacket}) of + {From, To, Acc, Packet} -> + Acc1 = mongoose_acc:update_stanza(#{from_jid => From, + to_jid => To, + element => Packet}, Acc), + mongoose_packet_handler:process(Handler, Acc1, From, To, Packet); + drop -> + mongoose_hooks:xmpp_stanza_dropped(mongoose_acc:host_type(Acc0), OrigFrom, + OrigTo, OrigPacket), + ok + end end. diff --git a/src/mongoose_router_external.erl b/src/mongoose_router_external.erl index 564529fb57..e98f4af98c 100644 --- a/src/mongoose_router_external.erl +++ b/src/mongoose_router_external.erl @@ -25,7 +25,6 @@ route(From, To, Acc, Packet) -> [] -> {From, To, Acc, Packet}; [#external_component{handler = Handler}|_] -> %% may be multiple on various nodes - mongoose_local_delivery:do_route(From, To, Acc, Packet, - LDstDomain, Handler), + mongoose_local_delivery:do_route(From, To, Acc, Packet, Handler), done end. diff --git a/src/mongoose_router_external_localnode.erl b/src/mongoose_router_external_localnode.erl index e06f2bb3e2..94255ad725 100644 --- a/src/mongoose_router_external_localnode.erl +++ b/src/mongoose_router_external_localnode.erl @@ -27,7 +27,6 @@ route(From, To, Acc, Packet) -> [] -> {From, To, Acc, Packet}; [#external_component{handler = Handler}] -> - mongoose_local_delivery:do_route(From, To, Acc, Packet, - LDstDomain, Handler), + mongoose_local_delivery:do_route(From, To, Acc, Packet, Handler), done end. diff --git a/src/mongoose_router_localdomain.erl b/src/mongoose_router_localdomain.erl index d11cfb5ff1..9930df09f0 100644 --- a/src/mongoose_router_localdomain.erl +++ b/src/mongoose_router_localdomain.erl @@ -22,12 +22,9 @@ filter(From, To, Acc, Packet) -> route(From, To, Acc, Packet) -> LDstDomain = To#jid.lserver, - route_to_host(From, To, Acc, Packet, LDstDomain). - -route_to_host(From, To, Acc, Packet, Host) -> - case mnesia:dirty_read(route, Host) of + case mnesia:dirty_read(route, LDstDomain) of [] -> {From, To, Acc, Packet}; [#route{handler = Handler}] -> - mongoose_local_delivery:do_route(From, To, Acc, Packet, Host, Handler), + mongoose_local_delivery:do_route(From, To, Acc, Packet, Handler), done end. diff --git a/test/acc_SUITE.erl b/test/acc_SUITE.erl index bc235a2fd0..4673c443c3 100644 --- a/test/acc_SUITE.erl +++ b/test/acc_SUITE.erl @@ -32,8 +32,7 @@ groups() -> produce_iq_meta_automatically, strip, strip_with_params, - parse_with_cdata, - tries_to_get_host_type_if_it_is_not_provided + parse_with_cdata ] } ]. @@ -94,15 +93,15 @@ store_permanent_retrieve_and_delete_many(_C) -> [?assertEqual(V, mongoose_acc:get(ns, K, Acc2)) || {K, V} <- KV], NS = mongoose_acc:get(ns, Acc2), ?assertEqual(lists:sort(NS), lists:sort(KV)), - ?assertEqual(lists:sort(NK),lists:sort(mongoose_acc:get_permanent_keys(Acc2))), + ?assertEqual(lists:sort(NK), lists:sort(mongoose_acc:get_permanent_keys(Acc2))), Acc3 = mongoose_acc:delete_many(ns, [K || {K, _} <- KV], Acc2), [?assertError(_, mongoose_acc:get(ns, K, Acc3)) || {K, _} <- KV], ?assertEqual([], mongoose_acc:get(ns, Acc3)), - ?assertEqual([],mongoose_acc:get_permanent_keys(Acc3)), + ?assertEqual([], mongoose_acc:get_permanent_keys(Acc3)), Acc4 = mongoose_acc:delete(ns, Acc2), [?assertError(_, mongoose_acc:get(ns, K, Acc4)) || {K, _} <- KV], ?assertEqual([], mongoose_acc:get(ns, Acc4)), - ?assertEqual([],mongoose_acc:get_permanent_keys(Acc4)), + ?assertEqual([], mongoose_acc:get_permanent_keys(Acc4)), ok. init_from_element(_C) -> @@ -184,7 +183,7 @@ strip_with_params(_Config) -> %% strip stanza with params and check that new params are applied %% and non-permanent fields are missing NewServer = <<"test.", Server/binary>>, - NewHostType = <<"new ",HostType/binary>>, + NewHostType = <<"new ", HostType/binary>>, NewStanza = sample_stanza(), StripParams = #{lserver => NewServer, host_type => NewHostType, @@ -200,56 +199,6 @@ strip_with_params(_Config) -> ?assertEqual(NewServer, mongoose_acc:lserver(NAcc2)), ?assertEqual(NewHostType, mongoose_acc:host_type(NAcc2)). -tries_to_get_host_type_if_it_is_not_provided(_Config) -> - meck:new(mongoose_domain_api), - meck:expect(mongoose_domain_api, get_host_type, - fun - (<<"host1">>) -> {ok, <<"host 1">>}; - (<<"host2">>) -> {ok, <<"host 2">>}; - (_) -> {error, not_found} - end), - allocate_with_unknown_host_type_and_change_it_on_stripping(), - meck:reset(mongoose_domain_api), - allocate_with_known_host_type_and_change_it_on_stripping(), - meck:unload(mongoose_domain_api). - -allocate_with_known_host_type_and_change_it_on_stripping() -> - AccParams=#{location => ?LOCATION}, - StripParams = #{element => sample_stanza()}, - %% new with <<"host 1">> host type - Acc1 = mongoose_acc:new(AccParams#{lserver => <<"host1">>}), - ?assertEqual(<<"host 1">>, mongoose_acc:host_type(Acc1)), - ?assertEqual(1, meck:num_calls(mongoose_domain_api, get_host_type, [<<"host1">>])), - %% host type changes from <<"host 1">> to 'undefined' - Acc2 = mongoose_acc:strip(StripParams#{lserver => <<"unknown.host1">>},Acc1), - ?assertEqual(undefined, mongoose_acc:host_type(Acc2)), - ?assertEqual(1, meck:num_calls(mongoose_domain_api, get_host_type, [<<"unknown.host1">>])), - %% host type changes from <<"host 1">> to <> - Acc3 = mongoose_acc:strip(StripParams#{lserver => <<"host2">>},Acc1), - ?assertEqual(<<"host 2">>, mongoose_acc:host_type(Acc3)), - ?assertEqual(1, meck:num_calls(mongoose_domain_api, get_host_type, [<<"host2">>])), - %% check overall number of calls to mongoose_domain_api:get_host_type/1 - ?assertEqual(3, meck:num_calls(mongoose_domain_api, get_host_type, 1)). - -allocate_with_unknown_host_type_and_change_it_on_stripping() -> - AccParams=#{location => ?LOCATION}, - StripParams = #{element => sample_stanza()}, - %% new acc with 'undefined' host type - Acc1 = mongoose_acc:new(AccParams#{lserver => <<"unknown.host1">>}), - ?assertEqual(undefined, mongoose_acc:host_type(Acc1)), - ?assertEqual(1, meck:num_calls(mongoose_domain_api, get_host_type, [<<"unknown.host1">>])), - %% host type changes from 'undefined' to <<"host 1">> - Acc2 = mongoose_acc:strip(StripParams#{lserver => <<"host1">>},Acc1), - ?assertEqual(<<"host 1">>, mongoose_acc:host_type(Acc2)), - ?assertEqual(1, meck:num_calls(mongoose_domain_api, get_host_type, [<<"host1">>])), - %% host type changes from 'undefined' to `undefined` - Acc3 = mongoose_acc:strip(StripParams#{lserver => <<"unknown.host2">>},Acc1), - ?assertEqual(undefined, mongoose_acc:host_type(Acc3)), - ?assertEqual(1, meck:num_calls(mongoose_domain_api, get_host_type, [<<"unknown.host2">>])), - %% check overall number of calls to mongoose_domain_api:get_host_type/1 - ?assertEqual(3, meck:num_calls(mongoose_domain_api, get_host_type, 1)). - - sample_stanza() -> {xmlel, <<"iq">>, [{<<"xml:lang">>, <<"en">>}, diff --git a/test/auth_dummy_SUITE.erl b/test/auth_dummy_SUITE.erl index 992fed2518..3b261c0e64 100644 --- a/test/auth_dummy_SUITE.erl +++ b/test/auth_dummy_SUITE.erl @@ -48,7 +48,7 @@ ejabberd_auth_interfaces(_Config) -> [{mongoose_domain_api, []}, {ejabberd_auth_dummy, [passthrough]}, {ejabberd_config, []}, {mongoose_metrics, []}]], - meck:expect(mongoose_domain_api, get_host_type, + meck:expect(mongoose_domain_api, get_domain_host_type, fun(?DOMAIN) -> {ok, ?HOST_TYPE} end), meck:expect(ejabberd_config, get_local_option, fun({auth_method, ?HOST_TYPE}) -> dummy end), diff --git a/test/commands_SUITE.erl b/test/commands_SUITE.erl index 024bfb72be..e845238604 100644 --- a/test/commands_SUITE.erl +++ b/test/commands_SUITE.erl @@ -92,7 +92,7 @@ init_per_testcase(_, C) -> meck:new(ejabberd_auth_dummy, [non_strict]), meck:expect(ejabberd_auth_dummy, get_password_s, fun(_, _) -> <<"">> end), meck:new(mongoose_domain_api), - meck:expect(mongoose_domain_api, get_host_type, fun(H) -> {ok, H} end), + meck:expect(mongoose_domain_api, get_domain_host_type, fun(H) -> {ok, H} end), C. end_per_testcase(_, C) -> diff --git a/test/ejabberd_c2s_SUITE_mocks.erl b/test/ejabberd_c2s_SUITE_mocks.erl index 55db7d9896..70f9e0ff3f 100644 --- a/test/ejabberd_c2s_SUITE_mocks.erl +++ b/test/ejabberd_c2s_SUITE_mocks.erl @@ -56,7 +56,7 @@ setup() -> meck:expect(gen_mod, is_loaded, fun (_, _) -> true end), meck:new(mongoose_domain_api), - meck:expect(mongoose_domain_api, get_host_type, fun get_host_type/1). + meck:expect(mongoose_domain_api, get_domain_host_type, fun get_host_type/1). teardown() -> diff --git a/test/ejabberd_sm_SUITE.erl b/test/ejabberd_sm_SUITE.erl index 1a141195b9..b5db746d58 100644 --- a/test/ejabberd_sm_SUITE.erl +++ b/test/ejabberd_sm_SUITE.erl @@ -379,7 +379,7 @@ set_test_case_meck(MaxUserSessions) -> meck:new(ejabberd_hooks, []), meck:expect(ejabberd_hooks, run_for_host_type, fun(_, _, Acc, _) -> Acc end), meck:new(mongoose_domain_api, []), - meck:expect(mongoose_domain_api, get_host_type, fun(H) -> {ok, H} end). + meck:expect(mongoose_domain_api, get_domain_host_type, fun(H) -> {ok, H} end). set_test_case_meck_unique_count_crash(Backend) -> F = get_fun_for_unique_count(Backend), diff --git a/test/roster_SUITE.erl b/test/roster_SUITE.erl index 5cedb9f5bb..f60c03d100 100644 --- a/test/roster_SUITE.erl +++ b/test/roster_SUITE.erl @@ -51,7 +51,7 @@ init_per_testcase(_TC, C) -> meck:expect(gen_iq_handler, add_iq_handler, fun(_, _, _, _, _, _) -> ok end), meck:expect(gen_iq_handler, remove_iq_handler, fun(_, _, _) -> ok end), meck:new(mongoose_domain_api), - meck:expect(mongoose_domain_api, get_host_type, fun(H) -> {ok, H} end), + meck:expect(mongoose_domain_api, get_domain_host_type, fun(H) -> {ok, H} end), gen_mod:start(), gen_mod:start_module(host(), mod_roster, []), C.