./ct_report/coverage/mongoose_hooks.COVER.html

1 %%% @doc Hooks wrapper providing clear specifications for a hook caller.
2 %%%
3 %%% Every hook has its own function in this module with specs as accurate as
4 %%% possible. This helps to have a static analysis of the hooks callers to
5 %%% make sure they pass the expected arguments.
6 -module(mongoose_hooks).
7
8 -include("mod_privacy.hrl").
9 -include("mongoose.hrl").
10
11 -export([adhoc_local_commands/4,
12 adhoc_sm_commands/4,
13 anonymous_purge/3,
14 auth_failed/3,
15 does_user_exist/3,
16 failed_to_store_message/1,
17 filter_local_packet/1,
18 filter_packet/1,
19 inbox_unread_count/3,
20 extend_inbox_result/3,
21 get_key/2,
22 packet_to_component/3,
23 presence_probe/5,
24 push_notifications/4,
25 register_subhost/2,
26 register_user/3,
27 remove_user/3,
28 resend_offline_messages/2,
29 session_cleanup/5,
30 sessions_cleanup/2,
31 set_vcard/3,
32 unacknowledged_message/2,
33 filter_unacknowledged_messages/3,
34 unregister_subhost/1,
35 user_available/2,
36 user_ping_response/5,
37 vcard_set/4,
38 xmpp_send_element/3,
39 xmpp_stanza_dropped/4]).
40
41 %% sasl2 handlers
42 -export([sasl2_stream_features/2,
43 bind2_stream_features/2,
44 bind2_enable_features/3,
45 sasl2_start/3,
46 sasl2_success/3]).
47
48 -export([get_pep_recipients/2,
49 filter_pep_recipient/3,
50 c2s_stream_features/3,
51 check_bl_c2s/1,
52 forbidden_session/3,
53 session_opening_allowed_for_user/2]).
54
55 -export([privacy_check_packet/5,
56 privacy_get_user_list/2,
57 privacy_iq_get/6,
58 privacy_iq_set/5,
59 privacy_updated_list/3,
60 privacy_list_push/5]).
61
62 -export([offline_groupchat_message/4,
63 offline_message/4,
64 set_presence/3,
65 sm_filter_offline_message/4,
66 sm_register_connection/4,
67 sm_remove_connection/5,
68 unset_presence/3,
69 xmpp_bounce_message/1]).
70
71 -export([roster_get/3,
72 roster_get_jid_info/3,
73 roster_get_subscription_lists/3,
74 roster_get_versioning_feature/1,
75 roster_groups/1,
76 roster_in_subscription/5,
77 roster_out_subscription/4,
78 roster_process_item/3,
79 roster_push/3,
80 roster_set/4]).
81
82 -export([is_muc_room_owner/4,
83 can_access_identity/3,
84 can_access_room/4,
85 acc_room_affiliations/2,
86 room_new_affiliations/4,
87 room_exists/2]).
88
89 -export([mam_archive_id/2,
90 mam_archive_size/3,
91 mam_get_behaviour/4,
92 mam_set_prefs/6,
93 mam_get_prefs/4,
94 mam_remove_archive/3,
95 mam_lookup_messages/2,
96 mam_archive_message/2,
97 mam_archive_sync/1,
98 mam_retraction/3]).
99
100 -export([mam_muc_archive_id/2,
101 mam_muc_archive_size/3,
102 mam_muc_get_behaviour/4,
103 mam_muc_set_prefs/6,
104 mam_muc_get_prefs/4,
105 mam_muc_remove_archive/3,
106 mam_muc_lookup_messages/2,
107 mam_muc_archive_message/2,
108 mam_muc_archive_sync/1,
109 mam_muc_retraction/3]).
110
111 -export([get_mam_pm_gdpr_data/2,
112 get_mam_muc_gdpr_data/2,
113 get_personal_data/2]).
114
115 -export([s2s_allow_host/2,
116 s2s_receive_packet/1,
117 s2s_stream_features/2,
118 s2s_send_packet/4]).
119
120 -export([disco_local_identity/1,
121 disco_sm_identity/1,
122 disco_local_items/1,
123 disco_sm_items/1,
124 disco_local_features/1,
125 disco_sm_features/1,
126 disco_muc_features/1,
127 disco_info/1]).
128
129 -export([amp_check_condition/3,
130 amp_determine_strategy/5,
131 amp_verify_support/2]).
132
133 -export([filter_room_packet/3,
134 forget_room/3,
135 invitation_sent/6,
136 join_room/5,
137 leave_room/5,
138 room_packet/5,
139 update_inbox_for_muc/2]).
140
141 -export([caps_recognised/4]).
142
143 -export([mod_global_distrib_known_recipient/4,
144 mod_global_distrib_unknown_recipient/2]).
145
146 -export([remove_domain/2,
147 node_cleanup/1,
148 node_cleanup_for_host_type/2]).
149
150 -ignore_xref([remove_domain/2]).
151 -ignore_xref([mam_archive_sync/1, mam_muc_archive_sync/1]).
152
153 %% Just a map, used by some hooks as a first argument.
154 %% Not mongoose_acc:t().
155 -type simple_acc() :: #{}.
156 -export_type([simple_acc/0]).
157
158 -type filter_packet_acc() :: {From :: jid:jid(),
159 To :: jid:jid(),
160 Acc :: mongoose_acc:t(),
161 Packet :: exml:element()}.
162 -export_type([filter_packet_acc/0]).
163
164 -spec adhoc_local_commands(HostType, From, To, AdhocRequest) -> Result when
165 HostType :: mongooseim:host_type(),
166 From :: jid:jid(),
167 To :: jid:jid(),
168 AdhocRequest :: adhoc:request(),
169 Result :: mod_adhoc:command_hook_acc().
170 adhoc_local_commands(HostType, From, To, AdhocRequest) ->
171 1 Params = #{from => From, to => To, adhoc_request => AdhocRequest},
172 1 run_hook_for_host_type(adhoc_local_commands, HostType, empty, Params).
173
174 -spec adhoc_sm_commands(HostType, From, To, AdhocRequest) -> Result when
175 HostType :: mongooseim:host_type(),
176 From :: jid:jid(),
177 To :: jid:jid(),
178 AdhocRequest :: adhoc:request(),
179 Result :: mod_adhoc:command_hook_acc().
180 adhoc_sm_commands(HostType, From, To, AdhocRequest) ->
181
:-(
Params = #{from => From, to => To, request => AdhocRequest},
182
:-(
run_hook_for_host_type(adhoc_sm_commands, HostType, empty, Params).
183
184 %%% @doc The `anonymous_purge' hook is called when anonymous user's data is removed.
185 -spec anonymous_purge(LServer, Acc, LUser) -> Result when
186 LServer :: jid:lserver(),
187 Acc :: mongoose_acc:t(),
188 LUser :: jid:user(),
189 Result :: mongoose_acc:t().
190 anonymous_purge(LServer, Acc, LUser) ->
191 4 Jid = jid:make_bare(LUser, LServer),
192 4 Params = #{jid => Jid},
193 4 HostType = mongoose_acc:host_type(Acc),
194 4 run_hook_for_host_type(anonymous_purge, HostType, Acc, Params).
195
196 -spec auth_failed(HostType, Server, Username) -> Result when
197 HostType :: mongooseim:host_type(),
198 Server :: jid:server(),
199 Username :: jid:user() | undefined,
200 Result :: ok.
201 auth_failed(HostType, Server, Username) ->
202 65 Params = #{username => Username, server => Server},
203 65 run_hook_for_host_type(auth_failed, HostType, ok, Params).
204
205 -spec does_user_exist(HostType, Jid, RequestType) -> Result when
206 HostType :: mongooseim:host_type(),
207 Jid :: jid:jid(),
208 RequestType :: ejabberd_auth:exist_type(),
209 Result :: boolean().
210 does_user_exist(HostType, Jid, RequestType) ->
211 14132 Params = #{jid => Jid, request_type => RequestType},
212 14132 run_hook_for_host_type(does_user_exist, HostType, false, Params).
213
214 -spec remove_domain(HostType, Domain) -> Result when
215 HostType :: mongooseim:host_type(),
216 Domain :: jid:lserver(),
217 Result :: mongoose_domain_api:remove_domain_acc().
218 remove_domain(HostType, Domain) ->
219 42 Params = #{domain => Domain},
220 42 run_hook_for_host_type(remove_domain, HostType, #{failed => []}, Params).
221
222 -spec node_cleanup(Node :: node()) -> Acc :: map().
223 node_cleanup(Node) ->
224 9 Params = #{node => Node},
225 9 run_global_hook(node_cleanup, #{}, Params).
226
227 -spec node_cleanup_for_host_type(HostType :: mongooseim:host_type(), Node :: node()) -> Acc :: map().
228 node_cleanup_for_host_type(HostType, Node) ->
229 44 Params = #{node => Node},
230 44 run_hook_for_host_type(node_cleanup_for_host_type, HostType, #{}, Params).
231
232 -spec failed_to_store_message(Acc) -> Result when
233 Acc :: mongoose_acc:t(),
234 Result :: mongoose_acc:t().
235 failed_to_store_message(Acc) ->
236 12 HostType = mongoose_acc:host_type(Acc),
237 12 run_hook_for_host_type(failed_to_store_message, HostType, Acc, #{}).
238
239 %%% @doc The `filter_local_packet' hook is called to filter out
240 %%% stanzas routed with `mongoose_local_delivery'.
241 -spec filter_local_packet(FilterAcc) -> Result when
242 FilterAcc :: filter_packet_acc(),
243 Result :: drop | filter_packet_acc().
244 filter_local_packet(FilterAcc = {_From, _To, Acc, _Packet}) ->
245 47834 HostType = mongoose_acc:host_type(Acc),
246 47834 run_hook_for_host_type(filter_local_packet, HostType, FilterAcc, #{}).
247
248 %%% @doc The `filter_packet' hook is called to filter out
249 %%% stanzas routed with `mongoose_router_global'.
250 -spec filter_packet(Acc) -> Result when
251 Acc :: filter_packet_acc(),
252 Result :: drop | filter_packet_acc().
253 filter_packet(Acc) ->
254 47879 run_global_hook(filter_packet, Acc, #{}).
255
256 %%% @doc The `inbox_unread_count' hook is called to get the number
257 %%% of unread messages in the inbox for a user.
258 -spec inbox_unread_count(LServer, Acc, User) -> Result when
259 LServer :: jid:lserver(),
260 Acc :: mongoose_acc:t(),
261 User :: jid:jid(),
262 Result :: mongoose_acc:t().
263 inbox_unread_count(LServer, Acc, User) ->
264
:-(
Params = #{user => User},
265
:-(
run_hook_for_host_type(inbox_unread_count, LServer, Acc, Params).
266
267 -spec extend_inbox_result(mongoose_acc:t(), [mod_inbox:inbox_res()], jlib:iq()) ->
268 [mod_inbox:inbox_res()].
269 extend_inbox_result(MongooseAcc, InboxResults, IQ) ->
270 1076 HostType = mongoose_acc:host_type(MongooseAcc),
271 1076 HookParams = #{mongoose_acc => MongooseAcc, iq => IQ},
272 1076 run_hook_for_host_type(extend_inbox_result, HostType, InboxResults, HookParams).
273
274 %%% @doc The `get_key' hook is called to extract a key from `mod_keystore'.
275 -spec get_key(HostType, KeyName) -> Result when
276 HostType :: mongooseim:host_type(),
277 KeyName :: atom(),
278 Result :: mod_keystore:key_list().
279 get_key(HostType, KeyName) ->
280 51 Params = #{key_id => {KeyName, HostType}},
281 51 run_hook_for_host_type(get_key, HostType, [], Params).
282
283 -spec packet_to_component(Acc, From, To) -> Result when
284 Acc :: mongoose_acc:t(),
285 From :: jid:jid(),
286 To :: jid:jid(),
287 Result :: mongoose_acc:t().
288 packet_to_component(Acc, From, To) ->
289
:-(
Params = #{from => From, to => To},
290
:-(
run_global_hook(packet_to_component, Acc, Params).
291
292 -spec presence_probe(HostType, Acc, From, To, Pid) -> Result when
293 HostType :: mongooseim:host_type(),
294 Acc :: mongoose_acc:t(),
295 From :: jid:jid(),
296 To :: jid:jid(),
297 Pid :: pid(),
298 Result :: mongoose_acc:t().
299 presence_probe(HostType, Acc, From, To, Pid) ->
300 5470 Params = #{from => From, to => To, pid => Pid},
301 5470 run_hook_for_host_type(presence_probe, HostType, Acc, Params).
302
303 %%% @doc The `push_notifications' hook is called to push notifications.
304 -spec push_notifications(HostType, Acc, NotificationForms, Options) -> Result when
305 HostType :: mongooseim:host_type(),
306 Acc :: ok | mongoose_acc:t(),
307 NotificationForms :: [#{binary() => binary()}],
308 Options :: #{binary() => binary()},
309 Result :: ok | {error, any()}.
310 push_notifications(HostType, Acc, NotificationForms, Options) ->
311
:-(
Params = #{options => Options, notification_forms => NotificationForms},
312
:-(
run_hook_for_host_type(push_notifications, HostType, Acc, Params).
313
314 %%% @doc The `register_subhost' hook is called when a component
315 %%% is registered for ejabberd_router or a subdomain is added to mongoose_subdomain_core.
316 -spec register_subhost(LDomain, IsHidden) -> Result when
317 LDomain :: binary(),
318 IsHidden :: boolean(),
319 Result :: any().
320 register_subhost(LDomain, IsHidden) ->
321 707 Params = #{ldomain => LDomain, is_hidden => IsHidden},
322 707 run_global_hook(register_subhost, ok, Params).
323
324 %%% @doc The `register_user' hook is called when a user is successfully
325 %%% registered in an authentication backend.
326 -spec register_user(HostType, LServer, LUser) -> Result when
327 HostType :: mongooseim:host_type(),
328 LServer :: jid:lserver(),
329 LUser :: jid:luser(),
330 Result :: any().
331 register_user(HostType, LServer, LUser) ->
332 5591 Jid = jid:make_bare(LUser, LServer),
333 5591 Params = #{jid => Jid},
334 5591 run_hook_for_host_type(register_user, HostType, ok, Params).
335
336 %%% @doc The `remove_user' hook is called when a user is removed.
337 -spec remove_user(Acc, LServer, LUser) -> Result when
338 Acc :: mongoose_acc:t(),
339 LServer :: jid:lserver(),
340 LUser :: jid:luser(),
341 Result :: mongoose_acc:t().
342 remove_user(Acc, LServer, LUser) ->
343 5565 Jid = jid:make_bare(LUser, LServer),
344 5565 Params = #{jid => Jid},
345 5565 HostType = mongoose_acc:host_type(Acc),
346 5565 run_hook_for_host_type(remove_user, HostType, Acc, Params).
347
348 -spec resend_offline_messages(Acc, JID) -> Result when
349 Acc :: mongoose_acc:t(),
350 JID :: jid:jid(),
351 Result :: mongoose_acc:t().
352 resend_offline_messages(Acc, JID) ->
353 5278 Params = #{jid => JID},
354 5278 HostType = mongoose_acc:host_type(Acc),
355 5278 run_hook_for_host_type(resend_offline_messages, HostType, Acc, Params).
356
357 %%% @doc The `session_cleanup' hook is called when sm backend cleans up a user's session.
358 -spec session_cleanup(Server, Acc, User, Resource, SID) -> Result when
359 Server :: jid:server(),
360 Acc :: mongoose_acc:t(),
361 User :: jid:user(),
362 Resource :: jid:resource(),
363 SID :: ejabberd_sm:sid(),
364 Result :: mongoose_acc:t().
365 session_cleanup(Server, Acc, User, Resource, SID) ->
366 345 JID = jid:make(User, Server, Resource),
367 345 Params = #{jid => JID, sid => SID},
368 345 HostType = mongoose_acc:host_type(Acc),
369 345 run_hook_for_host_type(session_cleanup, HostType, Acc, Params).
370
371 -spec sessions_cleanup(mongooseim:host_type(), [ejabberd_sm:session()]) -> map().
372 sessions_cleanup(HostType, Sessions) ->
373 1 Params = #{sessions => Sessions},
374 1 run_hook_for_host_type(sessions_cleanup, HostType, #{host_type => HostType}, Params).
375
376 %%% @doc The `set_vcard' hook is called when the caller wants to set the VCard.
377 -spec set_vcard(HostType, UserJID, VCard) -> Result when
378 HostType :: mongooseim:host_type(),
379 UserJID :: jid:jid(),
380 VCard :: exml:element(),
381 Result :: ok | {error, any()}.
382 set_vcard(HostType, UserJID, VCard) ->
383 1 Params = #{user => UserJID, vcard => VCard},
384 1 run_hook_for_host_type(set_vcard, HostType, {error, no_handler_defined}, Params).
385
386 -spec unacknowledged_message(Acc, JID) -> Result when
387 Acc :: mongoose_acc:t(),
388 JID :: jid:jid(),
389 Result :: mongoose_acc:t().
390 unacknowledged_message(Acc, JID) ->
391 97 HostType = mongoose_acc:host_type(Acc),
392 97 Params = #{jid => JID},
393 97 run_hook_for_host_type(unacknowledged_message, HostType, Acc, Params).
394
395 -spec filter_unacknowledged_messages(HostType, Jid, Buffer) -> Result when
396 HostType :: mongooseim:host_type(),
397 Jid :: jid:jid(),
398 Buffer :: [mongoose_acc:t()],
399 Result :: [mongoose_acc:t()].
400 filter_unacknowledged_messages(HostType, Jid, Buffer) ->
401 86 run_hook_for_host_type(filter_unacknowledged_messages, HostType, Buffer, #{jid => Jid}).
402
403 %%% @doc The `unregister_subhost' hook is called when a component
404 %%% is unregistered from ejabberd_router or a subdomain is removed from mongoose_subdomain_core.
405 -spec unregister_subhost(LDomain) -> Result when
406 LDomain :: binary(),
407 Result :: any().
408 unregister_subhost(LDomain) ->
409 707 Params = #{ldomain => LDomain},
410 707 run_global_hook(unregister_subhost, ok, Params).
411
412 -spec user_available(Acc, JID) -> Result when
413 Acc :: mongoose_acc:t(),
414 JID :: jid:jid(),
415 Result :: mongoose_acc:t().
416 user_available(Acc, JID) ->
417 5278 Params = #{jid => JID},
418 5278 HostType = mongoose_acc:host_type(Acc),
419 5278 run_hook_for_host_type(user_available, HostType, Acc, Params).
420
421 %%% @doc The `user_ping_response' hook is called when a user responds to a ping, or times out
422 -spec user_ping_response(HostType, Acc, JID, Response, TDelta) -> Result when
423 HostType :: mongooseim:host_type(),
424 Acc :: simple_acc(),
425 JID :: jid:jid(),
426 Response :: timeout | exml:element(),
427 TDelta :: non_neg_integer(),
428 Result :: simple_acc().
429 user_ping_response(HostType, Acc, JID, Response, TDelta) ->
430 16 Params = #{jid => JID, response => Response, time_delta => TDelta},
431 16 run_hook_for_host_type(user_ping_response, HostType, Acc, Params).
432
433 %%% @doc The `vcard_set' hook is called to inform that the vcard
434 %%% has been set in mod_vcard backend.
435 -spec vcard_set(HostType, Server, LUser, VCard) -> Result when
436 HostType :: mongooseim:host_type(),
437 Server :: jid:server(),
438 LUser :: jid:luser(),
439 VCard :: exml:element(),
440 Result :: any().
441 vcard_set(HostType, Server, LUser, VCard) ->
442 35 JID = jid:make_bare(LUser, Server),
443 35 Params = #{jid => JID, vcard => VCard},
444 35 run_hook_for_host_type(vcard_set, HostType, ok, Params).
445
446 -spec xmpp_send_element(HostType, Acc, El) -> Result when
447 HostType :: mongooseim:host_type(),
448 Acc :: mongoose_acc:t(),
449 El :: exml:element(),
450 Result :: mongoose_acc:t().
451 xmpp_send_element(HostType, Acc, El) ->
452 59472 Params = #{el => El},
453 59472 run_hook_for_host_type(xmpp_send_element, HostType, Acc, Params).
454
455 %%% @doc The `xmpp_stanza_dropped' hook is called to inform that
456 %%% an xmpp stanza has been dropped.
457 -spec xmpp_stanza_dropped(Acc, From, To, Packet) -> Result when
458 Acc :: mongoose_acc:t(),
459 From :: jid:jid(),
460 To :: jid:jid(),
461 Packet :: exml:element(),
462 Result :: any().
463 xmpp_stanza_dropped(Acc, From, To, Packet) ->
464 73 Params = #{from => From, to => To, packet => Packet},
465 73 HostType = mongoose_acc:host_type(Acc),
466 73 run_hook_for_host_type(xmpp_stanza_dropped, HostType, Acc, Params).
467
468 %% C2S related hooks
469
470 -spec get_pep_recipients(C2SData, Feature) -> Result when
471 C2SData :: mongoose_c2s:data(),
472 Feature :: binary(),
473 Result :: [jid:simple_jid()].
474 get_pep_recipients(C2SData, Feature) ->
475
:-(
Params = #{c2s_data => C2SData, feature => Feature},
476
:-(
HostType = mongoose_c2s:get_host_type(C2SData),
477
:-(
run_hook_for_host_type(get_pep_recipients, HostType, [], Params).
478
479 -spec filter_pep_recipient(C2SData, Feature, To) -> Result when
480 C2SData :: mongoose_c2s:data(),
481 Feature :: binary(),
482 To :: jid:jid(),
483 Result :: boolean().
484 filter_pep_recipient(C2SData, Feature, To) ->
485
:-(
Params = #{c2s_data => C2SData, feature => Feature, to => To},
486
:-(
HostType = mongoose_c2s:get_host_type(C2SData),
487
:-(
run_hook_for_host_type(filter_pep_recipient, HostType, true, Params).
488
489 -spec c2s_stream_features(HostType, Params, InitialFeatures) -> Result when
490 HostType :: mongooseim:host_type(),
491 Params :: #{c2s_data := mongoose_c2s:data(), lserver := jid:lserver()},
492 InitialFeatures :: [exml:element()],
493 Result :: [exml:element()].
494 c2s_stream_features(HostType, Params, InitialFeatures) ->
495 12313 run_hook_for_host_type(c2s_stream_features, HostType, InitialFeatures, Params).
496
497 -spec sasl2_stream_features(C2SData, InitialFeatures) -> Result when
498 C2SData :: mongoose_c2s:data(),
499 InitialFeatures :: [exml:element()],
500 Result :: [exml:element()].
501 sasl2_stream_features(C2SData, InitialFeatures) ->
502 29 Params = #{c2s_data => C2SData},
503 29 HostType = mongoose_c2s:get_host_type(C2SData),
504 29 run_hook_for_host_type(sasl2_stream_features, HostType, InitialFeatures, Params).
505
506 -spec bind2_stream_features(C2SData, InitialFeatures) -> Result when
507 C2SData :: mongoose_c2s:data(),
508 InitialFeatures :: [exml:element()],
509 Result :: [exml:element()].
510 bind2_stream_features(C2SData, InitialFeatures) ->
511 29 Params = #{c2s_data => C2SData},
512 29 HostType = mongoose_c2s:get_host_type(C2SData),
513 29 run_hook_for_host_type(bind2_stream_features, HostType, InitialFeatures, Params).
514
515 -spec bind2_enable_features(HostType, Acc, Params) -> Result when
516 HostType :: mongooseim:host_type(),
517 Acc :: mongoose_acc:t(),
518 Params :: mod_sasl2:c2s_state_data(),
519 Result :: mongoose_acc:t().
520 bind2_enable_features(HostType, Acc, Params) ->
521 10 run_hook_for_host_type(bind2_enable_features, HostType, Acc, Params).
522
523 %% This hook will cache in the accumulator all the requests from sasl2 inlined features
524 -spec sasl2_start(HostType, Acc, Element) -> Result when
525 HostType :: mongooseim:host_type(),
526 Acc :: mongoose_acc:t(),
527 Element :: exml:element(),
528 Result :: mongoose_acc:t().
529 sasl2_start(HostType, Acc, Element) ->
530 24 Params = #{stanza => Element},
531 24 run_hook_for_host_type(sasl2_start, HostType, Acc, Params).
532
533 %% If SASL authentication is successful, inline features can be triggered
534 -spec sasl2_success(HostType, Acc, Params) -> Result when
535 HostType :: mongooseim:host_type(),
536 Acc :: mongoose_acc:t(),
537 Params :: mod_sasl2:c2s_state_data(),
538 Result :: mongoose_acc:t().
539 sasl2_success(HostType, Acc, Params) ->
540 20 run_hook_for_host_type(sasl2_success, HostType, Acc, Params).
541
542 -spec check_bl_c2s(IP) -> Result when
543 IP :: inet:ip_address(),
544 Result :: boolean().
545 check_bl_c2s(IP) ->
546 6983 Params = #{ip => IP},
547 6983 run_global_hook(check_bl_c2s, false, Params).
548
549 -spec forbidden_session(HostType, Acc, JID) -> Result when
550 HostType :: mongooseim:host_type(),
551 Acc :: mongoose_acc:t(),
552 JID :: jid:jid(),
553 Result :: mongoose_acc:t().
554 forbidden_session(HostType, Acc, JID) ->
555 2 Params = #{jid => JID},
556 2 run_hook_for_host_type(forbidden_session, HostType, Acc, Params).
557
558 -spec session_opening_allowed_for_user(HostType, JID) -> Result when
559 HostType :: mongooseim:host_type(),
560 JID :: jid:jid(),
561 Result :: allow | any(). %% anything else than 'allow' is interpreted
562 %% as not allowed
563 session_opening_allowed_for_user(HostType, JID) ->
564 5858 Params = #{jid => JID},
565 5858 run_hook_for_host_type(session_opening_allowed_for_user, HostType, allow, Params).
566
567 %% Privacy related hooks
568
569 -spec privacy_check_packet(Acc, JID, PrivacyList,
570 FromToNameType, Dir) -> Result when
571 Acc :: mongoose_acc:t(), JID :: jid:jid(),
572 PrivacyList :: mongoose_privacy:userlist(),
573 FromToNameType :: {jid:jid(), jid:jid(), binary(), binary()},
574 Dir :: in | out,
575 Result :: mongoose_acc:t().
576 privacy_check_packet(Acc, JID, PrivacyList, FromToNameType, Dir) ->
577 3455 Params = #{jid => JID, privacy_list => PrivacyList,
578 from_to_name_type => FromToNameType, dir => Dir},
579 3455 HostType = mongoose_acc:host_type(Acc),
580 3455 AccWithRes = mongoose_acc:set(hook, result, allow, Acc),
581 3455 run_hook_for_host_type(privacy_check_packet, HostType, AccWithRes, Params).
582
583 -spec privacy_get_user_list(HostType, JID) -> Result when
584 HostType :: mongooseim:host_type(),
585 JID :: jid:jid(),
586 Result :: mongoose_privacy:userlist().
587 privacy_get_user_list(HostType, JID) ->
588 3292 Params = #{jid => JID},
589 3292 run_hook_for_host_type(privacy_get_user_list, HostType, #userlist{}, Params).
590
591 -spec privacy_iq_get(HostType, Acc, From, To, IQ, PrivList) -> Result when
592 HostType :: mongooseim:host_type(),
593 Acc :: mongoose_acc:t(),
594 From :: jid:jid(),
595 To :: jid:jid(),
596 IQ :: jlib:iq(),
597 PrivList :: mongoose_privacy:userlist(),
598 Result :: mongoose_acc:t().
599 privacy_iq_get(HostType, Acc, From, To, IQ, PrivList) ->
600 62 Params = #{from => From, to => To, iq => IQ, priv_list => PrivList},
601 62 run_hook_for_host_type(privacy_iq_get, HostType, Acc, Params).
602
603 -spec privacy_iq_set(HostType, Acc, From, To, IQ) -> Result when
604 HostType :: mongooseim:host_type(),
605 Acc :: mongoose_acc:t(),
606 From :: jid:jid(),
607 To :: jid:jid(),
608 IQ :: jlib:iq(),
609 Result :: mongoose_acc:t().
610 privacy_iq_set(HostType, Acc, From, To, IQ) ->
611 139 Params = #{from => From, to => To, iq => IQ},
612 139 run_hook_for_host_type(privacy_iq_set, HostType, Acc, Params).
613
614 -spec privacy_updated_list(HostType, OldList, NewList) -> Result when
615 HostType :: mongooseim:host_type(),
616 OldList :: mongoose_privacy:userlist(),
617 NewList :: mongoose_privacy:userlist(),
618 Result :: false | mongoose_privacy:userlist().
619 privacy_updated_list(HostType, OldList, NewList) ->
620 53 Params = #{old_list => OldList, new_list => NewList},
621 53 run_hook_for_host_type(privacy_updated_list, HostType, false, Params).
622
623 -spec privacy_list_push(HostType, LUser, LServer, Item, SessionCount) -> Result when
624 HostType :: mongooseim:host_type(),
625 LUser :: jid:luser(),
626 LServer :: jid:lserver(),
627 Item :: term(),
628 SessionCount :: non_neg_integer(),
629 Result :: any().
630 privacy_list_push(HostType, LUser, LServer, Item, SessionCount) ->
631 78 Params = #{luse => LUser, lserver => LServer, item => Item, session_count => SessionCount},
632 78 run_hook_for_host_type(privacy_list_push, HostType, ok, Params).
633
634 %% Session management related hooks
635
636 -spec offline_groupchat_message(Acc, From, To, Packet) -> Result when
637 Acc :: mongoose_acc:t(),
638 From :: jid:jid(),
639 To :: jid:jid(),
640 Packet :: exml:element(),
641 Result :: mongoose_acc:t().
642 offline_groupchat_message(Acc, From, To, Packet) ->
643 166 Params = #{from => From, to => To, packet => Packet},
644 166 HostType = mongoose_acc:host_type(Acc),
645 166 run_hook_for_host_type(offline_groupchat_message, HostType, Acc, Params).
646
647 -spec offline_message(Acc, From, To, Packet) -> Result when
648 Acc :: mongoose_acc:t(),
649 From :: jid:jid(),
650 To :: jid:jid(),
651 Packet :: exml:element(),
652 Result :: mongoose_acc:t().
653 offline_message(Acc, From, To, Packet) ->
654 222 Params = #{from => From, to => To, packet => Packet},
655 222 HostType = mongoose_acc:host_type(Acc),
656 222 run_hook_for_host_type(offline_message, HostType, Acc, Params).
657
658 -spec set_presence(Acc, JID, Presence) -> Result when
659 Acc :: mongoose_acc:t(),
660 JID :: jid:jid(),
661 Presence :: any(),
662 Result :: mongoose_acc:t().
663 set_presence(Acc, JID, Presence) ->
664 5314 Params = #{jid => JID, presence => Presence},
665 5314 HostType = mongoose_acc:host_type(Acc),
666 5314 run_hook_for_host_type(set_presence, HostType, Acc, Params).
667
668 -spec sm_filter_offline_message(HostType, From, To, Packet) -> Result when
669 HostType :: mongooseim:host_type(),
670 From :: jid:jid(),
671 To :: jid:jid(),
672 Packet :: exml:element(),
673 Result :: boolean().
674 sm_filter_offline_message(HostType, From, To, Packet) ->
675 230 Params = #{from => From, to => To, packet => Packet},
676 230 run_hook_for_host_type(sm_filter_offline_message, HostType, false, Params).
677
678 -spec sm_register_connection(HostType, SID, JID, Info) -> Result when
679 HostType :: mongooseim:host_type(),
680 SID :: 'undefined' | ejabberd_sm:sid(),
681 JID :: jid:jid(),
682 Info :: ejabberd_sm:info(),
683 Result :: ok.
684 sm_register_connection(HostType, SID, JID, Info) ->
685 6375 Params = #{sid => SID, jid => JID, info => Info},
686 6375 run_hook_for_host_type(sm_register_connection, HostType, ok, Params).
687
688 -spec sm_remove_connection(Acc, SID, JID, Info, Reason) -> Result when
689 Acc :: mongoose_acc:t(),
690 SID :: 'undefined' | ejabberd_sm:sid(),
691 JID :: jid:jid(),
692 Info :: ejabberd_sm:info(),
693 Reason :: ejabberd_sm:close_reason(),
694 Result :: mongoose_acc:t().
695 sm_remove_connection(Acc, SID, JID, Info, Reason) ->
696 6026 Params = #{sid => SID, jid => JID, info => Info, reason => Reason},
697 6026 HostType = mongoose_acc:host_type(Acc),
698 6026 run_hook_for_host_type(sm_remove_connection, HostType, Acc, Params).
699
700 -spec unset_presence(Acc, JID, Status) -> Result when
701 Acc :: mongoose_acc:t(),
702 JID:: jid:jid(),
703 Status :: binary(),
704 Result :: mongoose_acc:t().
705 unset_presence(Acc, JID, Status) ->
706 5261 Params = #{jid => JID, status => Status},
707 5261 HostType = mongoose_acc:host_type(Acc),
708 5261 run_hook_for_host_type(unset_presence, HostType, Acc, Params).
709
710 -spec xmpp_bounce_message(Acc) -> Result when
711 Acc :: mongoose_acc:t(),
712 Result :: mongoose_acc:t().
713 xmpp_bounce_message(Acc) ->
714 33 HostType = mongoose_acc:host_type(Acc),
715 33 run_hook_for_host_type(xmpp_bounce_message, HostType, Acc, #{}).
716
717 %% Roster related hooks
718
719 %%% @doc The `roster_get' hook is called to extract a user's roster.
720 -spec roster_get(Acc, JID, Full) -> Result when
721 Acc :: mongoose_acc:t(),
722 JID :: jid:jid(),
723 Full :: boolean(),
724 Result :: [mod_roster:roster()].
725 roster_get(Acc, JID, Full) ->
726 186 Params = #{mongoose_acc => Acc, show_full_roster => Full, jid => JID},
727 186 HostType = mongoose_acc:host_type(Acc),
728 186 run_hook_for_host_type(roster_get, HostType, [], Params).
729
730 %%% @doc The `roster_groups' hook is called to extract roster groups.
731 -spec roster_groups(LServer) -> Result when
732 LServer :: jid:lserver(),
733 Result :: list().
734 roster_groups(LServer) ->
735
:-(
Params = #{lserver => LServer},
736
:-(
run_hook_for_host_type(roster_groups, LServer, [], Params).
737
738 %%% @doc The `roster_get_jid_info' hook is called to determine the
739 %%% subscription state between a given pair of users.
740 %%% The hook handlers need to expect following arguments:
741 %%% * Acc with an initial value of {none, []},
742 %%% * ToJID, a stringprepped roster's owner's jid
743 %%% * RemoteBareJID, a bare JID of the other user.
744 %%%
745 %%% The arguments and the return value types correspond to the following spec.
746 -spec roster_get_jid_info(HostType, ToJID, RemoteJID) -> Result when
747 HostType :: mongooseim:host_type(),
748 ToJID :: jid:jid(),
749 RemoteJID :: jid:jid() | jid:simple_jid(),
750 Result :: {mod_roster:subscription_state(), [binary()]}.
751 roster_get_jid_info(HostType, ToJID, RemBareJID) ->
752 140 Params = #{to => ToJID, remote => RemBareJID},
753 140 run_hook_for_host_type(roster_get_jid_info, HostType, {none, []}, Params).
754
755 %%% @doc The `roster_get_subscription_lists' hook is called to extract
756 %%% user's subscription list.
757 -spec roster_get_subscription_lists(HostType, Acc, JID) -> Result when
758 HostType :: mongooseim:host_type(),
759 Acc ::mongoose_acc:t(),
760 JID :: jid:jid(),
761 Result :: mongoose_acc:t().
762 roster_get_subscription_lists(HostType, Acc, JID) ->
763 5314 BareJID = jid:to_bare(JID),
764 5314 Params = #{jid => BareJID},
765 5314 run_hook_for_host_type(roster_get_subscription_lists, HostType, Acc, Params).
766
767 %%% @doc The `roster_get_versioning_feature' hook is
768 %%% called to determine if roster versioning is enabled.
769 -spec roster_get_versioning_feature(HostType) -> Result when
770 HostType :: mongooseim:host_type(),
771 Result :: [exml:element()].
772 roster_get_versioning_feature(HostType) ->
773 6050 run_hook_for_host_type(roster_get_versioning_feature, HostType, [], #{}).
774
775 %%% @doc The `roster_in_subscription' hook is called to determine
776 %%% if a subscription presence is routed to a user.
777 -spec roster_in_subscription(Acc, To, From, Type, Reason) -> Result when
778 Acc :: mongoose_acc:t(),
779 To :: jid:jid(),
780 From :: jid:jid(),
781 Type :: mod_roster:sub_presence(),
782 Reason :: any(),
783 Result :: mongoose_acc:t().
784 roster_in_subscription(Acc, To, From, Type, Reason) ->
785 586 ToJID = jid:to_bare(To),
786 586 Params = #{to => ToJID, from => From, type => Type, reason => Reason},
787 586 HostType = mongoose_acc:host_type(Acc),
788 586 run_hook_for_host_type(roster_in_subscription, HostType, Acc, Params).
789
790 %%% @doc The `roster_out_subscription' hook is called
791 %%% when a user sends out subscription.
792 -spec roster_out_subscription(Acc, From, To, Type) -> Result when
793 Acc :: mongoose_acc:t(),
794 From :: jid:jid(),
795 To :: jid:jid(),
796 Type :: mod_roster:sub_presence(),
797 Result :: mongoose_acc:t().
798 roster_out_subscription(Acc, From, To, Type) ->
799 348 FromJID = jid:to_bare(From),
800 348 Params = #{to => To, from => FromJID, type => Type},
801 348 HostType = mongoose_acc:host_type(Acc),
802 348 run_hook_for_host_type(roster_out_subscription, HostType, Acc, Params).
803
804 %%% @doc The `roster_process_item' hook is called when a user's roster is set.
805 -spec roster_process_item(HostType, LServer, Item) -> Result when
806 HostType :: mongooseim:host_type(),
807 LServer :: jid:lserver(),
808 Item :: mod_roster:roster(),
809 Result :: mod_roster:roster().
810 roster_process_item(HostType, LServer, Item) ->
811 173 Params = #{lserver => LServer},
812 173 run_hook_for_host_type(roster_process_item, HostType, Item, Params).
813
814 %%% @doc The `roster_push' hook is called when a roster item is
815 %%% being pushed and roster versioning is not enabled.
816 -spec roster_push(HostType, From, Item) -> Result when
817 HostType :: mongooseim:host_type(),
818 From :: jid:jid(),
819 Item :: mod_roster:roster(),
820 Result :: any().
821 roster_push(HostType, From, Item) ->
822 772 Params = #{from => From, item => Item},
823 772 run_hook_for_host_type(roster_push, HostType, ok, Params).
824
825 %%% @doc The `roster_set' hook is called when a user's roster is set through an IQ.
826 -spec roster_set(HostType, From, To, SubEl) -> Result when
827 HostType :: mongooseim:host_type(),
828 From :: jid:jid(),
829 To :: jid:jid(),
830 SubEl :: exml:element(),
831 Result :: any().
832 roster_set(HostType, From, To, SubEl) ->
833 31 Params = #{from => From, to => To, sub_el => SubEl},
834 31 run_hook_for_host_type(roster_set, HostType, ok, Params).
835
836 %% MUC related hooks
837
838 %%% @doc The `is_muc_room_owner' hooks is called to determine
839 %%% if a given user is a room's owner.
840 %%%
841 %%% The hook's handler needs to expect the following arguments:
842 %%% `Acc', `Room', `User'.
843 %%% The arguments and the return value types correspond to the
844 %%% following spec.
845 -spec is_muc_room_owner(HostType, Acc, Room, User) -> Result when
846 HostType :: mongooseim:host_type(),
847 Acc :: mongoose_acc:t(),
848 Room :: jid:jid(),
849 User :: jid:jid(),
850 Result :: boolean().
851 is_muc_room_owner(HostType, Acc, Room, User) ->
852 168 Params = #{acc => Acc, room => Room, user => User},
853 168 run_hook_for_host_type(is_muc_room_owner, HostType, false, Params).
854
855 %%% @doc The `can_access_identity' hook is called to determine if
856 %%% a given user can see the real identity of the people in a room.
857 -spec can_access_identity(HostType, Room, User) -> Result when
858 HostType :: mongooseim:host_type(),
859 Room :: jid:jid(),
860 User :: jid:jid(),
861 Result :: boolean().
862 can_access_identity(HostType, Room, User) ->
863 339 Params = #{room => Room, user => User},
864 339 run_hook_for_host_type(can_access_identity, HostType, false, Params).
865
866 %%% @doc The `can_access_room' hook is called to determine
867 %%% if a given user can access a room.
868 -spec can_access_room(HostType, Acc, Room, User) -> Result when
869 HostType :: mongooseim:host_type(),
870 Acc :: mongoose_acc:t(),
871 Room :: jid:jid(),
872 User :: jid:jid(),
873 Result :: boolean().
874 can_access_room(HostType, Acc, Room, User) ->
875 531 Params = #{acc => Acc, room => Room, user => User},
876 531 run_hook_for_host_type(can_access_room, HostType, false, Params).
877
878 -spec acc_room_affiliations(Acc, Room) -> NewAcc when
879 Acc :: mongoose_acc:t(),
880 Room :: jid:jid(),
881 NewAcc :: mongoose_acc:t().
882 acc_room_affiliations(Acc, Room) ->
883 660 Params = #{room => Room},
884 660 HostType = mod_muc_light_utils:acc_to_host_type(Acc),
885 660 run_hook_for_host_type(acc_room_affiliations, HostType, Acc, Params).
886
887 -spec room_exists(HostType, Room) -> Result when
888 HostType :: mongooseim:host_type(),
889 Room :: jid:jid(),
890 Result :: boolean().
891 room_exists(HostType, Room) ->
892 582 Params = #{room => Room},
893 582 run_hook_for_host_type(room_exists, HostType, false, Params).
894
895 -spec room_new_affiliations(Acc, Room, NewAffs, Version) -> NewAcc when
896 Acc :: mongoose_acc:t(),
897 Room :: jid:jid(),
898 NewAffs :: mod_muc_light:aff_users(),
899 Version :: binary(),
900 NewAcc :: mongoose_acc:t().
901 room_new_affiliations(Acc, Room, NewAffs, Version) ->
902 173 Params = #{room => Room, new_affs => NewAffs, version => Version},
903 173 HostType = mod_muc_light_utils:acc_to_host_type(Acc),
904 173 run_hook_for_host_type(room_new_affiliations, HostType, Acc, Params).
905
906 %% MAM related hooks
907
908 %%% @doc The `mam_archive_id' hook is called to determine
909 %%% the integer id of an archive for a particular user or entity.
910 %%%
911 %%% If a MAM backend doesn't support or doesn't require archive IDs,
912 %%% `undefined' may be returned.
913 -spec mam_archive_id(HostType, Owner) -> Result when
914 HostType :: mongooseim:host_type(),
915 Owner :: jid:jid(),
916 Result :: undefined | mod_mam:archive_id().
917 mam_archive_id(HostType, Owner) ->
918 9829 Params = #{owner => Owner},
919 9829 run_hook_for_host_type(mam_archive_id, HostType, undefined, Params).
920
921 %%% @doc The `mam_archive_size' hook is called to determine the size
922 %%% of the archive for a given JID
923 -spec mam_archive_size(HostType, ArchiveID, Owner) -> Result when
924 HostType :: mongooseim:host_type(),
925 ArchiveID :: undefined | mod_mam:archive_id(),
926 Owner :: jid:jid(),
927 Result :: integer().
928 mam_archive_size(HostType, ArchiveID, Owner) ->
929 1743 Params = #{archive_id => ArchiveID, owner => Owner},
930 1743 run_hook_for_host_type(mam_archive_size, HostType, 0, Params).
931
932 %%% @doc The `mam_get_behaviour' hooks is called to determine if a message
933 %%% should be archived or not based on a given pair of JIDs.
934 -spec mam_get_behaviour(HostType, ArchiveID,
935 Owner, Remote) -> Result when
936 HostType :: mongooseim:host_type(),
937 ArchiveID :: undefined | mod_mam:archive_id(),
938 Owner :: jid:jid(),
939 Remote :: jid:jid(),
940 Result :: mod_mam:archive_behaviour().
941 mam_get_behaviour(HostType, ArchiveID, Owner, Remote) ->
942 2861 Params = #{archive_id => ArchiveID, owner => Owner, remote => Remote},
943 2861 run_hook_for_host_type(mam_get_behaviour, HostType, always, Params).
944
945 %%% @doc The `mam_set_prefs' hook is called to set a user's archive preferences.
946 %%%
947 %%% It's possible to set which JIDs are always or never allowed in the archive
948 -spec mam_set_prefs(HostType, ArchiveId, Owner,
949 DefaultMode, AlwaysJIDs, NeverJIDs) -> Result when
950 HostType :: mongooseim:host_type(),
951 ArchiveId :: undefined | mod_mam:archive_id(),
952 Owner :: jid:jid(),
953 DefaultMode :: mod_mam:archive_behaviour(),
954 AlwaysJIDs :: [jid:literal_jid()],
955 NeverJIDs :: [jid:literal_jid()],
956 Result :: any().
957 mam_set_prefs(HostType, ArchiveID, Owner, DefaultMode, AlwaysJIDs, NeverJIDs) ->
958 308 Params = #{archive_id => ArchiveID, owner => Owner,
959 default_mode => DefaultMode, always_jids => AlwaysJIDs, never_jids => NeverJIDs},
960 308 run_hook_for_host_type(mam_set_prefs, HostType, {error, not_implemented}, Params).
961
962 %%% @doc The `mam_get_prefs' hook is called to read
963 %%% the archive settings for a given user.
964 -spec mam_get_prefs(HostType, DefaultMode, ArchiveID, Owner) -> Result when
965 HostType :: mongooseim:host_type(),
966 DefaultMode :: mod_mam:archive_behaviour(),
967 ArchiveID :: undefined | mod_mam:archive_id(),
968 Owner :: jid:jid(),
969 Result :: mod_mam:preference() | {error, Reason :: term()}.
970 mam_get_prefs(HostType, DefaultMode, ArchiveID, Owner) ->
971 161 Params = #{archive_id => ArchiveID, owner => Owner},
972 161 InitialAccValue = {DefaultMode, [], []}, %% mod_mam:preference() type
973 161 run_hook_for_host_type(mam_get_prefs, HostType, InitialAccValue, Params).
974
975 %%% @doc The `mam_remove_archive' hook is called in order to
976 %%% remove the entire archive for a particular user.
977 -spec mam_remove_archive(HostType, ArchiveID, Owner) -> any() when
978 HostType :: mongooseim:host_type(),
979 ArchiveID :: undefined | mod_mam:archive_id(),
980 Owner :: jid:jid().
981 mam_remove_archive(HostType, ArchiveID, Owner) ->
982 464 Params = #{archive_id => ArchiveID, owner => Owner},
983 464 run_hook_for_host_type(mam_remove_archive, HostType, ok, Params).
984
985 %%% @doc The `mam_lookup_messages' hook is to retrieve
986 %%% archived messages for given search parameters.
987 -spec mam_lookup_messages(HostType, Params) -> Result when
988 HostType :: mongooseim:host_type(),
989 Params :: map(),
990 Result :: {ok, mod_mam:lookup_result()}.
991 mam_lookup_messages(HostType, Params) ->
992 1070 InitialLookupValue = {0, 0, []}, %% mod_mam:lookup_result() type
993 1070 run_hook_for_host_type(mam_lookup_messages, HostType, {ok, InitialLookupValue},
994 Params).
995
996 %%% @doc The `mam_archive_message' hook is called in order
997 %%% to store the message in the archive.
998 -spec mam_archive_message(HostType, Params) ->
999 Result when
1000 HostType :: mongooseim:host_type(),
1001 Params :: mod_mam:archive_message_params(),
1002 Result :: ok | {error, timeout}.
1003 mam_archive_message(HostType, Params) ->
1004 7739 run_hook_for_host_type(mam_archive_message, HostType, ok, Params).
1005
1006 %% @doc Waits until all pending messages are written
1007 -spec mam_archive_sync(HostType :: mongooseim:host_type()) -> ok.
1008 mam_archive_sync(HostType) ->
1009 70 run_hook_for_host_type(mam_archive_sync, HostType, ok, #{}).
1010
1011 %% @doc Notifies of a message retraction
1012 -spec mam_retraction(mongooseim:host_type(),
1013 mod_mam_utils:retraction_info(),
1014 mod_mam:archive_message_params()) ->
1015 mod_mam_utils:retraction_info().
1016 mam_retraction(HostType, RetractionInfo, Env) ->
1017 28 run_hook_for_host_type(mam_retraction, HostType, RetractionInfo, Env).
1018
1019 %% MAM MUC related hooks
1020
1021 %%% @doc The `mam_muc_archive_id' hook is called to determine the
1022 %%% archive ID for a particular room.
1023 %%% The hook handler is expected to accept the following arguments:
1024 %%% * Acc with initial value `undefined',
1025 %%% * Host as passed in `HooksServer' variable,
1026 %%% * OwnerJID,
1027 %%%
1028 %%% and return an integer value corresponding to the given owner's archive.
1029 %%%
1030 %%% If a MAM backend doesn't support or doesn't require archive IDs,
1031 %%% `undefined' may be returned.
1032 -spec mam_muc_archive_id(HostType, Owner) -> Result when
1033 HostType :: mongooseim:host_type(),
1034 Owner :: jid:jid(),
1035 Result :: undefined | mod_mam:archive_id().
1036 mam_muc_archive_id(HostType, Owner) ->
1037 3225 Params = #{owner => Owner},
1038 3225 run_hook_for_host_type(mam_muc_archive_id, HostType, undefined, Params).
1039
1040 %%% @doc The `mam_muc_archive_size' hook is called to determine
1041 %%% the archive size for a given room.
1042 -spec mam_muc_archive_size(HostType, ArchiveID, Room) -> Result when
1043 HostType :: mongooseim:host_type(),
1044 ArchiveID :: undefined | mod_mam:archive_id(),
1045 Room :: jid:jid(),
1046 Result :: integer().
1047 mam_muc_archive_size(HostType, ArchiveID, Room) ->
1048 619 Params = #{archive_id => ArchiveID, room => Room},
1049 619 run_hook_for_host_type(mam_muc_archive_size, HostType, 0, Params).
1050
1051 %%% @doc The `mam_muc_get_behaviour' hooks is called to determine if a message should
1052 %%% be archived or not based on the given room and user JIDs.
1053 -spec mam_muc_get_behaviour(HostType, ArchiveID,
1054 Room, Remote) -> Result when
1055 HostType :: mongooseim:host_type(),
1056 ArchiveID :: undefined | mod_mam:archive_id(),
1057 Room :: jid:jid(),
1058 Remote :: jid:jid(),
1059 Result :: mod_mam:archive_behaviour().
1060 mam_muc_get_behaviour(HostType, ArchiveID, Room, Remote) ->
1061 1206 Params = #{archive_id => ArchiveID, room => Room, remote => Remote},
1062 1206 DefaultBehaviour = always, %% mod_mam:archive_behaviour() type
1063 1206 run_hook_for_host_type(mam_muc_get_behaviour, HostType, DefaultBehaviour, Params).
1064
1065 %%% @doc The `mam_muc_set_prefs' hook is called to set a room's archive preferences.
1066 %%%
1067 %%% It's possible to set which JIDs are always or never allowed in the archive
1068 -spec mam_muc_set_prefs(HostType, ArchiveId, Room,
1069 DefaultMode, AlwaysJIDs, NeverJIDs) -> Result when
1070 HostType :: mongooseim:host_type(),
1071 ArchiveId :: undefined | mod_mam:archive_id(),
1072 Room :: jid:jid(),
1073 DefaultMode :: mod_mam:archive_behaviour(),
1074 AlwaysJIDs :: [jid:literal_jid()],
1075 NeverJIDs :: [jid:literal_jid()],
1076 Result :: any().
1077 mam_muc_set_prefs(HostType, ArchiveID, Room, DefaultMode, AlwaysJIDs, NeverJIDs) ->
1078 161 Params = #{archive_id => ArchiveID, room => Room, default_mode => DefaultMode,
1079 always_jids => AlwaysJIDs, never_jids => NeverJIDs},
1080 161 InitialAcc = {error, not_implemented},
1081 161 run_hook_for_host_type(mam_muc_set_prefs, HostType, InitialAcc, Params).
1082
1083 %%% @doc The `mam_muc_get_prefs' hook is called to read
1084 %%% the archive settings for a given room.
1085 -spec mam_muc_get_prefs(HostType, DefaultMode, ArchiveID, Room) -> Result when
1086 HostType :: mongooseim:host_type(),
1087 DefaultMode :: mod_mam:archive_behaviour(),
1088 ArchiveID :: undefined | mod_mam:archive_id(),
1089 Room :: jid:jid(),
1090 Result :: mod_mam:preference() | {error, Reason :: term()}.
1091 mam_muc_get_prefs(HostType, DefaultMode, ArchiveID, Room) ->
1092 14 Params = #{archive_id => ArchiveID, room => Room},
1093 14 InitialAcc = {DefaultMode, [], []}, %% mod_mam:preference() type
1094 14 run_hook_for_host_type(mam_muc_get_prefs, HostType, InitialAcc, Params).
1095
1096 %%% @doc The `mam_muc_remove_archive' hook is called in order to remove the entire
1097 %%% archive for a particular user.
1098 -spec mam_muc_remove_archive(HostType, ArchiveID, Room) -> any() when
1099 HostType :: mongooseim:host_type(),
1100 ArchiveID :: undefined | mod_mam:archive_id(),
1101 Room :: jid:jid().
1102 mam_muc_remove_archive(HostType, ArchiveID, Room) ->
1103 684 Params = #{archive_id => ArchiveID, room => Room},
1104 684 run_hook_for_host_type(mam_muc_remove_archive, HostType, ok, Params).
1105
1106 %%% @doc The `mam_muc_lookup_messages' hook is to retrieve archived
1107 %%% MUC messages for any given search parameters.
1108 -spec mam_muc_lookup_messages(HostType, Params) -> Result when
1109 HostType :: mongooseim:host_type(),
1110 Params :: map(),
1111 Result :: {ok, mod_mam:lookup_result()}.
1112 mam_muc_lookup_messages(HostType, Params) ->
1113 519 InitialLookupValue = {0, 0, []}, %% mod_mam:lookup_result() type
1114 519 run_hook_for_host_type(mam_muc_lookup_messages, HostType, {ok, InitialLookupValue},
1115 Params).
1116
1117 %%% @doc The `mam_muc_archive_message' hook is called in order
1118 %%% to store the MUC message in the archive.
1119 -spec mam_muc_archive_message(HostType, Params) -> Result when
1120 HostType :: mongooseim:host_type(),
1121 Params :: mod_mam:archive_message_params(),
1122 Result :: ok | {error, timeout}.
1123 mam_muc_archive_message(HostType, Params) ->
1124 2890 run_hook_for_host_type(mam_muc_archive_message, HostType, ok, Params).
1125
1126 %% @doc Waits until all pending messages are written
1127 -spec mam_muc_archive_sync(HostType :: mongooseim:host_type()) -> ok.
1128 mam_muc_archive_sync(HostType) ->
1129 180 run_hook_for_host_type(mam_muc_archive_sync, HostType, ok, #{}).
1130
1131 %% @doc Notifies of a muc message retraction
1132 -spec mam_muc_retraction(mongooseim:host_type(),
1133 mod_mam_utils:retraction_info(),
1134 mod_mam:archive_message_params()) ->
1135 mod_mam_utils:retraction_info().
1136 mam_muc_retraction(HostType, RetractionInfo, Env) ->
1137 14 run_hook_for_host_type(mam_muc_retraction, HostType, RetractionInfo, Env).
1138
1139 %% GDPR related hooks
1140
1141 %%% @doc `get_mam_pm_gdpr_data' hook is called to provide
1142 %%% a user's archive for GDPR purposes.
1143 -spec get_mam_pm_gdpr_data(HostType, JID) -> Result when
1144 HostType :: mongooseim:host_type(),
1145 JID :: jid:jid(),
1146 Result :: ejabberd_gen_mam_archive:mam_pm_gdpr_data().
1147 get_mam_pm_gdpr_data(HostType, JID) ->
1148 44 Params = #{jid => JID},
1149 44 run_hook_for_host_type(get_mam_pm_gdpr_data, HostType, [], Params).
1150
1151 %%% @doc `get_mam_muc_gdpr_data' hook is called to provide
1152 %%% a user's archive for GDPR purposes.
1153 -spec get_mam_muc_gdpr_data(HostType, JID) -> Result when
1154 HostType :: mongooseim:host_type(),
1155 JID :: jid:jid(),
1156 Result :: ejabberd_gen_mam_archive:mam_muc_gdpr_data().
1157 get_mam_muc_gdpr_data(HostType, JID) ->
1158 40 Params = #{jid => JID},
1159 40 run_hook_for_host_type(get_mam_muc_gdpr_data, HostType, [], Params).
1160
1161 %%% @doc `get_personal_data' hook is called to retrieve
1162 %%% a user's personal data for GDPR purposes.
1163 -spec get_personal_data(HostType, JID) -> Result when
1164 HostType :: mongooseim:host_type(),
1165 JID :: jid:jid(),
1166 Result :: gdpr:personal_data().
1167 get_personal_data(HostType, JID) ->
1168 69 Params = #{jid => JID},
1169 69 run_hook_for_host_type(get_personal_data, HostType, [], Params).
1170
1171 %% S2S related hooks
1172
1173 %%% @doc `s2s_allow_host' hook is called to check whether a server
1174 %%% should be allowed to be connected to.
1175 %%%
1176 %%% A handler can decide that a server should not be allowed and pass this
1177 %%% information to the caller.
1178 -spec s2s_allow_host(MyHost, S2SHost) -> Result when
1179 MyHost :: jid:server(),
1180 S2SHost :: jid:server(),
1181 Result :: allow | deny.
1182 s2s_allow_host(MyHost, S2SHost) ->
1183 8 Params = #{my_host => MyHost, s2s_host => S2SHost},
1184 8 run_global_hook(s2s_allow_host, allow, Params).
1185
1186 %%% @doc `s2s_send_packet' hook is called when a message is routed.
1187 -spec s2s_send_packet(Acc, From, To, Packet) -> Result when
1188 Acc :: mongoose_acc:t(),
1189 From :: jid:jid(),
1190 To :: jid:jid(),
1191 Packet :: exml:element(),
1192 Result :: mongoose_acc:t().
1193 s2s_send_packet(Acc, From, To, Packet) ->
1194 32 Params = #{from => From, to => To, packet => Packet},
1195 32 run_global_hook(s2s_send_packet, Acc, Params).
1196
1197 %%% @doc `s2s_stream_features' hook is used to extract
1198 %%% the stream management features supported by the server.
1199 -spec s2s_stream_features(HostType, LServer) -> Result when
1200 HostType :: mongooseim:host_type(),
1201 LServer :: jid:lserver(),
1202 Result :: [exml:element()].
1203 s2s_stream_features(HostType, LServer) ->
1204
:-(
Params = #{lserver => LServer},
1205
:-(
run_hook_for_host_type(s2s_stream_features, HostType, [], Params).
1206
1207 %%% @doc `s2s_receive_packet' hook is called when
1208 %%% an incoming stanza is routed by the server.
1209 -spec s2s_receive_packet(Acc) -> Result when
1210 Acc :: mongoose_acc:t(),
1211 Result :: mongoose_acc:t().
1212 s2s_receive_packet(Acc) ->
1213
:-(
run_global_hook(s2s_receive_packet, Acc, #{}).
1214
1215 %% Discovery related hooks
1216
1217 %%% @doc `disco_local_identity' hook is called to get the identity of the server.
1218 -spec disco_local_identity(mongoose_disco:identity_acc()) ->
1219 mongoose_disco:identity_acc().
1220 disco_local_identity(Acc = #{host_type := HostType}) ->
1221 118 run_hook_for_host_type(disco_local_identity, HostType, Acc, #{}).
1222
1223 %%% @doc `disco_sm_identity' hook is called to get the identity of the
1224 %%% client when a discovery IQ gets to session management.
1225 -spec disco_sm_identity(mongoose_disco:identity_acc()) -> mongoose_disco:identity_acc().
1226 disco_sm_identity(Acc = #{host_type := HostType}) ->
1227 30 run_hook_for_host_type(disco_sm_identity, HostType, Acc, #{}).
1228
1229 %%% @doc `disco_local_items' hook is called to extract items associated with the server.
1230 -spec disco_local_items(mongoose_disco:item_acc()) -> mongoose_disco:item_acc().
1231 disco_local_items(Acc = #{host_type := HostType}) ->
1232 30 run_hook_for_host_type(disco_local_items, HostType, Acc, #{}).
1233
1234 %%% @doc `disco_sm_items' hook is called to get the items associated
1235 %%% with the client when a discovery IQ gets to session management.
1236 -spec disco_sm_items(mongoose_disco:item_acc()) -> mongoose_disco:item_acc().
1237 disco_sm_items(Acc = #{host_type := HostType}) ->
1238 11 run_hook_for_host_type(disco_sm_items, HostType, Acc, #{}).
1239
1240 %%% @doc `disco_local_features' hook is called to extract features
1241 %%% offered by the server.
1242 -spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc().
1243 disco_local_features(Acc = #{host_type := HostType}) ->
1244 118 run_hook_for_host_type(disco_local_features, HostType, Acc, #{}).
1245
1246 %%% @doc `disco_sm_features' hook is called to get the features of the client
1247 %%% when a discovery IQ gets to session management.
1248 -spec disco_sm_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc().
1249 disco_sm_features(Acc = #{host_type := HostType}) ->
1250 30 run_hook_for_host_type(disco_sm_features, HostType, Acc, #{}).
1251
1252 %%% @doc `disco_muc_features' hook is called to get the features
1253 %%% supported by the MUC (Light) service.
1254 -spec disco_muc_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc().
1255 disco_muc_features(Acc = #{host_type := HostType}) ->
1256 29 run_hook_for_host_type(disco_muc_features, HostType, Acc, #{}).
1257
1258 %%% @doc `disco_info' hook is called to extract information about the server.
1259 -spec disco_info(mongoose_disco:info_acc()) -> mongoose_disco:info_acc().
1260 disco_info(Acc = #{host_type := HostType}) ->
1261 135 run_hook_for_host_type(disco_info, HostType, Acc, #{}).
1262
1263 %% AMP related hooks
1264
1265 %%% @doc The `amp_check_condition' hook is called to determine whether
1266 %%% the AMP strategy matches the given AMP rule.
1267 -spec amp_check_condition(HostType, Strategy, Rule) -> Result when
1268 HostType :: mongooseim:host_type(),
1269 Strategy :: mod_amp:amp_strategy(),
1270 Rule :: mod_amp:amp_rule(),
1271 Result :: mod_amp:amp_match_result().
1272 amp_check_condition(HostType, Strategy, Rule) ->
1273 544 Params = #{strategy => Strategy, rule => Rule},
1274 544 InitialAcc = no_match, %% mod_amp:amp_match_result() type
1275 544 run_hook_for_host_type(amp_check_condition, HostType, InitialAcc, Params).
1276
1277 %%% @doc The `amp_determine_strategy' hook is called when checking to determine
1278 %%% which strategy will be chosen when executing AMP rules.
1279 -spec amp_determine_strategy(HostType, From, To, Packet, Event) -> Result when
1280 HostType :: mongooseim:host_type(),
1281 From :: jid:jid(),
1282 To :: jid:jid() | undefined,
1283 Packet :: exml:element(),
1284 Event :: mod_amp:amp_event(),
1285 Result :: mod_amp:amp_strategy().
1286 amp_determine_strategy(HostType, From, To, Packet, Event) ->
1287 566 Params = #{from => From, to => To, packet => Packet, event => Event},
1288 566 DefaultStrategy = amp_strategy:null_strategy(),
1289 566 run_hook_for_host_type(amp_determine_strategy, HostType, DefaultStrategy, Params).
1290
1291 %%% @doc The `amp_verify_support' hook is called when checking
1292 %%% whether the host supports given AMP rules.
1293 -spec amp_verify_support(HostType, Rules) -> Result when
1294 HostType :: mongooseim:host_type(),
1295 Rules :: mod_amp:amp_rules(),
1296 Result :: [mod_amp:amp_rule_support()].
1297 amp_verify_support(HostType, Rules) ->
1298 271 Params = #{rules => Rules},
1299 271 run_hook_for_host_type(amp_verify_support, HostType, [], Params).
1300
1301 %% MUC and MUC Light related hooks
1302
1303 -spec filter_room_packet(HostType, Packet, EventData) -> Result when
1304 HostType :: mongooseim:host_type(),
1305 Packet :: exml:element(),
1306 EventData :: mod_muc:room_event_data(),
1307 Result :: exml:element().
1308 filter_room_packet(HostType, Packet, EventData) ->
1309 1734 run_hook_for_host_type(filter_room_packet, HostType, Packet, EventData).
1310
1311 %%% @doc The `forget_room' hook is called when a room is removed from the database.
1312 -spec forget_room(HostType, MucHost, Room) -> Result when
1313 HostType :: mongooseim:host_type(),
1314 MucHost :: jid:server(),
1315 Room :: jid:luser(),
1316 Result :: any().
1317 forget_room(HostType, MucHost, Room) ->
1318 432 Params = #{muc_host => MucHost, room => Room},
1319 432 run_hook_for_host_type(forget_room, HostType, #{}, Params).
1320
1321 -spec invitation_sent(HookServer, Host, RoomJID, From, To, Reason) -> Result when
1322 HookServer :: jid:server(),
1323 Host :: jid:server(),
1324 RoomJID :: jid:jid(),
1325 From :: jid:jid(),
1326 To :: jid:jid(),
1327 Reason :: binary(),
1328 Result :: any().
1329 invitation_sent(HookServer, Host, RoomJID, From, To, Reason) ->
1330 11 Params = #{host => Host, room_jid => RoomJID, from => From, to => To, reason => Reason},
1331 11 run_hook_for_host_type(invitation_sent, HookServer, ok, Params).
1332
1333 %%% @doc The `join_room' hook is called when a user joins a MUC room.
1334 -spec join_room(HookServer, Room, Host, JID, MucJID) -> Result when
1335 HookServer :: jid:server(),
1336 Room :: mod_muc:room(),
1337 Host :: jid:server(),
1338 JID :: jid:jid(),
1339 MucJID :: jid:jid(),
1340 Result :: any().
1341 join_room(HookServer, Room, Host, JID, MucJID) ->
1342 787 Params = #{room => Room, host => Host, jid => JID, muc_jid => MucJID},
1343 787 run_hook_for_host_type(join_room, HookServer, ok, Params).
1344
1345 %%% @doc The `leave_room' hook is called when a user joins a MUC room.
1346 -spec leave_room(HookServer, Room, Host, JID, MucJID) -> Result when
1347 HookServer :: jid:server(),
1348 Room :: mod_muc:room(),
1349 Host :: jid:server(),
1350 JID :: jid:jid(),
1351 MucJID :: jid:jid(),
1352 Result :: any().
1353 leave_room(HookServer, Room, Host, JID, MucJID) ->
1354 728 Params = #{room => Room, host => Host, jid => JID, muc_jid => MucJID},
1355 728 run_hook_for_host_type(leave_room, HookServer, ok, Params).
1356
1357 %%% @doc The `room_packet' hook is called when a message is added to room's history.
1358 -spec room_packet(Server, FromNick, FromJID, JID, Packet) -> Result when
1359 Server :: jid:lserver(),
1360 FromNick :: mod_muc:nick(),
1361 FromJID :: jid:jid(),
1362 JID :: jid:jid(),
1363 Packet :: exml:element(),
1364 Result :: any().
1365 room_packet(Server, FromNick, FromJID, JID, Packet) ->
1366 990 Params = #{from_nick => FromNick, from_jid => FromJID, jid => JID, packet => Packet},
1367 990 run_hook_for_host_type(room_packet, Server, ok, Params).
1368
1369 -spec update_inbox_for_muc(HostType, Info) -> Result when
1370 HostType :: mongooseim:host_type(),
1371 Info :: mod_muc_room:update_inbox_for_muc_payload(),
1372 Result :: mod_muc_room:update_inbox_for_muc_payload().
1373 update_inbox_for_muc(HostType, Info) ->
1374 990 run_hook_for_host_type(update_inbox_for_muc, HostType, Info, #{}).
1375
1376 %% Caps related hooks
1377
1378 -spec caps_recognised(Acc, From, Pid, Features) -> Result when
1379 Acc :: mongoose_acc:t(),
1380 From :: jid:jid(),
1381 Pid :: pid(),
1382 Features :: unknown | list(),
1383 Result :: mongoose_acc:t().
1384 caps_recognised(Acc, From, Pid, Features) ->
1385
:-(
Params = #{from => From, pid => Pid, features => Features},
1386
:-(
HostType = mongoose_acc:host_type(Acc),
1387
:-(
run_hook_for_host_type(caps_recognised, HostType, Acc, Params).
1388
1389 %% Global distribution related hooks
1390
1391 %%% @doc The `mod_global_distrib_known_recipient' hook is called when
1392 %%% the recipient is known to `global_distrib'.
1393 -spec mod_global_distrib_known_recipient(GlobalHost, From, To, LocalHost) -> Result when
1394 GlobalHost :: jid:server(),
1395 From :: jid:jid(),
1396 To :: jid:jid(),
1397 LocalHost :: jid:server(),
1398 Result :: any().
1399 mod_global_distrib_known_recipient(GlobalHost, From, To, LocalHost) ->
1400
:-(
Params = #{from => From, to => To, target_host => LocalHost},
1401
:-(
run_hook_for_host_type(mod_global_distrib_known_recipient, GlobalHost, ok, Params).
1402
1403 %%% @doc The `mod_global_distrib_unknown_recipient' hook is called when
1404 %%% the recipient is unknown to `global_distrib'.
1405 -spec mod_global_distrib_unknown_recipient(GlobalHost, Info) -> Result when
1406 GlobalHost :: jid:server(),
1407 Info :: filter_packet_acc(),
1408 Result :: any().
1409 mod_global_distrib_unknown_recipient(GlobalHost, Info) ->
1410
:-(
run_hook_for_host_type(mod_global_distrib_unknown_recipient, GlobalHost, Info, #{}).
1411
1412
1413 %%%----------------------------------------------------------------------
1414 %%% Internal functions
1415 %%%----------------------------------------------------------------------
1416 run_global_hook(HookName, Acc, Params) when is_map(Params) ->
1417 56325 run_fold(HookName, global, Acc, Params).
1418
1419 run_hook_for_host_type(HookName, undefined, Acc, Args) ->
1420
:-(
?LOG_ERROR(#{what => undefined_host_type,
1421 text => <<"Running hook for an undefined host type">>,
1422
:-(
hook_name => HookName, hook_acc => Acc, hook_args => Args}),
1423
:-(
Acc;
1424 run_hook_for_host_type(HookName, HostType, Acc, Params) when is_binary(HostType),
1425 is_map(Params) ->
1426 257105 run_fold(HookName, HostType, Acc, Params).
1427
1428 run_fold(HookName, HostType, Acc, Params) when is_map(Params) ->
1429 313430 {_, RetValue} = gen_hook:run_fold(HookName, HostType, Acc, Params),
1430 313428 RetValue.
Line Hits Source