diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 0195f92ee16..565ea0dd6af 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -54,7 +54,7 @@ %% Hooks callbacks --export([disco_local_features/1]). +-export([disco_local_features/3]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -62,7 +62,7 @@ -export([do_route/4]). --ignore_xref([disco_local_features/1, do_route/4, get_iq_callback/1, +-ignore_xref([do_route/4, get_iq_callback/1, process_iq_reply/4, start_link/0]). -include("mongoose.hrl"). @@ -241,12 +241,14 @@ register_host(Host) -> unregister_host(Host) -> gen_server:call(?MODULE, {unregister_host, Host}). --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{to_jid := #jid{lserver = LServer}, node := <<>>}) -> +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{to_jid := #jid{lserver = LServer}, node := <<>>}, _, _) -> Features = [Feature || {_, Feature} <- ets:lookup(?NSTABLE, LServer)], - mongoose_disco:add_features(Features, Acc); -disco_local_features(Acc) -> - Acc. + {ok, mongoose_disco:add_features(Features, Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. %%==================================================================== %% gen_server callbacks @@ -263,7 +265,7 @@ init([]) -> catch ets:new(?IQTABLE, [named_table, protected, {read_concurrency, true}]), catch ets:new(?NSTABLE, [named_table, bag, protected, {read_concurrency, true}]), catch ets:new(?IQRESPONSE, [named_table, public]), - ejabberd_hooks:add(hooks()), + gen_hook:add_handlers(hooks()), {ok, #state{}}. %%-------------------------------------------------------------------- @@ -337,7 +339,7 @@ handle_info(_Info, State) -> %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> - ejabberd_hooks:delete(hooks()). + gen_hook:delete_handlers(hooks()). %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} @@ -351,7 +353,7 @@ code_change(_OldVsn, State, _Extra) -> %%-------------------------------------------------------------------- hooks() -> - [{disco_local_features, HostType, ?MODULE, disco_local_features, 99} + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 99} || HostType <- ?ALL_HOST_TYPES]. -spec do_route(Acc :: mongoose_acc:t(), diff --git a/src/inbox/mod_inbox.erl b/src/inbox/mod_inbox.erl index bff15a8e4d8..f73cadc56fa 100644 --- a/src/inbox/mod_inbox.erl +++ b/src/inbox/mod_inbox.erl @@ -27,12 +27,12 @@ inbox_unread_count/2, remove_user/3, remove_domain/3, - disco_local_features/1 + disco_local_features/3 ]). -ignore_xref([ - disco_local_features/1, filter_local_packet/1, get_personal_data/3, - inbox_unread_count/2, remove_domain/3, remove_user/3, user_send_packet/4 + filter_local_packet/1, get_personal_data/3, inbox_unread_count/2, + remove_domain/3, remove_user/3, user_send_packet/4 ]). -export([process_inbox_boxes/1]). @@ -89,7 +89,8 @@ process_entry(#{remote_jid := RemJID, start(HostType, #{iqdisc := IQDisc, groupchat := MucTypes} = Opts) -> mod_inbox_backend:init(HostType, Opts), lists:member(muc, MucTypes) andalso mod_inbox_muc:start(HostType), - ejabberd_hooks:add(hooks(HostType)), + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)), gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_ESL_INBOX, ejabberd_sm, fun ?MODULE:process_iq/5, #{}, IQDisc), gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_ESL_INBOX_CONVERSATION, ejabberd_sm, @@ -101,7 +102,8 @@ start(HostType, #{iqdisc := IQDisc, groupchat := MucTypes} = Opts) -> stop(HostType) -> gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_ESL_INBOX, ejabberd_sm), gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_ESL_INBOX_CONVERSATION, ejabberd_sm), - ejabberd_hooks:delete(hooks(HostType)), + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)), stop_cleaner(HostType), mod_inbox_muc:stop(HostType), case mongoose_config:get_opt([{modules, HostType}, ?MODULE, backend]) of @@ -265,11 +267,13 @@ remove_domain(Acc, HostType, Domain) -> mod_inbox_backend:remove_domain(HostType, Domain), Acc. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := <<>>}) -> - mongoose_disco:add_features([?NS_ESL_INBOX], Acc); -disco_local_features(Acc) -> - Acc. +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := <<>>}, _, _) -> + {ok, mongoose_disco:add_features([?NS_ESL_INBOX], Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc} . -spec maybe_process_message(Acc :: mongoose_acc:t(), From :: jid:jid(), @@ -546,17 +550,19 @@ get_inbox_unread(undefined, Acc, To) -> {ok, Count} = mod_inbox_backend:get_inbox_unread(HostType, InboxEntryKey), mongoose_acc:set(inbox, unread_count, Count, Acc). -hooks(HostType) -> +legacy_hooks(HostType) -> [ {remove_user, HostType, ?MODULE, remove_user, 50}, {remove_domain, HostType, ?MODULE, remove_domain, 50}, {user_send_packet, HostType, ?MODULE, user_send_packet, 70}, {filter_local_packet, HostType, ?MODULE, filter_local_packet, 90}, {inbox_unread_count, HostType, ?MODULE, inbox_unread_count, 80}, - {get_personal_data, HostType, ?MODULE, get_personal_data, 50}, - {disco_local_features, HostType, ?MODULE, disco_local_features, 99} + {get_personal_data, HostType, ?MODULE, get_personal_data, 50} ]. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 99}]. + get_groupchat_types(HostType) -> gen_mod:get_module_opt(HostType, ?MODULE, groupchat). diff --git a/src/mam/mod_mam_pm.erl b/src/mam/mod_mam_pm.erl index 6588bb2e205..9b2a0eddf24 100644 --- a/src/mam/mod_mam_pm.erl +++ b/src/mam/mod_mam_pm.erl @@ -46,7 +46,7 @@ -export([start/2, stop/1, supported_features/0]). %% ejabberd handlers --export([disco_local_features/1, +-export([disco_local_features/3, process_mam_iq/5, user_send_packet/4, remove_user/3, @@ -64,9 +64,8 @@ -ignore_xref([archive_message_from_ct/1, archive_size/2, archive_size_with_host_type/3, delete_archive/2, - determine_amp_strategy/5, disco_local_features/1, filter_packet/1, - get_personal_data/3, remove_user/3, sm_filter_offline_message/4, - user_send_packet/4]). + determine_amp_strategy/5, filter_packet/1, get_personal_data/3, + remove_user/3, sm_filter_offline_message/4, user_send_packet/4]). -type host_type() :: mongooseim:host_type(). @@ -154,14 +153,16 @@ archive_id(Server, User) start(HostType, Opts) -> ?LOG_INFO(#{what => mam_starting, host_type => HostType}), ensure_metrics(HostType), - ejabberd_hooks:add(hooks(HostType)), + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)), add_iq_handlers(HostType, Opts), ok. -spec stop(host_type()) -> any(). stop(HostType) -> ?LOG_INFO(#{what => mam_stopping, host_type => HostType}), - ejabberd_hooks:delete(hooks(HostType)), + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)), remove_iq_handlers(HostType), ok. @@ -202,11 +203,13 @@ process_mam_iq(Acc, From, To, IQ, _Extra) -> {Acc, return_action_not_allowed_error_iq(IQ)} end. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{host_type := HostType, node := <<>>}) -> - mongoose_disco:add_features(features(?MODULE, HostType), Acc); -disco_local_features(Acc) -> - Acc. +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{host_type := HostType, node := <<>>}, _, _) -> + {ok, mongoose_disco:add_features(features(?MODULE, HostType), Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. %% @doc Handle an outgoing message. %% @@ -679,10 +682,9 @@ is_archivable_message(HostType, Dir, Packet) -> ArchiveChatMarkers = mod_mam_params:archive_chat_markers(?MODULE, HostType), erlang:apply(M, is_archivable_message, [?MODULE, Dir, Packet, ArchiveChatMarkers]). --spec hooks(jid:lserver()) -> [ejabberd_hooks:hook()]. -hooks(HostType) -> - [{disco_local_features, HostType, ?MODULE, disco_local_features, 99}, - {user_send_packet, HostType, ?MODULE, user_send_packet, 60}, +-spec legacy_hooks(jid:lserver()) -> [ejabberd_hooks:hook()]. +legacy_hooks(HostType) -> + [{user_send_packet, HostType, ?MODULE, user_send_packet, 60}, {rest_user_send_packet, HostType, ?MODULE, user_send_packet, 60}, {filter_local_packet, HostType, ?MODULE, filter_packet, 60}, {remove_user, HostType, ?MODULE, remove_user, 50}, @@ -692,6 +694,9 @@ hooks(HostType) -> {get_personal_data, HostType, ?MODULE, get_personal_data, 50} | mongoose_metrics_mam_hooks:get_mam_hooks(HostType)]. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 99}]. + add_iq_handlers(HostType, Opts) -> Component = ejabberd_sm, %% `parallel' is the only one recommended here. diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index 6563e4da3cb..a7b6f56c7e9 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -42,13 +42,13 @@ process_sm_iq/5, disco_local_items/1, disco_local_identity/1, - disco_local_features/1, + disco_local_features/3, disco_sm_items/1, disco_sm_identity/1, disco_sm_features/1, ping_command/4]). --ignore_xref([disco_local_features/1, disco_local_identity/1, disco_local_items/1, +-ignore_xref([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/5, process_sm_iq/5]). @@ -61,11 +61,13 @@ start(HostType, #{iqdisc := IQDisc}) -> [gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_COMMANDS, Component, Fn, #{}, IQDisc) || {Component, Fn} <- iq_handlers()], - ejabberd_hooks:add(hooks(HostType)). + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)). -spec stop(mongooseim:host_type()) -> ok. stop(HostType) -> - ejabberd_hooks:delete(hooks(HostType)), + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)), [gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_COMMANDS, Component) || {Component, _Fn} <- iq_handlers()], ok. @@ -74,15 +76,17 @@ iq_handlers() -> [{ejabberd_local, fun ?MODULE:process_local_iq/5}, {ejabberd_sm, fun ?MODULE:process_sm_iq/5}]. -hooks(HostType) -> +legacy_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(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 99}]. + %%% %%% config_spec %%% @@ -212,17 +216,19 @@ command_list_identity(Lang) -> %%------------------------------------------------------------------------- --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := <<>>}) -> - mongoose_disco:add_features([?NS_COMMANDS], Acc); -disco_local_features(Acc = #{node := ?NS_COMMANDS}) -> +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := <<>>}, _, _) -> + {ok, mongoose_disco:add_features([?NS_COMMANDS], Acc)}; +disco_local_features(Acc = #{node := ?NS_COMMANDS}, _, _) -> %% override all lesser features... - Acc#{result := []}; -disco_local_features(Acc = #{node := <<"ping">>}) -> + {ok, Acc#{result := []}}; +disco_local_features(Acc = #{node := <<"ping">>}, _, _) -> %% override all lesser features... - Acc#{result := [?NS_COMMANDS]}; -disco_local_features(Acc) -> - Acc. + {ok, Acc#{result := [?NS_COMMANDS]}}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. %%------------------------------------------------------------------------- diff --git a/src/mod_amp.erl b/src/mod_amp.erl index e6fb5cae59a..7b92d4d9b43 100644 --- a/src/mod_amp.erl +++ b/src/mod_amp.erl @@ -11,11 +11,11 @@ -export([start/2, stop/1, supported_features/0]). -export([run_initial_check/2, check_packet/2, - disco_local_features/1, + disco_local_features/3, c2s_stream_features/3 ]). --ignore_xref([c2s_stream_features/3, disco_local_features/1, run_initial_check/2]). +-ignore_xref([c2s_stream_features/3, run_initial_check/2]). -include("amp.hrl"). -include("mongoose.hrl"). @@ -29,23 +29,27 @@ -spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok. start(HostType, _Opts) -> - ejabberd_hooks:add(hooks(HostType)). + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)). -spec stop(mongooseim:host_type()) -> ok. stop(HostType) -> - ejabberd_hooks:delete(hooks(HostType)). + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)). -spec supported_features() -> [atom()]. supported_features() -> [dynamic_domains]. -hooks(HostType) -> +legacy_hooks(HostType) -> [{c2s_stream_features, HostType, ?MODULE, c2s_stream_features, 50}, - {disco_local_features, HostType, ?MODULE, disco_local_features, 99}, {c2s_preprocessing_hook, HostType, ?MODULE, run_initial_check, 10}, {amp_verify_support, HostType, ?AMP_RESOLVER, verify_support, 10}, {amp_check_condition, HostType, ?AMP_RESOLVER, check_condition, 10}, {amp_determine_strategy, HostType, ?AMP_STRATEGY, determine_strategy, 10}]. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 99}]. + %% API -spec run_initial_check(mongoose_acc:t(), ejabberd_c2s:state()) -> mongoose_acc:t(). @@ -64,12 +68,15 @@ check_packet(Acc, Event) -> Rules -> process_event(Acc, Rules, Event) end. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := Node}) -> - case amp_features(Node) of +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := Node}, _, _) -> + NewAcc = case amp_features(Node) of [] -> Acc; Features -> mongoose_disco:add_features(Features, Acc) - end. + end, + {ok, NewAcc}. -spec c2s_stream_features([exml:element()], mongooseim:host_type(), jid:lserver()) -> [exml:element()]. diff --git a/src/mod_auth_token.erl b/src/mod_auth_token.erl index 845a382485f..22114b725ba 100644 --- a/src/mod_auth_token.erl +++ b/src/mod_auth_token.erl @@ -17,7 +17,7 @@ %% Hook handlers -export([clean_tokens/3, - disco_local_features/1]). + disco_local_features/3]). %% gen_iq_handler handlers -export([process_iq/5]). @@ -50,7 +50,7 @@ -ignore_xref([ behaviour_info/1, clean_tokens/3, datetime_to_seconds/1, deserialize/1, - disco_local_features/1, expiry_datetime/3, get_key_for_host_type/2, process_iq/5, + expiry_datetime/3, get_key_for_host_type/2, process_iq/5, revoke/2, revoke_token_command/1, seconds_to_datetime/1, serialize/1, token/3, token_with_mac/2 ]). @@ -78,7 +78,8 @@ -spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok. start(HostType, #{iqdisc := IQDisc} = Opts) -> mod_auth_token_backend:start(HostType, Opts), - ejabberd_hooks:add(hooks(HostType)), + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)), gen_iq_handler:add_iq_handler_for_domain( HostType, ?NS_ESL_TOKEN_AUTH, ejabberd_sm, fun ?MODULE:process_iq/5, #{}, IQDisc), @@ -88,12 +89,15 @@ start(HostType, #{iqdisc := IQDisc} = Opts) -> -spec stop(mongooseim:host_type()) -> ok. stop(HostType) -> gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_ESL_TOKEN_AUTH, ejabberd_sm), - ejabberd_hooks:delete(hooks(HostType)), + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)), ok. +legacy_hooks(HostType) -> + [{remove_user, HostType, ?MODULE, clean_tokens, 50}]. + hooks(HostType) -> - [{remove_user, HostType, ?MODULE, clean_tokens, 50}, - {disco_local_features, HostType, ?MODULE, disco_local_features, 90}]. + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 90}]. -spec supported_features() -> [atom()]. supported_features() -> @@ -446,8 +450,10 @@ clean_tokens(Acc, User, Server) -> config_metrics(HostType) -> mongoose_module_metrics:opts_for_module(HostType, ?MODULE, [backend]). --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := <<>>}) -> - mongoose_disco:add_features([?NS_ESL_TOKEN_AUTH], Acc); -disco_local_features(Acc) -> - Acc. +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := <<>>}, _, _) -> + {ok, mongoose_disco:add_features([?NS_ESL_TOKEN_AUTH], Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 766db27a4c3..a1f99221583 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -14,10 +14,10 @@ -export([ process_iq_get/5, process_iq_set/4, - disco_local_features/1 + disco_local_features/3 ]). --ignore_xref([disco_local_features/1, process_iq_get/5, process_iq_set/4]). +-ignore_xref([process_iq_get/5, process_iq_set/4]). -include("jlib.hrl"). -include("mod_privacy.hrl"). @@ -26,11 +26,13 @@ -spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok. start(HostType, Opts) when is_map(Opts) -> - ejabberd_hooks:add(hooks(HostType)). + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)). -spec stop(mongooseim:host_type()) -> ok. stop(HostType) -> - ejabberd_hooks:delete(hooks(HostType)). + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)). deps(_HostType, Opts) -> [{mod_privacy, Opts, hard}]. @@ -42,16 +44,20 @@ supported_features() -> config_spec() -> mod_privacy:config_spec(). -hooks(HostType) -> - [{disco_local_features, HostType, ?MODULE, disco_local_features, 99}, - {privacy_iq_get, HostType, ?MODULE, process_iq_get, 50}, +legacy_hooks(HostType) -> + [{privacy_iq_get, HostType, ?MODULE, process_iq_get, 50}, {privacy_iq_set, HostType, ?MODULE, process_iq_set, 50}]. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := <<>>}) -> - mongoose_disco:add_features([?NS_BLOCKING], Acc); -disco_local_features(Acc) -> - Acc. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 99}]. + +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := <<>>}, _, _) -> + {ok, mongoose_disco:add_features([?NS_BLOCKING], Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. process_iq_get(Acc, _From = #jid{luser = LUser, lserver = LServer}, _, #iq{xmlns = ?NS_BLOCKING}, _) -> diff --git a/src/mod_caps.erl b/src/mod_caps.erl index c91b44e7355..7118f6c3363 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -36,7 +36,7 @@ -behaviour(mongoose_module_metrics). -export([read_caps/1, caps_stream_features/3, - disco_local_features/1, disco_local_identity/1, disco_info/1]). + disco_local_features/3, disco_local_identity/1, disco_info/1]). %% gen_mod callbacks -export([start/2, start_link/2, stop/1, config_spec/0, supported_features/0]). @@ -53,7 +53,7 @@ -export([delete_caps/1, make_disco_hash/2]). -ignore_xref([c2s_broadcast_recipients/5, c2s_filter_packet/5, c2s_presence_in/4, - caps_stream_features/3, delete_caps/1, disco_info/1, disco_local_features/1, + caps_stream_features/3, delete_caps/1, disco_info/1, disco_local_identity/1, make_disco_hash/2, read_caps/1, start_link/2, user_receive_packet/5, user_send_packet/4]). @@ -225,12 +225,15 @@ caps_stream_features(Acc, HostType, LServer) -> | Acc] end. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := Node}) -> - case is_valid_node(Node) of +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := Node}, _, _) -> + NewAcc = case is_valid_node(Node) of true -> Acc#{node := <<>>}; false -> Acc - end. + end, + {ok, NewAcc}. -spec disco_local_identity(mongoose_disco:identity_acc()) -> mongoose_disco:identity_acc(). disco_local_identity(Acc = #{node := Node}) -> @@ -357,7 +360,8 @@ init_db(mnesia) -> init([HostType, #{cache_size := MaxSize, cache_life_time := LifeTime}]) -> init_db(db_type(HostType)), cache_tab:new(caps_features, [{max_size, MaxSize}, {life_time, LifeTime}]), - ejabberd_hooks:add(hooks(HostType)), + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)), {ok, #state{host_type = HostType}}. -spec handle_call(term(), any(), state()) -> @@ -375,9 +379,10 @@ handle_info(_Info, State) -> {noreply, State}. -spec terminate(any(), state()) -> ok. terminate(_Reason, #state{host_type = HostType}) -> - ejabberd_hooks:delete(hooks(HostType)). + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)). -hooks(HostType) -> +legacy_hooks(HostType) -> [{c2s_presence_in, HostType, ?MODULE, c2s_presence_in, 75}, {c2s_filter_packet, HostType, ?MODULE, c2s_filter_packet, 75}, {c2s_broadcast_recipients, HostType, ?MODULE, c2s_broadcast_recipients, 75}, @@ -385,10 +390,12 @@ hooks(HostType) -> {user_receive_packet, HostType, ?MODULE, user_receive_packet, 75}, {c2s_stream_features, HostType, ?MODULE, caps_stream_features, 75}, {s2s_stream_features, HostType, ?MODULE, caps_stream_features, 75}, - {disco_local_features, HostType, ?MODULE, disco_local_features, 1}, {disco_local_identity, HostType, ?MODULE, disco_local_identity, 1}, {disco_info, HostType, ?MODULE, disco_info, 1}]. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 1}]. + -spec code_change(any(), state(), any()) -> {ok, state()}. code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 1547c495cec..8e228f174fd 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -38,7 +38,7 @@ is_carbon_copy/1]). %% Hooks --export([disco_local_features/1, +-export([disco_local_features/3, user_send_packet/4, user_receive_packet/5, iq_handler2/5, @@ -49,7 +49,7 @@ %% Tests -export([should_forward/3]). --ignore_xref([disco_local_features/1, is_carbon_copy/1, remove_connection/5, +-ignore_xref([is_carbon_copy/1, remove_connection/5, should_forward/3, user_receive_packet/5, user_send_packet/4]). -define(CC_KEY, 'cc'). @@ -77,34 +77,41 @@ is_carbon_copy(Packet) -> %% Default IQDisc is no_queue: %% executes disable/enable actions in the c2s process itself start(HostType, #{iqdisc := IQDisc}) -> - ejabberd_hooks:add(hooks(HostType)), + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)), gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_CC_2, ejabberd_sm, fun ?MODULE:iq_handler2/5, #{}, IQDisc), gen_iq_handler:add_iq_handler_for_domain(HostType, ?NS_CC_1, ejabberd_sm, fun ?MODULE:iq_handler1/5, #{}, IQDisc). stop(HostType) -> - ejabberd_hooks:delete(hooks(HostType)), + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)), gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_CC_1, ejabberd_sm), gen_iq_handler:remove_iq_handler_for_domain(HostType, ?NS_CC_2, ejabberd_sm), ok. -hooks(HostType) -> - [{disco_local_features, HostType, ?MODULE, disco_local_features, 99}, - {unset_presence_hook, HostType, ?MODULE, remove_connection, 10}, +legacy_hooks(HostType) -> + [{unset_presence_hook, HostType, ?MODULE, remove_connection, 10}, {user_send_packet, HostType, ?MODULE, user_send_packet, 89}, {user_receive_packet, HostType, ?MODULE, user_receive_packet, 89}]. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 99}]. + -spec config_spec() -> mongoose_config_spec:config_section(). config_spec() -> #section{items = #{<<"iqdisc">> => mongoose_config_spec:iqdisc()}, defaults = #{<<"iqdisc">> => no_queue}}. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := <<>>}) -> - mongoose_disco:add_features([?NS_CC_1, ?NS_CC_2, ?NS_CC_RULES], Acc); -disco_local_features(Acc) -> - Acc. +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := <<>>}, _, _) -> + NewAcc = mongoose_disco:add_features([?NS_CC_1, ?NS_CC_2, ?NS_CC_RULES], Acc), + {ok, NewAcc}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. iq_handler2(Acc, From, _To, IQ, _Extra) -> iq_handler(Acc, From, IQ, ?NS_CC_2). diff --git a/src/mod_disco.erl b/src/mod_disco.erl index c362b7e8cf5..eadefea3fd9 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -47,11 +47,11 @@ disco_sm_identity/1, disco_local_items/1, disco_sm_items/1, - disco_local_features/1, + disco_local_features/3, disco_info/1]). --ignore_xref([disco_info/1, disco_local_features/1, disco_local_identity/1, - disco_local_items/1, disco_sm_identity/1, disco_sm_items/1]). +-ignore_xref([disco_info/1, disco_local_identity/1, disco_local_items/1, + disco_sm_identity/1, disco_sm_items/1]). -include("mongoose.hrl"). -include("jlib.hrl"). @@ -64,23 +64,27 @@ start(HostType, #{iqdisc := IQDisc}) -> [gen_iq_handler:add_iq_handler_for_domain(HostType, NS, Component, Handler, #{}, IQDisc) || {Component, NS, Handler} <- iq_handlers()], - ejabberd_hooks:add(hooks(HostType)). + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)). -spec stop(mongooseim:host_type()) -> ok. stop(HostType) -> - ejabberd_hooks:delete(hooks(HostType)), + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)), [gen_iq_handler:remove_iq_handler_for_domain(HostType, NS, Component) || {Component, NS, _Handler} <- iq_handlers()], ok. -hooks(HostType) -> +legacy_hooks(HostType) -> [{disco_local_items, HostType, ?MODULE, disco_local_items, 100}, - {disco_local_features, HostType, ?MODULE, disco_local_features, 100}, {disco_local_identity, HostType, ?MODULE, disco_local_identity, 100}, {disco_sm_items, HostType, ?MODULE, disco_sm_items, 100}, {disco_sm_identity, HostType, ?MODULE, disco_sm_identity, 100}, {disco_info, HostType, ?MODULE, disco_info, 100}]. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 100}]. + iq_handlers() -> [{ejabberd_local, ?NS_DISCO_ITEMS, fun ?MODULE:process_local_iq_items/5}, {ejabberd_local, ?NS_DISCO_INFO, fun ?MODULE:process_local_iq_info/5}, @@ -227,11 +231,13 @@ disco_sm_items(Acc = #{to_jid := To, node := <<>>}) -> disco_sm_items(Acc) -> Acc. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := <<>>}) -> - mongoose_disco:add_features([<<"iq">>, <<"presence">>, <<"presence-invisible">>], Acc); -disco_local_features(Acc) -> - Acc. +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := <<>>}, _, _) -> + {ok, mongoose_disco:add_features([<<"iq">>, <<"presence">>, <<"presence-invisible">>], Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. %% @doc Support for: XEP-0157 Contact Addresses for XMPP Services -spec disco_info(mongoose_disco:info_acc()) -> mongoose_disco:info_acc(). diff --git a/src/mongoose_hooks.erl b/src/mongoose_hooks.erl index c60646178f9..959588183ec 100644 --- a/src/mongoose_hooks.erl +++ b/src/mongoose_hooks.erl @@ -1315,7 +1315,7 @@ disco_sm_items(Acc = #{host_type := HostType}) -> %%% offered by the server. -spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). disco_local_features(Acc = #{host_type := HostType}) -> - run_hook_for_host_type(disco_local_features, HostType, Acc, []). + run_hook_for_host_type(disco_local_features, HostType, Acc, #{}). %%% @doc `disco_sm_features' hook is called to get the features of the client %%% when a discovery IQ gets to session management. diff --git a/src/privacy/mod_privacy.erl b/src/privacy/mod_privacy.erl index 22dd3f5b9c2..c1691ba373c 100644 --- a/src/privacy/mod_privacy.erl +++ b/src/privacy/mod_privacy.erl @@ -43,7 +43,7 @@ remove_user/3, remove_domain/3, updated_list/3, - disco_local_features/1, + disco_local_features/3, remove_unused_backend_opts/1 ]). @@ -52,7 +52,7 @@ -ignore_xref([ behaviour_info/1, check_packet/5, get_user_list/3, process_iq_get/5, process_iq_set/4, remove_user/3, updated_list/3, - remove_user/3, remove_domain/3, disco_local_features/1]). + remove_user/3, remove_domain/3]). -include("jlib.hrl"). -include("mod_privacy.hrl"). @@ -73,11 +73,13 @@ -spec start(mongooseim:host_type(), gen_mod:module_opts()) -> ok. start(HostType, Opts) when is_map(Opts) -> mod_privacy_backend:init(HostType, Opts), - ejabberd_hooks:add(hooks(HostType)). + ejabberd_hooks:add(legacy_hooks(HostType)), + gen_hook:add_handlers(hooks(HostType)). -spec stop(mongooseim:host_type()) -> ok. stop(HostType) -> - ejabberd_hooks:delete(hooks(HostType)). + ejabberd_hooks:delete(legacy_hooks(HostType)), + gen_hook:delete_handlers(hooks(HostType)). config_spec() -> #section{ @@ -110,9 +112,8 @@ remove_unused_backend_opts(Opts) -> maps:remove(riak, Opts). supported_features() -> [dynamic_domains]. -hooks(HostType) -> +legacy_hooks(HostType) -> [ - {disco_local_features, HostType, ?MODULE, disco_local_features, 98}, {privacy_iq_get, HostType, ?MODULE, process_iq_get, 50}, {privacy_iq_set, HostType, ?MODULE, process_iq_set, 50}, {privacy_get_user_list, HostType, ?MODULE, get_user_list, 50}, @@ -123,15 +124,20 @@ hooks(HostType) -> {anonymous_purge_hook, HostType, ?MODULE, remove_user, 50} ]. +hooks(HostType) -> + [{disco_local_features, HostType, fun ?MODULE:disco_local_features/3, #{}, 98}]. + %% ------------------------------------------------------------------ %% Handlers %% ------------------------------------------------------------------ --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{node := <<>>}) -> - mongoose_disco:add_features([?NS_PRIVACY], Acc); -disco_local_features(Acc) -> - Acc. +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{node := <<>>}, _, _) -> + {ok, mongoose_disco:add_features([?NS_PRIVACY], Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. process_iq_get(Acc, _From = #jid{luser = LUser, lserver = LServer}, diff --git a/src/pubsub/mod_pubsub.erl b/src/pubsub/mod_pubsub.erl index aada409c59a..c7a9a552686 100644 --- a/src/pubsub/mod_pubsub.erl +++ b/src/pubsub/mod_pubsub.erl @@ -69,7 +69,7 @@ -export([presence_probe/4, caps_recognised/4, in_subscription/5, out_subscription/4, on_user_offline/5, remove_user/3, - disco_local_features/1, + disco_local_features/3, disco_sm_identity/1, disco_sm_features/1, disco_sm_items/1, handle_pep_authorization_response/1, handle_remote_hook/4]). @@ -120,7 +120,7 @@ {?MOD_PUBSUB_DB_BACKEND, set_subscription_opts, 4}, {?MOD_PUBSUB_DB_BACKEND, stop, 0}, affiliation_to_string/1, caps_recognised/4, create_node/7, default_host/0, - delete_item/4, delete_node/3, disco_local_features/1, disco_sm_features/1, + delete_item/4, delete_node/3, disco_sm_features/1, disco_sm_identity/1, disco_sm_items/1, extended_error/3, get_cached_item/2, get_item/3, get_items/2, get_personal_data/3, handle_pep_authorization_response/1, handle_remote_hook/4, host/2, in_subscription/5, iq_sm/4, node_action/4, node_call/4, @@ -398,7 +398,8 @@ init([ServerHost, Opts = #{host := SubdomainPattern}]) -> init_backend(ServerHost, Opts), Plugins = init_plugins(Host, ServerHost, Opts), - add_hooks(ServerHost, hooks()), + add_hooks(ServerHost, legacy_hooks()), + gen_hook:add_handlers(hooks(ServerHost)), case lists:member(?PEPNODE, Plugins) of true -> add_hooks(ServerHost, pep_hooks()), @@ -435,10 +436,9 @@ add_hooks(ServerHost, Hooks) -> delete_hooks(ServerHost, Hooks) -> [ ejabberd_hooks:delete(Hook, ServerHost, ?MODULE, F, Seq) || {Hook, F, Seq} <- Hooks ]. -hooks() -> +legacy_hooks() -> [ {sm_remove_connection_hook, on_user_offline, 75}, - {disco_local_features, disco_local_features, 75}, {presence_probe_hook, presence_probe, 80}, {roster_in_subscription, in_subscription, 50}, {roster_out_subscription, out_subscription, 50}, @@ -447,6 +447,9 @@ hooks() -> {get_personal_data, get_personal_data, 50} ]. +hooks(ServerHost) -> + [{disco_local_features, ServerHost, fun ?MODULE:disco_local_features/3, #{}, 75}]. + pep_hooks() -> [ {caps_recognised, caps_recognised, 80}, @@ -616,12 +619,15 @@ node_identity(Host, Type) -> false -> [] end. --spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc(). -disco_local_features(Acc = #{to_jid := #jid{lserver = LServer}, node := <<>>}) -> + +-spec disco_local_features(mongoose_disco:feature_acc(), + map(), + map()) -> {ok, mongoose_disco:feature_acc()}. +disco_local_features(Acc = #{to_jid := #jid{lserver = LServer}, node := <<>>}, _, _) -> Features = [?NS_PUBSUB | [feature(F) || F <- features(LServer, <<>>)]], - mongoose_disco:add_features(Features, Acc); -disco_local_features(Acc) -> - Acc. + {ok, mongoose_disco:add_features(Features, Acc)}; +disco_local_features(Acc, _, _) -> + {ok, Acc}. -spec disco_sm_identity(mongoose_disco:identity_acc()) -> mongoose_disco:identity_acc(). disco_sm_identity(Acc = #{from_jid := From, to_jid := To, node := Node}) -> @@ -928,7 +934,8 @@ terminate(_Reason, #state{host = Host, server_host = ServerHost, delete_pep_iq_handlers(ServerHost); false -> ok end, - delete_hooks(ServerHost, hooks()), + delete_hooks(ServerHost, legacy_hooks()), + gen_hook:delete_handlers(hooks(ServerHost)), case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of undefined -> ?LOG_ERROR(#{what => pubsub_process_is_dead,