./ct_report/coverage/mod_inbox_muclight.COVER.html

1 %%%-------------------------------------------------------------------
2 %%% @copyright (C) 2018, Erlang-Solutions
3 %%% @doc
4 %%%
5 %%% @end
6 %%% Created : 30. Jan 2018 13:22
7 %%%-------------------------------------------------------------------
8 -module(mod_inbox_muclight).
9
10 -include("mod_muc_light.hrl").
11 -include("jlib.hrl").
12 -include("mongoose.hrl").
13
14 -export([handle_outgoing_message/5, handle_incoming_message/5]).
15
16 -type role() :: r_member() | r_owner() | r_none().
17 -type r_member() :: binary().
18 -type r_owner() :: binary().
19 -type r_none() :: binary().
20
21 -spec handle_outgoing_message(HostType :: mongooseim:host_type(),
22 User :: jid:jid(),
23 Room :: jid:jid(),
24 Packet :: exml:element(),
25 Acc :: mongoose_acc:t()) ->
26 mod_inbox:count_res().
27 handle_outgoing_message(HostType, User, Room, Packet, Acc) ->
28 191 mod_inbox_utils:maybe_reset_unread_count(HostType, User, Room, Packet, Acc).
29
30 -spec handle_incoming_message(HostType :: mongooseim:host_type(),
31 RoomUser :: jid:jid(),
32 Remote :: jid:jid(),
33 Packet :: exml:element(),
34 Acc :: mongoose_acc:t()) ->
35 mod_inbox:count_res().
36 handle_incoming_message(HostType, RoomUser, Remote, Packet, Acc) ->
37 899 case mod_inbox_utils:has_chat_marker(Packet) of
38 true ->
39 %% don't store chat markers in inbox
40 459 ok;
41 false ->
42 440 maybe_handle_system_message(HostType, RoomUser, Remote, Packet, Acc)
43 end.
44
45 -spec maybe_handle_system_message(HostType :: mongooseim:host_type(),
46 RoomOrUser :: jid:jid(),
47 Receiver :: jid:jid(),
48 Packet :: exml:element(),
49 Acc :: mongoose_acc:t()) ->
50 mod_inbox:count_res().
51 maybe_handle_system_message(HostType, RoomOrUser, Receiver, Packet, Acc) ->
52 440 case is_system_message(HostType, RoomOrUser, Receiver, Packet) of
53 true ->
54 328 handle_system_message(HostType, RoomOrUser, Receiver, Packet, Acc);
55 _ ->
56 112 Sender = jid:from_binary(RoomOrUser#jid.lresource),
57 112 write_to_inbox(HostType, RoomOrUser, Receiver, Sender, Packet, Acc)
58 end.
59
60 -spec handle_system_message(HostType :: mongooseim:host_type(),
61 Room :: jid:jid(),
62 Remote :: jid:jid(),
63 Packet :: exml:element(),
64 Acc :: mongoose_acc:t()) -> ok.
65 handle_system_message(HostType, Room, Remote, Packet, Acc) ->
66 328 case system_message_type(Remote, Packet) of
67 kick ->
68 61 handle_kicked_message(HostType, Room, Remote, Packet, Acc);
69 invite ->
70 170 handle_invitation_message(HostType, Room, Remote, Packet, Acc);
71 other ->
72 97 ?LOG_DEBUG(#{what => irrelevant_system_message_for_mod_inbox_muclight,
73 97 room => Room, exml_packet => Packet}),
74 97 ok
75 end.
76
77 -spec handle_invitation_message(HostType :: mongooseim:host_type(),
78 Room :: jid:jid(),
79 Remote :: jid:jid(),
80 Packet :: exml:element(),
81 Acc :: mongoose_acc:t()) -> ok.
82 handle_invitation_message(HostType, Room, Remote, Packet, Acc) ->
83 170 maybe_store_system_message(HostType, Room, Remote, Packet, Acc).
84
85 -spec handle_kicked_message(HostType :: mongooseim:host_type(),
86 Room :: jid:jid(),
87 Remote :: jid:jid(),
88 Packet :: exml:element(),
89 Acc :: mongoose_acc:t()) -> ok.
90 handle_kicked_message(HostType, Room, Remote, Packet, Acc) ->
91 61 CheckRemove = mod_inbox_utils:get_option_remove_on_kicked(HostType),
92 61 maybe_store_system_message(HostType, Room, Remote, Packet, Acc),
93 61 maybe_remove_inbox_row(HostType, Room, Remote, CheckRemove).
94
95 -spec maybe_store_system_message(HostType :: mongooseim:host_type(),
96 Room :: jid:jid(),
97 Remote :: jid:jid(),
98 Packet :: exml:element(),
99 Acc :: mongoose_acc:t()) -> ok.
100 maybe_store_system_message(HostType, Room, Remote, Packet, Acc) ->
101 231 WriteAffChanges = mod_inbox_utils:get_option_write_aff_changes(HostType),
102 231 case WriteAffChanges of
103 true ->
104 217 write_to_inbox(HostType, Room, Remote, Room, Packet, Acc);
105 false ->
106 14 ok
107 end.
108
109 -spec maybe_remove_inbox_row(HostType :: mongooseim:host_type(),
110 Room :: jid:jid(),
111 Remote :: jid:jid(),
112 WriteAffChanges :: boolean()) -> ok.
113 maybe_remove_inbox_row(_, _, _, false) ->
114 4 ok;
115 maybe_remove_inbox_row(HostType, Room, Remote, true) ->
116 57 InboxEntryKey = mod_inbox_utils:build_inbox_entry_key(Remote, Room),
117 57 ok = mod_inbox_backend:remove_inbox_row(HostType, InboxEntryKey).
118
119 -spec write_to_inbox(HostType :: mongooseim:host_type(),
120 RoomUser :: jid:jid(),
121 Remote :: jid:jid(),
122 Sender :: jid:jid(),
123 Packet :: exml:element(),
124 Acc :: mongoose_acc:t()) ->
125 mod_inbox:count_res().
126 write_to_inbox(HostType, RoomUser, Remote, Sender, Packet, Acc) ->
127 329 case jid:are_equal(Remote, Sender) of
128 38 true -> mod_inbox_utils:write_to_sender_inbox(HostType, Remote, RoomUser, Packet, Acc);
129 291 false -> mod_inbox_utils:write_to_receiver_inbox(HostType, RoomUser, Remote, Packet, Acc)
130 end.
131
132 %%%%%%%
133 %% Predicate funs
134
135 %% @doc Check if sender is just 'roomname@muclight.domain' with no resource
136 %% TODO: Replace sender domain check with namespace check - current logic won't handle all cases!
137 -spec is_system_message(HostType :: mongooseim:host_type(),
138 Sender :: jid:jid(),
139 Receiver :: jid:jid(),
140 Packet :: exml:element()) -> boolean().
141 is_system_message(_HostType, #jid{lresource = <<>>}, _Receiver, _Packet) ->
142 328 true;
143 is_system_message(_HostType, #jid{lresource = _RoomUser}, _Receiver, _Packet) ->
144 112 false.
145
146 -spec is_change_aff_message(jid:jid(), exml:element(), role()) -> boolean().
147 is_change_aff_message(User, Packet, Role) ->
148 984 AffItems = exml_query:paths(Packet, [{element_with_ns, ?NS_MUC_LIGHT_AFFILIATIONS},
149 {element, <<"user">>}]),
150 984 AffList = get_users_with_affiliation(AffItems, Role),
151 984 Jids = [Jid || #xmlel{children = [#xmlcdata{content = Jid}]} <- AffList],
152 984 UserBin = jid:to_binary(jid:to_lower(jid:to_bare(User))),
153 984 lists:member(UserBin, Jids).
154
155 -spec system_message_type(User :: jid:jid(), Packet :: exml:element()) -> invite | kick | other.
156 system_message_type(User, Packet) ->
157 328 case {is_invitation_message(User, Packet),
158 is_new_owner_message(User, Packet),
159 is_kicked_message(User, Packet)} of
160 104 {true, _, _} -> invite;
161 66 {_, true, _} -> invite;
162 61 {_, _, true} -> kick;
163 97 _ -> other
164 end.
165
166 -spec is_invitation_message(jid:jid(), exml:element()) -> boolean().
167 is_invitation_message(User, Packet) ->
168 328 is_change_aff_message(User, Packet, <<"member">>).
169
170 -spec is_new_owner_message(jid:jid(), exml:element()) -> boolean().
171 is_new_owner_message(User, Packet) ->
172 328 is_change_aff_message(User, Packet, <<"owner">>).
173
174 -spec is_kicked_message(jid:jid(), exml:element()) -> boolean().
175 is_kicked_message(User, Packet) ->
176 328 is_change_aff_message(User, Packet, <<"none">>).
177
178 -spec get_users_with_affiliation(list(exml:element()), role()) -> list(exml:element()).
179 get_users_with_affiliation(AffItems, Role) ->
180 984 [M || #xmlel{name = <<"user">>, attrs = [{<<"affiliation">>, R}]} = M <- AffItems, R == Role].
Line Hits Source