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