./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/3,
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 69 Params = #{username => Username, server => Server},
204 69 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 14281 Params = #{jid => Jid, request_type => RequestType},
213 14281 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 39 Params = #{domain => Domain},
221 39 run_hook_for_host_type(remove_domain, HostType, #{failed => []}, Params).
222
223 -spec node_cleanup(Node :: node()) -> Acc :: map().
224 node_cleanup(Node) ->
225 8 Params = #{node => Node},
226 8 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 44 Params = #{node => Node},
231 44 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 49794 HostType = mongoose_acc:host_type(Acc),
247 49794 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 50333 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 388 Params = #{user => User},
266 388 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 1082 HostType = mongoose_acc:host_type(MongooseAcc),
272 1082 HookParams = #{mongoose_acc => MongooseAcc, iq => IQ},
273 1082 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 18 Params = #{from => From, to => To},
291 18 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 5926 Params = #{from => From, to => To, pid => Pid},
302 5926 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 131 Params = #{options => Options, notification_forms => NotificationForms},
313 131 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 534 Params = #{ldomain => LDomain, is_hidden => IsHidden},
323 534 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 6090 Jid = jid:make_bare(LUser, LServer),
334 6090 Params = #{jid => Jid},
335 6090 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 6064 Jid = jid:make_bare(LUser, LServer),
345 6064 Params = #{jid => Jid},
346 6064 HostType = mongoose_acc:host_type(Acc),
347 6064 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 5754 Params = #{jid => JID},
355 5754 HostType = mongoose_acc:host_type(Acc),
356 5754 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 110 HostType = mongoose_acc:host_type(Acc),
388 110 Params = #{jid => JID},
389 110 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 106 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 536 Params = #{ldomain => LDomain},
406 536 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 5754 Params = #{jid => JID},
414 5754 HostType = mongoose_acc:host_type(Acc),
415 5754 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 62529 Params = #{el => El},
449 62529 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 74 Params = #{from => From, to => To, packet => Packet},
461 74 HostType = mongoose_acc:host_type(Acc),
462 74 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 18 Params = #{c2s_data => C2SData, feature => Feature},
472 18 HostType = mongoose_c2s:get_host_type(C2SData),
473 18 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 7 Params = #{c2s_data => C2SData, feature => Feature, to => To},
482 7 HostType = mongoose_c2s:get_host_type(C2SData),
483 7 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 13658 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 7770 Params = #{ip => IP},
543 7770 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 6398 Params = #{jid => JID},
561 6398 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 3569 Params = #{jid => JID, privacy_list => PrivacyList,
574 from_to_name_type => FromToNameType, dir => Dir},
575 3569 HostType = mongoose_acc:host_type(Acc),
576 3569 AccWithRes = mongoose_acc:set(hook, result, allow, Acc),
577 3569 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 3406 Params = #{jid => JID},
585 3406 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 363 Params = #{from => From, to => To, packet => Packet},
640 363 HostType = mongoose_acc:host_type(Acc),
641 363 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 275 Params = #{from => From, to => To, packet => Packet},
651 275 HostType = mongoose_acc:host_type(Acc),
652 275 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 5793 Params = #{jid => JID, presence => Presence},
661 5793 HostType = mongoose_acc:host_type(Acc),
662 5793 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 233 Params = #{from => From, to => To, packet => Packet},
672 233 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 6588 Params = #{sid => SID, jid => JID, info => Info},
682 6588 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 6586 Params = #{sid => SID, jid => JID, info => Info, reason => Reason},
693 6586 HostType = mongoose_acc:host_type(Acc),
694 6586 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 5727 Params = #{jid => JID, status => Status},
703 5727 HostType = mongoose_acc:host_type(Acc),
704 5727 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, Full) -> Result when
717 Acc :: mongoose_acc:t(),
718 JID :: jid:jid(),
719 Full :: boolean(),
720 Result :: [mod_roster:roster()].
721 roster_get(Acc, JID, Full) ->
722 191 Params = #{mongoose_acc => Acc, show_full_roster => Full, jid => JID},
723 191 HostType = mongoose_acc:host_type(Acc),
724 191 run_hook_for_host_type(roster_get, HostType, [], Params).
725
726 %%% @doc The `roster_groups' hook is called to extract roster groups.
727 -spec roster_groups(LServer) -> Result when
728 LServer :: jid:lserver(),
729 Result :: list().
730 roster_groups(LServer) ->
731 7 Params = #{lserver => LServer},
732 7 run_hook_for_host_type(roster_groups, LServer, [], Params).
733
734 %%% @doc The `roster_get_jid_info' hook is called to determine the
735 %%% subscription state between a given pair of users.
736 %%% The hook handlers need to expect following arguments:
737 %%% * Acc with an initial value of {none, []},
738 %%% * ToJID, a stringprepped roster's owner's jid
739 %%% * RemoteBareJID, a bare JID of the other user.
740 %%%
741 %%% The arguments and the return value types correspond to the following spec.
742 -spec roster_get_jid_info(HostType, ToJID, RemoteJID) -> Result when
743 HostType :: mongooseim:host_type(),
744 ToJID :: jid:jid(),
745 RemoteJID :: jid:jid() | jid:simple_jid(),
746 Result :: {mod_roster:subscription_state(), [binary()]}.
747 roster_get_jid_info(HostType, ToJID, RemBareJID) ->
748 143 Params = #{to => ToJID, remote => RemBareJID},
749 143 run_hook_for_host_type(roster_get_jid_info, HostType, {none, []}, Params).
750
751 %%% @doc The `roster_get_subscription_lists' hook is called to extract
752 %%% user's subscription list.
753 -spec roster_get_subscription_lists(HostType, Acc, JID) -> Result when
754 HostType :: mongooseim:host_type(),
755 Acc ::mongoose_acc:t(),
756 JID :: jid:jid(),
757 Result :: mongoose_acc:t().
758 roster_get_subscription_lists(HostType, Acc, JID) ->
759 5793 BareJID = jid:to_bare(JID),
760 5793 Params = #{jid => BareJID},
761 5793 run_hook_for_host_type(roster_get_subscription_lists, HostType, Acc, Params).
762
763 %%% @doc The `roster_get_versioning_feature' hook is
764 %%% called to determine if roster versioning is enabled.
765 -spec roster_get_versioning_feature(HostType) -> Result when
766 HostType :: mongooseim:host_type(),
767 Result :: [exml:element()].
768 roster_get_versioning_feature(HostType) ->
769 6608 run_hook_for_host_type(roster_get_versioning_feature, HostType, [], #{}).
770
771 %%% @doc The `roster_in_subscription' hook is called to determine
772 %%% if a subscription presence is routed to a user.
773 -spec roster_in_subscription(Acc, To, From, Type, Reason) -> Result when
774 Acc :: mongoose_acc:t(),
775 To :: jid:jid(),
776 From :: jid:jid(),
777 Type :: mod_roster:sub_presence(),
778 Reason :: any(),
779 Result :: mongoose_acc:t().
780 roster_in_subscription(Acc, To, From, Type, Reason) ->
781 647 ToJID = jid:to_bare(To),
782 647 Params = #{to => ToJID, from => From, type => Type, reason => Reason},
783 647 HostType = mongoose_acc:host_type(Acc),
784 647 run_hook_for_host_type(roster_in_subscription, HostType, Acc, Params).
785
786 %%% @doc The `roster_out_subscription' hook is called
787 %%% when a user sends out subscription.
788 -spec roster_out_subscription(Acc, From, To, Type) -> Result when
789 Acc :: mongoose_acc:t(),
790 From :: jid:jid(),
791 To :: jid:jid(),
792 Type :: mod_roster:sub_presence(),
793 Result :: mongoose_acc:t().
794 roster_out_subscription(Acc, From, To, Type) ->
795 386 FromJID = jid:to_bare(From),
796 386 Params = #{to => To, from => FromJID, type => Type},
797 386 HostType = mongoose_acc:host_type(Acc),
798 386 run_hook_for_host_type(roster_out_subscription, HostType, Acc, Params).
799
800 %%% @doc The `roster_process_item' hook is called when a user's roster is set.
801 -spec roster_process_item(HostType, LServer, Item) -> Result when
802 HostType :: mongooseim:host_type(),
803 LServer :: jid:lserver(),
804 Item :: mod_roster:roster(),
805 Result :: mod_roster:roster().
806 roster_process_item(HostType, LServer, Item) ->
807 173 Params = #{lserver => LServer},
808 173 run_hook_for_host_type(roster_process_item, HostType, Item, Params).
809
810 %%% @doc The `roster_push' hook is called when a roster item is
811 %%% being pushed and roster versioning is not enabled.
812 -spec roster_push(HostType, From, Item) -> Result when
813 HostType :: mongooseim:host_type(),
814 From :: jid:jid(),
815 Item :: mod_roster:roster(),
816 Result :: any().
817 roster_push(HostType, From, Item) ->
818 837 Params = #{from => From, item => Item},
819 837 run_hook_for_host_type(roster_push, HostType, ok, Params).
820
821 %%% @doc The `roster_set' hook is called when a user's roster is set through an IQ.
822 -spec roster_set(HostType, From, To, SubEl) -> Result when
823 HostType :: mongooseim:host_type(),
824 From :: jid:jid(),
825 To :: jid:jid(),
826 SubEl :: exml:element(),
827 Result :: any().
828 roster_set(HostType, From, To, SubEl) ->
829 31 Params = #{from => From, to => To, sub_el => SubEl},
830 31 run_hook_for_host_type(roster_set, HostType, ok, Params).
831
832 %% MUC related hooks
833
834 %%% @doc The `is_muc_room_owner' hooks is called to determine
835 %%% if a given user is a room's owner.
836 %%%
837 %%% The hook's handler needs to expect the following arguments:
838 %%% `Acc', `Room', `User'.
839 %%% The arguments and the return value types correspond to the
840 %%% following spec.
841 -spec is_muc_room_owner(HostType, Acc, Room, User) -> Result when
842 HostType :: mongooseim:host_type(),
843 Acc :: mongoose_acc:t(),
844 Room :: jid:jid(),
845 User :: jid:jid(),
846 Result :: boolean().
847 is_muc_room_owner(HostType, Acc, Room, User) ->
848
:-(
Params = #{acc => Acc, room => Room, user => User},
849
:-(
run_hook_for_host_type(is_muc_room_owner, HostType, false, Params).
850
851 %%% @doc The `can_access_identity' hook is called to determine if
852 %%% a given user can see the real identity of the people in a room.
853 -spec can_access_identity(HostType, Room, User) -> Result when
854 HostType :: mongooseim:host_type(),
855 Room :: jid:jid(),
856 User :: jid:jid(),
857 Result :: boolean().
858 can_access_identity(HostType, Room, User) ->
859 318 Params = #{room => Room, user => User},
860 318 run_hook_for_host_type(can_access_identity, HostType, false, Params).
861
862 %%% @doc The `can_access_room' hook is called to determine
863 %%% if a given user can access a room.
864 -spec can_access_room(HostType, Acc, Room, User) -> Result when
865 HostType :: mongooseim:host_type(),
866 Acc :: mongoose_acc:t(),
867 Room :: jid:jid(),
868 User :: jid:jid(),
869 Result :: boolean().
870 can_access_room(HostType, Acc, Room, User) ->
871 482 Params = #{acc => Acc, room => Room, user => User},
872 482 run_hook_for_host_type(can_access_room, HostType, false, Params).
873
874 -spec acc_room_affiliations(Acc, Room) -> NewAcc when
875 Acc :: mongoose_acc:t(),
876 Room :: jid:jid(),
877 NewAcc :: mongoose_acc:t().
878 acc_room_affiliations(Acc, Room) ->
879 726 Params = #{room => Room},
880 726 HostType = mod_muc_light_utils:acc_to_host_type(Acc),
881 726 run_hook_for_host_type(acc_room_affiliations, HostType, Acc, Params).
882
883 -spec room_exists(HostType, Room) -> Result when
884 HostType :: mongooseim:host_type(),
885 Room :: jid:jid(),
886 Result :: boolean().
887 room_exists(HostType, Room) ->
888 649 Params = #{room => Room},
889 649 run_hook_for_host_type(room_exists, HostType, false, Params).
890
891 -spec room_new_affiliations(Acc, Room, NewAffs, Version) -> NewAcc when
892 Acc :: mongoose_acc:t(),
893 Room :: jid:jid(),
894 NewAffs :: mod_muc_light:aff_users(),
895 Version :: binary(),
896 NewAcc :: mongoose_acc:t().
897 room_new_affiliations(Acc, Room, NewAffs, Version) ->
898 204 Params = #{room => Room, new_affs => NewAffs, version => Version},
899 204 HostType = mod_muc_light_utils:acc_to_host_type(Acc),
900 204 run_hook_for_host_type(room_new_affiliations, HostType, Acc, Params).
901
902 %% MAM related hooks
903
904 %%% @doc The `mam_archive_id' hook is called to determine
905 %%% the integer id of an archive for a particular user or entity.
906 %%%
907 %%% If a MAM backend doesn't support or doesn't require archive IDs,
908 %%% `undefined' may be returned.
909 -spec mam_archive_id(HostType, Owner) -> Result when
910 HostType :: mongooseim:host_type(),
911 Owner :: jid:jid(),
912 Result :: undefined | mod_mam:archive_id().
913 mam_archive_id(HostType, Owner) ->
914 9234 Params = #{owner => Owner},
915 9234 run_hook_for_host_type(mam_archive_id, HostType, undefined, Params).
916
917 %%% @doc The `mam_archive_size' hook is called to determine the size
918 %%% of the archive for a given JID
919 -spec mam_archive_size(HostType, ArchiveID, Owner) -> Result when
920 HostType :: mongooseim:host_type(),
921 ArchiveID :: undefined | mod_mam:archive_id(),
922 Owner :: jid:jid(),
923 Result :: integer().
924 mam_archive_size(HostType, ArchiveID, Owner) ->
925 1653 Params = #{archive_id => ArchiveID, owner => Owner},
926 1653 run_hook_for_host_type(mam_archive_size, HostType, 0, Params).
927
928 %%% @doc The `mam_get_behaviour' hooks is called to determine if a message
929 %%% should be archived or not based on a given pair of JIDs.
930 -spec mam_get_behaviour(HostType, ArchiveID,
931 Owner, Remote) -> Result when
932 HostType :: mongooseim:host_type(),
933 ArchiveID :: undefined | mod_mam:archive_id(),
934 Owner :: jid:jid(),
935 Remote :: jid:jid(),
936 Result :: mod_mam:archive_behaviour().
937 mam_get_behaviour(HostType, ArchiveID, Owner, Remote) ->
938 2695 Params = #{archive_id => ArchiveID, owner => Owner, remote => Remote},
939 2695 run_hook_for_host_type(mam_get_behaviour, HostType, always, Params).
940
941 %%% @doc The `mam_set_prefs' hook is called to set a user's archive preferences.
942 %%%
943 %%% It's possible to set which JIDs are always or never allowed in the archive
944 -spec mam_set_prefs(HostType, ArchiveId, Owner,
945 DefaultMode, AlwaysJIDs, NeverJIDs) -> Result when
946 HostType :: mongooseim:host_type(),
947 ArchiveId :: undefined | mod_mam:archive_id(),
948 Owner :: jid:jid(),
949 DefaultMode :: mod_mam:archive_behaviour(),
950 AlwaysJIDs :: [jid:literal_jid()],
951 NeverJIDs :: [jid:literal_jid()],
952 Result :: any().
953 mam_set_prefs(HostType, ArchiveID, Owner, DefaultMode, AlwaysJIDs, NeverJIDs) ->
954 308 Params = #{archive_id => ArchiveID, owner => Owner,
955 default_mode => DefaultMode, always_jids => AlwaysJIDs, never_jids => NeverJIDs},
956 308 run_hook_for_host_type(mam_set_prefs, HostType, {error, not_implemented}, Params).
957
958 %%% @doc The `mam_get_prefs' hook is called to read
959 %%% the archive settings for a given user.
960 -spec mam_get_prefs(HostType, DefaultMode, ArchiveID, Owner) -> Result when
961 HostType :: mongooseim:host_type(),
962 DefaultMode :: mod_mam:archive_behaviour(),
963 ArchiveID :: undefined | mod_mam:archive_id(),
964 Owner :: jid:jid(),
965 Result :: mod_mam:preference() | {error, Reason :: term()}.
966 mam_get_prefs(HostType, DefaultMode, ArchiveID, Owner) ->
967 161 Params = #{archive_id => ArchiveID, owner => Owner},
968 161 InitialAccValue = {DefaultMode, [], []}, %% mod_mam:preference() type
969 161 run_hook_for_host_type(mam_get_prefs, HostType, InitialAccValue, Params).
970
971 %%% @doc The `mam_remove_archive' hook is called in order to
972 %%% remove the entire archive for a particular user.
973 -spec mam_remove_archive(HostType, ArchiveID, Owner) -> any() when
974 HostType :: mongooseim:host_type(),
975 ArchiveID :: undefined | mod_mam:archive_id(),
976 Owner :: jid:jid().
977 mam_remove_archive(HostType, ArchiveID, Owner) ->
978 513 Params = #{archive_id => ArchiveID, owner => Owner},
979 513 run_hook_for_host_type(mam_remove_archive, HostType, ok, Params).
980
981 %%% @doc The `mam_lookup_messages' hook is to retrieve
982 %%% archived messages for given search parameters.
983 -spec mam_lookup_messages(HostType, Params) -> Result when
984 HostType :: mongooseim:host_type(),
985 Params :: map(),
986 Result :: {ok, mod_mam:lookup_result()}.
987 mam_lookup_messages(HostType, Params) ->
988 1050 InitialLookupValue = {0, 0, []}, %% mod_mam:lookup_result() type
989 1050 run_hook_for_host_type(mam_lookup_messages, HostType, {ok, InitialLookupValue},
990 Params).
991
992 %%% @doc The `mam_archive_message' hook is called in order
993 %%% to store the message in the archive.
994 -spec mam_archive_message(HostType, Params) ->
995 Result when
996 HostType :: mongooseim:host_type(),
997 Params :: mod_mam:archive_message_params(),
998 Result :: ok | {error, timeout}.
999 mam_archive_message(HostType, Params) ->
1000 7573 run_hook_for_host_type(mam_archive_message, HostType, ok, Params).
1001
1002 %%% @doc The `mam_flush_messages' hook is run after the async bulk write
1003 %%% happens for messages despite the result of the write.
1004 -spec mam_flush_messages(HostType :: mongooseim:host_type(),
1005 MessageCount :: integer()) -> ok.
1006 mam_flush_messages(HostType, MessageCount) ->
1007 880 Params = #{count => MessageCount},
1008 880 run_hook_for_host_type(mam_flush_messages, HostType, ok, Params).
1009
1010 %% @doc Waits until all pending messages are written
1011 -spec mam_archive_sync(HostType :: mongooseim:host_type()) -> ok.
1012 mam_archive_sync(HostType) ->
1013 74 run_hook_for_host_type(mam_archive_sync, HostType, ok, #{}).
1014
1015 %% @doc Notifies of a message retraction
1016 -spec mam_retraction(mongooseim:host_type(),
1017 mod_mam_utils:retraction_info(),
1018 mod_mam:archive_message_params()) ->
1019 mod_mam_utils:retraction_info().
1020 mam_retraction(HostType, RetractionInfo, Env) ->
1021 28 run_hook_for_host_type(mam_retraction, HostType, RetractionInfo, Env).
1022
1023 %% MAM MUC related hooks
1024
1025 %%% @doc The `mam_muc_archive_id' hook is called to determine the
1026 %%% archive ID for a particular room.
1027 %%% The hook handler is expected to accept the following arguments:
1028 %%% * Acc with initial value `undefined',
1029 %%% * Host as passed in `HooksServer' variable,
1030 %%% * OwnerJID,
1031 %%%
1032 %%% and return an integer value corresponding to the given owner's archive.
1033 %%%
1034 %%% If a MAM backend doesn't support or doesn't require archive IDs,
1035 %%% `undefined' may be returned.
1036 -spec mam_muc_archive_id(HostType, Owner) -> Result when
1037 HostType :: mongooseim:host_type(),
1038 Owner :: jid:jid(),
1039 Result :: undefined | mod_mam:archive_id().
1040 mam_muc_archive_id(HostType, Owner) ->
1041 2256 Params = #{owner => Owner},
1042 2256 run_hook_for_host_type(mam_muc_archive_id, HostType, undefined, Params).
1043
1044 %%% @doc The `mam_muc_archive_size' hook is called to determine
1045 %%% the archive size for a given room.
1046 -spec mam_muc_archive_size(HostType, ArchiveID, Room) -> Result when
1047 HostType :: mongooseim:host_type(),
1048 ArchiveID :: undefined | mod_mam:archive_id(),
1049 Room :: jid:jid(),
1050 Result :: integer().
1051 mam_muc_archive_size(HostType, ArchiveID, Room) ->
1052 554 Params = #{archive_id => ArchiveID, room => Room},
1053 554 run_hook_for_host_type(mam_muc_archive_size, HostType, 0, Params).
1054
1055 %%% @doc The `mam_muc_get_behaviour' hooks is called to determine if a message should
1056 %%% be archived or not based on the given room and user JIDs.
1057 -spec mam_muc_get_behaviour(HostType, ArchiveID,
1058 Room, Remote) -> Result when
1059 HostType :: mongooseim:host_type(),
1060 ArchiveID :: undefined | mod_mam:archive_id(),
1061 Room :: jid:jid(),
1062 Remote :: jid:jid(),
1063 Result :: mod_mam:archive_behaviour().
1064 mam_muc_get_behaviour(HostType, ArchiveID, Room, Remote) ->
1065 614 Params = #{archive_id => ArchiveID, room => Room, remote => Remote},
1066 614 DefaultBehaviour = always, %% mod_mam:archive_behaviour() type
1067 614 run_hook_for_host_type(mam_muc_get_behaviour, HostType, DefaultBehaviour, Params).
1068
1069 %%% @doc The `mam_muc_set_prefs' hook is called to set a room's archive preferences.
1070 %%%
1071 %%% It's possible to set which JIDs are always or never allowed in the archive
1072 -spec mam_muc_set_prefs(HostType, ArchiveId, Room,
1073 DefaultMode, AlwaysJIDs, NeverJIDs) -> Result when
1074 HostType :: mongooseim:host_type(),
1075 ArchiveId :: undefined | mod_mam:archive_id(),
1076 Room :: jid:jid(),
1077 DefaultMode :: mod_mam:archive_behaviour(),
1078 AlwaysJIDs :: [jid:literal_jid()],
1079 NeverJIDs :: [jid:literal_jid()],
1080 Result :: any().
1081 mam_muc_set_prefs(HostType, ArchiveID, Room, DefaultMode, AlwaysJIDs, NeverJIDs) ->
1082
:-(
Params = #{archive_id => ArchiveID, room => Room, default_mode => DefaultMode,
1083 always_jids => AlwaysJIDs, never_jids => NeverJIDs},
1084
:-(
InitialAcc = {error, not_implemented},
1085
:-(
run_hook_for_host_type(mam_muc_set_prefs, HostType, InitialAcc, Params).
1086
1087 %%% @doc The `mam_muc_get_prefs' hook is called to read
1088 %%% the archive settings for a given room.
1089 -spec mam_muc_get_prefs(HostType, DefaultMode, ArchiveID, Room) -> Result when
1090 HostType :: mongooseim:host_type(),
1091 DefaultMode :: mod_mam:archive_behaviour(),
1092 ArchiveID :: undefined | mod_mam:archive_id(),
1093 Room :: jid:jid(),
1094 Result :: mod_mam:preference() | {error, Reason :: term()}.
1095 mam_muc_get_prefs(HostType, DefaultMode, ArchiveID, Room) ->
1096
:-(
Params = #{archive_id => ArchiveID, room => Room},
1097
:-(
InitialAcc = {DefaultMode, [], []}, %% mod_mam:preference() type
1098
:-(
run_hook_for_host_type(mam_muc_get_prefs, HostType, InitialAcc, Params).
1099
1100 %%% @doc The `mam_muc_remove_archive' hook is called in order to remove the entire
1101 %%% archive for a particular user.
1102 -spec mam_muc_remove_archive(HostType, ArchiveID, Room) -> any() when
1103 HostType :: mongooseim:host_type(),
1104 ArchiveID :: undefined | mod_mam:archive_id(),
1105 Room :: jid:jid().
1106 mam_muc_remove_archive(HostType, ArchiveID, Room) ->
1107 568 Params = #{archive_id => ArchiveID, room => Room},
1108 568 run_hook_for_host_type(mam_muc_remove_archive, HostType, ok, Params).
1109
1110 %%% @doc The `mam_muc_lookup_messages' hook is to retrieve archived
1111 %%% MUC messages for any given search parameters.
1112 -spec mam_muc_lookup_messages(HostType, Params) -> Result when
1113 HostType :: mongooseim:host_type(),
1114 Params :: map(),
1115 Result :: {ok, mod_mam:lookup_result()}.
1116 mam_muc_lookup_messages(HostType, Params) ->
1117 498 InitialLookupValue = {0, 0, []}, %% mod_mam:lookup_result() type
1118 498 run_hook_for_host_type(mam_muc_lookup_messages, HostType, {ok, InitialLookupValue},
1119 Params).
1120
1121 %%% @doc The `mam_muc_archive_message' hook is called in order
1122 %%% to store the MUC message in the archive.
1123 -spec mam_muc_archive_message(HostType, Params) -> Result when
1124 HostType :: mongooseim:host_type(),
1125 Params :: mod_mam:archive_message_params(),
1126 Result :: ok | {error, timeout}.
1127 mam_muc_archive_message(HostType, Params) ->
1128 2522 run_hook_for_host_type(mam_muc_archive_message, HostType, ok, Params).
1129
1130 %%% @doc The `mam_muc_flush_messages' hook is run after the async bulk write
1131 %%% happens for MUC messages despite the result of the write.
1132 -spec mam_muc_flush_messages(HostType :: mongooseim:host_type(),
1133 MessageCount :: integer()) -> ok.
1134 mam_muc_flush_messages(HostType, MessageCount) ->
1135 467 Params = #{count => MessageCount},
1136 467 run_hook_for_host_type(mam_muc_flush_messages, HostType, ok, Params).
1137
1138 %% @doc Waits until all pending messages are written
1139 -spec mam_muc_archive_sync(HostType :: mongooseim:host_type()) -> ok.
1140 mam_muc_archive_sync(HostType) ->
1141 152 run_hook_for_host_type(mam_muc_archive_sync, HostType, ok, #{}).
1142
1143 %% @doc Notifies of a muc message retraction
1144 -spec mam_muc_retraction(mongooseim:host_type(),
1145 mod_mam_utils:retraction_info(),
1146 mod_mam:archive_message_params()) ->
1147 mod_mam_utils:retraction_info().
1148 mam_muc_retraction(HostType, RetractionInfo, Env) ->
1149 14 run_hook_for_host_type(mam_muc_retraction, HostType, RetractionInfo, Env).
1150
1151 %% GDPR related hooks
1152
1153 %%% @doc `get_mam_pm_gdpr_data' hook is called to provide
1154 %%% a user's archive for GDPR purposes.
1155 -spec get_mam_pm_gdpr_data(HostType, JID) -> Result when
1156 HostType :: mongooseim:host_type(),
1157 JID :: jid:jid(),
1158 Result :: ejabberd_gen_mam_archive:mam_pm_gdpr_data().
1159 get_mam_pm_gdpr_data(HostType, JID) ->
1160 51 Params = #{jid => JID},
1161 51 run_hook_for_host_type(get_mam_pm_gdpr_data, HostType, [], Params).
1162
1163 %%% @doc `get_mam_muc_gdpr_data' hook is called to provide
1164 %%% a user's archive for GDPR purposes.
1165 -spec get_mam_muc_gdpr_data(HostType, JID) -> Result when
1166 HostType :: mongooseim:host_type(),
1167 JID :: jid:jid(),
1168 Result :: ejabberd_gen_mam_archive:mam_muc_gdpr_data().
1169 get_mam_muc_gdpr_data(HostType, JID) ->
1170 47 Params = #{jid => JID},
1171 47 run_hook_for_host_type(get_mam_muc_gdpr_data, HostType, [], Params).
1172
1173 %%% @doc `get_personal_data' hook is called to retrieve
1174 %%% a user's personal data for GDPR purposes.
1175 -spec get_personal_data(HostType, JID) -> Result when
1176 HostType :: mongooseim:host_type(),
1177 JID :: jid:jid(),
1178 Result :: gdpr:personal_data().
1179 get_personal_data(HostType, JID) ->
1180 87 Params = #{jid => JID},
1181 87 run_hook_for_host_type(get_personal_data, HostType, [], Params).
1182
1183 %% S2S related hooks
1184
1185 %%% @doc `s2s_allow_host' hook is called to check whether a server
1186 %%% should be allowed to be connected to.
1187 %%%
1188 %%% A handler can decide that a server should not be allowed and pass this
1189 %%% information to the caller.
1190 -spec s2s_allow_host(MyHost, S2SHost) -> Result when
1191 MyHost :: jid:server(),
1192 S2SHost :: jid:server(),
1193 Result :: allow | deny.
1194 s2s_allow_host(MyHost, S2SHost) ->
1195 52 Params = #{my_host => MyHost, s2s_host => S2SHost},
1196 52 run_global_hook(s2s_allow_host, allow, Params).
1197
1198 %%% @doc `s2s_send_packet' hook is called when a message is routed.
1199 -spec s2s_send_packet(Acc, From, To, Packet) -> Result when
1200 Acc :: mongoose_acc:t(),
1201 From :: jid:jid(),
1202 To :: jid:jid(),
1203 Packet :: exml:element(),
1204 Result :: mongoose_acc:t().
1205 s2s_send_packet(Acc, From, To, Packet) ->
1206 116 Params = #{from => From, to => To, packet => Packet},
1207 116 run_global_hook(s2s_send_packet, Acc, Params).
1208
1209 %%% @doc `s2s_stream_features' hook is used to extract
1210 %%% the stream management features supported by the server.
1211 -spec s2s_stream_features(HostType, LServer) -> Result when
1212 HostType :: mongooseim:host_type(),
1213 LServer :: jid:lserver(),
1214 Result :: [exml:element()].
1215 s2s_stream_features(HostType, LServer) ->
1216 45 Params = #{lserver => LServer},
1217 45 run_hook_for_host_type(s2s_stream_features, HostType, [], Params).
1218
1219 %%% @doc `s2s_receive_packet' hook is called when
1220 %%% an incoming stanza is routed by the server.
1221 -spec s2s_receive_packet(Acc) -> Result when
1222 Acc :: mongoose_acc:t(),
1223 Result :: mongoose_acc:t().
1224 s2s_receive_packet(Acc) ->
1225 80 run_global_hook(s2s_receive_packet, Acc, #{}).
1226
1227 %% Discovery related hooks
1228
1229 %%% @doc `disco_local_identity' hook is called to get the identity of the server.
1230 -spec disco_local_identity(mongoose_disco:identity_acc()) ->
1231 mongoose_disco:identity_acc().
1232 disco_local_identity(Acc = #{host_type := HostType}) ->
1233 234 run_hook_for_host_type(disco_local_identity, HostType, Acc, #{}).
1234
1235 %%% @doc `disco_sm_identity' hook is called to get the identity of the
1236 %%% client when a discovery IQ gets to session management.
1237 -spec disco_sm_identity(mongoose_disco:identity_acc()) -> mongoose_disco:identity_acc().
1238 disco_sm_identity(Acc = #{host_type := HostType}) ->
1239 33 run_hook_for_host_type(disco_sm_identity, HostType, Acc, #{}).
1240
1241 %%% @doc `disco_local_items' hook is called to extract items associated with the server.
1242 -spec disco_local_items(mongoose_disco:item_acc()) -> mongoose_disco:item_acc().
1243 disco_local_items(Acc = #{host_type := HostType}) ->
1244 45 run_hook_for_host_type(disco_local_items, HostType, Acc, #{}).
1245
1246 %%% @doc `disco_sm_items' hook is called to get the items associated
1247 %%% with the client when a discovery IQ gets to session management.
1248 -spec disco_sm_items(mongoose_disco:item_acc()) -> mongoose_disco:item_acc().
1249 disco_sm_items(Acc = #{host_type := HostType}) ->
1250 13 run_hook_for_host_type(disco_sm_items, HostType, Acc, #{}).
1251
1252 %%% @doc `disco_local_features' hook is called to extract features
1253 %%% offered by the server.
1254 -spec disco_local_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc().
1255 disco_local_features(Acc = #{host_type := HostType}) ->
1256 234 run_hook_for_host_type(disco_local_features, HostType, Acc, #{}).
1257
1258 %%% @doc `disco_sm_features' hook is called to get the features of the client
1259 %%% when a discovery IQ gets to session management.
1260 -spec disco_sm_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc().
1261 disco_sm_features(Acc = #{host_type := HostType}) ->
1262 33 run_hook_for_host_type(disco_sm_features, HostType, Acc, #{}).
1263
1264 %%% @doc `disco_muc_features' hook is called to get the features
1265 %%% supported by the MUC (Light) service.
1266 -spec disco_muc_features(mongoose_disco:feature_acc()) -> mongoose_disco:feature_acc().
1267 disco_muc_features(Acc = #{host_type := HostType}) ->
1268 29 run_hook_for_host_type(disco_muc_features, HostType, Acc, #{}).
1269
1270 %%% @doc `disco_info' hook is called to extract information about the server.
1271 -spec disco_info(mongoose_disco:info_acc()) -> mongoose_disco:info_acc().
1272 disco_info(Acc = #{host_type := HostType}) ->
1273 255 run_hook_for_host_type(disco_info, HostType, Acc, #{}).
1274
1275 %% AMP related hooks
1276
1277 %%% @doc The `amp_check_condition' hook is called to determine whether
1278 %%% the AMP strategy matches the given AMP rule.
1279 -spec amp_check_condition(HostType, Strategy, Rule) -> Result when
1280 HostType :: mongooseim:host_type(),
1281 Strategy :: mod_amp:amp_strategy(),
1282 Rule :: mod_amp:amp_rule(),
1283 Result :: mod_amp:amp_match_result().
1284 amp_check_condition(HostType, Strategy, Rule) ->
1285 544 Params = #{strategy => Strategy, rule => Rule},
1286 544 InitialAcc = no_match, %% mod_amp:amp_match_result() type
1287 544 run_hook_for_host_type(amp_check_condition, HostType, InitialAcc, Params).
1288
1289 %%% @doc The `amp_determine_strategy' hook is called when checking to determine
1290 %%% which strategy will be chosen when executing AMP rules.
1291 -spec amp_determine_strategy(HostType, From, To, Packet, Event) -> Result when
1292 HostType :: mongooseim:host_type(),
1293 From :: jid:jid(),
1294 To :: jid:jid() | undefined,
1295 Packet :: exml:element(),
1296 Event :: mod_amp:amp_event(),
1297 Result :: mod_amp:amp_strategy().
1298 amp_determine_strategy(HostType, From, To, Packet, Event) ->
1299 566 Params = #{from => From, to => To, packet => Packet, event => Event},
1300 566 DefaultStrategy = amp_strategy:null_strategy(),
1301 566 run_hook_for_host_type(amp_determine_strategy, HostType, DefaultStrategy, Params).
1302
1303 %%% @doc The `amp_verify_support' hook is called when checking
1304 %%% whether the host supports given AMP rules.
1305 -spec amp_verify_support(HostType, Rules) -> Result when
1306 HostType :: mongooseim:host_type(),
1307 Rules :: mod_amp:amp_rules(),
1308 Result :: [mod_amp:amp_rule_support()].
1309 amp_verify_support(HostType, Rules) ->
1310 271 Params = #{rules => Rules},
1311 271 run_hook_for_host_type(amp_verify_support, HostType, [], Params).
1312
1313 %% MUC and MUC Light related hooks
1314
1315 -spec filter_room_packet(HostType, Packet, EventData) -> Result when
1316 HostType :: mongooseim:host_type(),
1317 Packet :: exml:element(),
1318 EventData :: mod_muc:room_event_data(),
1319 Result :: exml:element().
1320 filter_room_packet(HostType, Packet, EventData) ->
1321 1350 run_hook_for_host_type(filter_room_packet, HostType, Packet, EventData).
1322
1323 %%% @doc The `forget_room' hook is called when a room is removed from the database.
1324 -spec forget_room(HostType, MucHost, Room) -> Result when
1325 HostType :: mongooseim:host_type(),
1326 MucHost :: jid:server(),
1327 Room :: jid:luser(),
1328 Result :: any().
1329 forget_room(HostType, MucHost, Room) ->
1330 465 Params = #{muc_host => MucHost, room => Room},
1331 465 run_hook_for_host_type(forget_room, HostType, #{}, Params).
1332
1333 -spec invitation_sent(HookServer, Host, RoomJID, From, To, Reason) -> Result when
1334 HookServer :: jid:server(),
1335 Host :: jid:server(),
1336 RoomJID :: jid:jid(),
1337 From :: jid:jid(),
1338 To :: jid:jid(),
1339 Reason :: binary(),
1340 Result :: any().
1341 invitation_sent(HookServer, Host, RoomJID, From, To, Reason) ->
1342 11 Params = #{host => Host, room_jid => RoomJID, from => From, to => To, reason => Reason},
1343 11 run_hook_for_host_type(invitation_sent, HookServer, ok, Params).
1344
1345 %%% @doc The `join_room' hook is called when a user joins a MUC room.
1346 -spec join_room(HookServer, Room, Host, JID, MucJID) -> Result when
1347 HookServer :: jid:server(),
1348 Room :: mod_muc:room(),
1349 Host :: jid:server(),
1350 JID :: jid:jid(),
1351 MucJID :: jid:jid(),
1352 Result :: any().
1353 join_room(HookServer, Room, Host, JID, MucJID) ->
1354 701 Params = #{room => Room, host => Host, jid => JID, muc_jid => MucJID},
1355 701 run_hook_for_host_type(join_room, HookServer, ok, Params).
1356
1357 %%% @doc The `leave_room' hook is called when a user joins a MUC room.
1358 -spec leave_room(HookServer, Room, Host, JID, MucJID) -> Result when
1359 HookServer :: jid:server(),
1360 Room :: mod_muc:room(),
1361 Host :: jid:server(),
1362 JID :: jid:jid(),
1363 MucJID :: jid:jid(),
1364 Result :: any().
1365 leave_room(HookServer, Room, Host, JID, MucJID) ->
1366 639 Params = #{room => Room, host => Host, jid => JID, muc_jid => MucJID},
1367 639 run_hook_for_host_type(leave_room, HookServer, ok, Params).
1368
1369 %%% @doc The `room_packet' hook is called when a message is added to room's history.
1370 -spec room_packet(Server, FromNick, FromJID, JID, Packet) -> Result when
1371 Server :: jid:lserver(),
1372 FromNick :: mod_muc:nick(),
1373 FromJID :: jid:jid(),
1374 JID :: jid:jid(),
1375 Packet :: exml:element(),
1376 Result :: any().
1377 room_packet(Server, FromNick, FromJID, JID, Packet) ->
1378 394 Params = #{from_nick => FromNick, from_jid => FromJID, jid => JID, packet => Packet},
1379 394 run_hook_for_host_type(room_packet, Server, ok, Params).
1380
1381 -spec update_inbox_for_muc(HostType, Info) -> Result when
1382 HostType :: mongooseim:host_type(),
1383 Info :: mod_muc_room:update_inbox_for_muc_payload(),
1384 Result :: mod_muc_room:update_inbox_for_muc_payload().
1385 update_inbox_for_muc(HostType, Info) ->
1386 394 run_hook_for_host_type(update_inbox_for_muc, HostType, Info, #{}).
1387
1388 %% Caps related hooks
1389
1390 -spec caps_recognised(Acc, From, Pid, Features) -> Result when
1391 Acc :: mongoose_acc:t(),
1392 From :: jid:jid(),
1393 Pid :: pid(),
1394 Features :: unknown | list(),
1395 Result :: mongoose_acc:t().
1396 caps_recognised(Acc, From, Pid, Features) ->
1397 9 Params = #{from => From, pid => Pid, features => Features},
1398 9 HostType = mongoose_acc:host_type(Acc),
1399 9 run_hook_for_host_type(caps_recognised, HostType, Acc, Params).
1400
1401 %% Global distribution related hooks
1402
1403 %%% @doc The `mod_global_distrib_known_recipient' hook is called when
1404 %%% the recipient is known to `global_distrib'.
1405 -spec mod_global_distrib_known_recipient(GlobalHost, From, To, LocalHost) -> Result when
1406 GlobalHost :: jid:server(),
1407 From :: jid:jid(),
1408 To :: jid:jid(),
1409 LocalHost :: jid:server(),
1410 Result :: any().
1411 mod_global_distrib_known_recipient(GlobalHost, From, To, LocalHost) ->
1412 747 Params = #{from => From, to => To, target_host => LocalHost},
1413 747 run_hook_for_host_type(mod_global_distrib_known_recipient, GlobalHost, ok, Params).
1414
1415 %%% @doc The `mod_global_distrib_unknown_recipient' hook is called when
1416 %%% the recipient is unknown to `global_distrib'.
1417 -spec mod_global_distrib_unknown_recipient(GlobalHost, Info) -> Result when
1418 GlobalHost :: jid:server(),
1419 Info :: filter_packet_acc(),
1420 Result :: any().
1421 mod_global_distrib_unknown_recipient(GlobalHost, Info) ->
1422 54 run_hook_for_host_type(mod_global_distrib_unknown_recipient, GlobalHost, Info, #{}).
1423
1424
1425 %%%----------------------------------------------------------------------
1426 %%% Internal functions
1427 %%%----------------------------------------------------------------------
1428 run_global_hook(HookName, Acc, Params) when is_map(Params) ->
1429 59447 run_fold(HookName, global, Acc, Params).
1430
1431 run_hook_for_host_type(HookName, undefined, Acc, Args) ->
1432
:-(
?LOG_ERROR(#{what => undefined_host_type,
1433 text => <<"Running hook for an undefined host type">>,
1434
:-(
hook_name => HookName, hook_acc => Acc, hook_args => Args}),
1435
:-(
Acc;
1436 run_hook_for_host_type(HookName, HostType, Acc, Params) when is_binary(HostType),
1437 is_map(Params) ->
1438 267731 run_fold(HookName, HostType, Acc, Params).
1439
1440 run_fold(HookName, HostType, Acc, Params) when is_map(Params) ->
1441 327178 {_, RetValue} = gen_hook:run_fold(HookName, HostType, Acc, Params),
1442 327177 RetValue.
Line Hits Source