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