mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
mod_pubsub: Check access_model when publishing PEP
Don't just adhere to the node's access_model when delivering the last PEP item but also when a new item is published. Many thanks to Philipp Hrist for spotting this.
This commit is contained in:
parent
27a1771deb
commit
026540f7e6
@ -2869,21 +2869,23 @@ broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, Nidx, Type, NodeO
|
||||
%% set the from address on the notification to the bare JID of the account owner
|
||||
%% Also, add "replyto" if entity has presence subscription to the account owner
|
||||
%% See XEP-0163 1.1 section 4.3.1
|
||||
FromBareJid = xmpp:set_from(BaseStanza, jid:make(LUser, LServer)),
|
||||
Owner = jid:make(LUser, LServer),
|
||||
FromBareJid = xmpp:set_from(BaseStanza, Owner),
|
||||
Stanza = add_extended_headers(
|
||||
add_message_type(FromBareJid, NotificationType),
|
||||
extended_headers([Publisher])),
|
||||
Pred = fun(To) -> delivery_permitted(Owner, To, NodeOptions) end,
|
||||
ejabberd_sm:route(jid:make(LUser, LServer, SenderResource),
|
||||
{pep_message, <<((Node))/binary, "+notify">>, Stanza}),
|
||||
{pep_message, <<((Node))/binary, "+notify">>, Stanza, Pred}),
|
||||
ejabberd_router:route(xmpp:set_to(Stanza, jid:make(LUser, LServer)));
|
||||
broadcast_stanza(Host, _Publisher, Node, Nidx, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) ->
|
||||
broadcast_stanza(Host, Node, Nidx, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM).
|
||||
|
||||
-spec c2s_handle_info(ejabberd_c2s:state(), term()) -> ejabberd_c2s:state().
|
||||
c2s_handle_info(#{lserver := LServer} = C2SState,
|
||||
{pep_message, Feature, Packet}) ->
|
||||
{pep_message, Feature, Packet, Pred}) when is_function(Pred) ->
|
||||
[maybe_send_pep_stanza(LServer, USR, Caps, Feature, Packet)
|
||||
|| {USR, Caps} <- mod_caps:list_features(C2SState)],
|
||||
|| {USR, Caps} <- mod_caps:list_features(C2SState), Pred(USR)],
|
||||
{stop, C2SState};
|
||||
c2s_handle_info(#{lserver := LServer} = C2SState,
|
||||
{pep_message, Feature, Packet, USR}) ->
|
||||
@ -2990,27 +2992,17 @@ send_last_pep(From, To) ->
|
||||
Host = host(ServerHost),
|
||||
Publisher = jid:tolower(From),
|
||||
Owner = jid:remove_resource(Publisher),
|
||||
RecipientIsOwner = jid:remove_resource(jid:tolower(To)) == Owner,
|
||||
lists:foreach(
|
||||
fun(#pubsub_node{nodeid = {_, Node}, type = Type, id = Nidx, options = Options}) ->
|
||||
case match_option(Options, send_last_published_item, on_sub_and_presence) of
|
||||
true ->
|
||||
LJID = jid:tolower(To),
|
||||
Subscribed = case get_option(Options, access_model) of
|
||||
open -> true;
|
||||
presence -> true;
|
||||
%% TODO: Fix the 'whitelist'/'authorize'
|
||||
%% cases. Currently, only node owners
|
||||
%% receive last PEP notifications.
|
||||
whitelist -> RecipientIsOwner;
|
||||
authorize -> RecipientIsOwner;
|
||||
roster ->
|
||||
Grps = get_option(Options, roster_groups_allowed, []),
|
||||
{OU, OS, _} = Owner,
|
||||
element(2, get_roster_info(OU, OS, LJID, Grps))
|
||||
end,
|
||||
if Subscribed -> send_items(Owner, Node, Nidx, Type, Options, Publisher, LJID, LJID, 1);
|
||||
true -> ok
|
||||
case delivery_permitted(From, To, Options) of
|
||||
true ->
|
||||
LJID = jid:tolower(To),
|
||||
send_items(Owner, Node, Nidx, Type, Options,
|
||||
Publisher, LJID, LJID, 1);
|
||||
false ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
@ -3078,6 +3070,26 @@ subscribed_nodes_by_jid(NotifyType, SubsByDepth) ->
|
||||
{_, JIDSubs} = lists:foldl(DepthsToDeliver, {[], []}, SubsByDepth),
|
||||
JIDSubs.
|
||||
|
||||
-spec delivery_permitted(jid() | ljid(), jid() | ljid(), nodeOptions())
|
||||
-> boolean().
|
||||
delivery_permitted(From, To, Options) ->
|
||||
LFrom = jid:tolower(From),
|
||||
LTo = jid:tolower(To),
|
||||
RecipientIsOwner = jid:remove_resource(LFrom) == jid:remove_resource(LTo),
|
||||
%% TODO: Fix the 'whitelist'/'authorize' cases for last PEP notifications.
|
||||
%% Currently, only node owners receive those.
|
||||
case get_option(Options, access_model) of
|
||||
open -> true;
|
||||
presence -> true;
|
||||
whitelist -> RecipientIsOwner;
|
||||
authorize -> RecipientIsOwner;
|
||||
roster ->
|
||||
Grps = get_option(Options, roster_groups_allowed, []),
|
||||
{LUser, LServer, _} = LFrom,
|
||||
{_, IsInGrp} = get_roster_info(LUser, LServer, LTo, Grps),
|
||||
IsInGrp
|
||||
end.
|
||||
|
||||
-spec user_resources(binary(), binary()) -> [binary()].
|
||||
user_resources(User, Server) ->
|
||||
ejabberd_sm:get_user_resources(User, Server).
|
||||
|
Loading…
Reference in New Issue
Block a user