Make fetching roster in mod_privacy lazy

This commit is contained in:
Paweł Chmielowski 2021-02-16 10:57:55 +01:00
parent 8cb7ff7a88
commit fad14ff319
1 changed files with 39 additions and 30 deletions

View File

@ -607,34 +607,28 @@ do_check_packet(#jid{luser = LUser, lserver = LServer}, List, Packet, Dir) ->
in -> jid:tolower(From); in -> jid:tolower(From);
out -> jid:tolower(To) out -> jid:tolower(To)
end, end,
{Subscription, _Ask, Groups} = ejabberd_hooks:run_fold( check_packet_aux(List, PType2, LJID, [LUser, LServer])
roster_get_jid_info, LServer,
{none, none, []},
[LUser, LServer, LJID]),
check_packet_aux(List, PType2, LJID, Subscription, Groups)
end. end.
-spec check_packet_aux([listitem()], -spec check_packet_aux([listitem()],
message | iq | presence_in | presence_out | other, message | iq | presence_in | presence_out | other,
ljid(), none | both | from | to, [binary()]) -> ljid(), none | {none | both | from | to, [binary()]}) ->
allow | deny. allow | deny.
%% Ptype = message | iq | presence_in | presence_out | other %% Ptype = message | iq | presence_in | presence_out | other
check_packet_aux([], _PType, _JID, _Subscription, check_packet_aux([], _PType, _JID, _RosterInfo) ->
_Groups) ->
allow; allow;
check_packet_aux([Item | List], PType, JID, check_packet_aux([Item | List], PType, JID, RosterInfo) ->
Subscription, Groups) ->
#listitem{type = Type, value = Value, action = Action} = #listitem{type = Type, value = Value, action = Action} =
Item, Item,
case is_ptype_match(Item, PType) of case is_ptype_match(Item, PType) of
true -> true ->
case is_type_match(Type, Value, JID, Subscription, Groups) of case is_type_match(Type, Value, JID, RosterInfo) of
true -> Action; {true, _} -> Action;
false -> {false, RI} ->
check_packet_aux(List, PType, JID, Subscription, Groups) check_packet_aux(List, PType, JID, RI)
end; end;
false -> false ->
check_packet_aux(List, PType, JID, Subscription, Groups) check_packet_aux(List, PType, JID, RosterInfo)
end. end.
-spec is_ptype_match(listitem(), -spec is_ptype_match(listitem(),
@ -654,32 +648,47 @@ is_ptype_match(Item, PType) ->
end. end.
-spec is_type_match(none | jid | subscription | group, listitem_value(), -spec is_type_match(none | jid | subscription | group, listitem_value(),
ljid(), none | both | from | to, [binary()]) -> boolean(). ljid(), [binary()] | {none | both | from | to, [binary()]}) ->
is_type_match(none, _Value, _JID, _Subscription, _Groups) -> {boolean(), [binary()] | {none | both | from | to, [binary()]}}.
true; is_type_match(none, _Value, _JID, RosterInfo) ->
is_type_match(jid, Value, JID, _Subscription, _Groups) -> {true, RosterInfo};
is_type_match(jid, Value, JID, RosterInfo) ->
case Value of case Value of
{<<"">>, Server, <<"">>} -> {<<"">>, Server, <<"">>} ->
case JID of case JID of
{_, Server, _} -> true; {_, Server, _} -> {true, RosterInfo};
_ -> false _ -> {false, RosterInfo}
end; end;
{User, Server, <<"">>} -> {User, Server, <<"">>} ->
case JID of case JID of
{User, Server, _} -> true; {User, Server, _} -> {true, RosterInfo};
_ -> false _ -> {false, RosterInfo}
end; end;
{<<"">>, Server, Resource} -> {<<"">>, Server, Resource} ->
case JID of case JID of
{_, Server, Resource} -> true; {_, Server, Resource} -> {true, RosterInfo};
_ -> false _ -> {false, RosterInfo}
end; end;
_ -> Value == JID _ -> {Value == JID, RosterInfo}
end; end;
is_type_match(subscription, Value, _JID, Subscription, _Groups) -> is_type_match(subscription, Value, JID, RosterInfo) ->
Value == Subscription; {Subscription, _} = RI = resolve_roster_info(JID, RosterInfo),
is_type_match(group, Group, _JID, _Subscription, Groups) -> {Value == Subscription, RI};
lists:member(Group, Groups). is_type_match(group, Group, JID, RosterInfo) ->
{_, Groups} = RI = resolve_roster_info(JID, RosterInfo),
{lists:member(Group, Groups), RI}.
-spec resolve_roster_info(ljid(), [binary()] | {none | both | from | to, [binary()]}) ->
{none | both | from | to, [binary()]}.
resolve_roster_info(JID, [LUser, LServer]) ->
{Subscription, _Ask, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, LServer,
{none, none, []},
[LUser, LServer, JID]),
{Subscription, Groups};
resolve_roster_info(_, RosterInfo) ->
RosterInfo.
-spec remove_user(binary(), binary()) -> ok. -spec remove_user(binary(), binary()) -> ok.
remove_user(User, Server) -> remove_user(User, Server) ->