diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2019-06-20 19:18:14 +0300 |
---|---|---|
committer | Holger Weiss <holger@zedat.fu-berlin.de> | 2019-06-20 19:18:14 +0300 |
commit | 026540f7e6d487b67b11d088d521776fe84e9d23 (patch) | |
tree | 6e7df657c773f15a60b384ef54d2cad808fddf2e | |
parent | 27a1771deba502de1894d2f7772914fe8eedc3db (diff) |
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 Hörist for spotting this.
-rw-r--r-- | src/mod_pubsub.erl | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index c65b90c60..a3c7bf356 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -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). |