From c8cba04f052a1a2ed977307e14b1775f574f6bcb Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Thu, 6 Jun 2013 11:11:37 +0200 Subject: [PATCH] access_createnode acl also applies to auto created nodes ported to pubsub_odbc --- src/mod_pubsub/mod_pubsub_odbc.erl | 11 +-- src/mod_pubsub/pubsub_odbc.patch | 148 ++++++++++++++++------------- 2 files changed, 87 insertions(+), 72 deletions(-) diff --git a/src/mod_pubsub/mod_pubsub_odbc.erl b/src/mod_pubsub/mod_pubsub_odbc.erl index 3396570a4..d803395d0 100644 --- a/src/mod_pubsub/mod_pubsub_odbc.erl +++ b/src/mod_pubsub/mod_pubsub_odbc.erl @@ -1633,7 +1633,7 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) -> [#xmlel{name = <<"item">>, attrs = ItemAttrs, children = Payload}] -> ItemId = xml:get_attr_s(<<"id">>, ItemAttrs), - publish_item(Host, ServerHost, Node, From, ItemId, Payload); + publish_item(Host, ServerHost, Node, From, ItemId, Payload, Access); [] -> {error, extended_error(?ERR_BAD_REQUEST, <<"item-required">>)}; @@ -2610,8 +2610,10 @@ unsubscribe_node(Host, Node, From, Subscriber, SubId) -> | {error, xmlel()} ). publish_item(Host, ServerHost, Node, Publisher, <<>>, Payload) -> - publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload); + publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload, all); publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> + publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, all). +publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, Access) -> Action = fun (#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PublishFeature = lists:member(<<"publish">>, Features), @@ -2704,7 +2706,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> Type = select_type(ServerHost, Host, Node), case lists:member("auto-create", features(Type)) of true -> - case create_node(Host, ServerHost, Node, Publisher, Type) of + case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of {result, [#xmlel{name = <<"pubsub">>, attrs = [{<<"xmlns">>, ?NS_PUBSUB}], children = @@ -4238,9 +4240,6 @@ node_options(Type) -> jlib:binary_to_atom(<<(?PLUGIN_PREFIX)/binary, Type/binary>>), case catch Module:options() of -%% @spec (Host, Type, NodeId) -> [ljid()] -%% NodeId = pubsubNodeId() -%% @doc

Return list of node owners.

{'EXIT', {undef, _}} -> DefaultModule = jlib:binary_to_atom(<<(?PLUGIN_PREFIX)/binary, diff --git a/src/mod_pubsub/pubsub_odbc.patch b/src/mod_pubsub/pubsub_odbc.patch index 986c6fe00..d6385dce7 100644 --- a/src/mod_pubsub/pubsub_odbc.patch +++ b/src/mod_pubsub/pubsub_odbc.patch @@ -1,6 +1,6 @@ ---- mod_pubsub.erl 2013-03-03 23:32:53.669953265 +0100 -+++ mod_pubsub_odbc.erl 2013-03-03 23:37:10.128953065 +0100 -@@ -41,7 +41,7 @@ +--- mod_pubsub.erl 2013-06-06 11:08:12.333599362 +0200 ++++ mod_pubsub_odbc.erl 2013-06-06 11:09:59.073591158 +0200 +@@ -43,7 +43,7 @@ %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see %%% XEP-0060 section 12.18. @@ -9,7 +9,7 @@ -author('christophe.romain@process-one.net'). -@@ -59,11 +59,11 @@ +@@ -61,11 +61,11 @@ -include("pubsub.hrl"). @@ -24,7 +24,7 @@ %% exports for hooks -export([presence_probe/3, caps_update/3, -@@ -98,7 +98,7 @@ +@@ -100,7 +100,7 @@ -export([subscription_to_string/1, affiliation_to_string/1, string_to_subscription/1, string_to_affiliation/1, extended_error/2, extended_error/3, @@ -33,7 +33,7 @@ %% API and gen_server callbacks -export([start_link/2, start/2, stop/1, init/1, -@@ -108,7 +108,7 @@ +@@ -110,7 +110,7 @@ %% calls for parallel sending of last items -export([send_loop/1]). @@ -42,7 +42,7 @@ -define(LOOPNAME, ejabberd_mod_pubsub_loop). -@@ -333,8 +333,6 @@ +@@ -349,8 +349,6 @@ false -> ok end, ejabberd_router:register_route(Host), @@ -51,7 +51,7 @@ put(server_host, ServerHost), init_nodes(Host, ServerHost, NodeTree, Plugins), State = #state{host = Host, server_host = ServerHost, -@@ -394,359 +392,14 @@ +@@ -423,359 +421,14 @@ ok. init_nodes(Host, ServerHost, _NodeTree, Plugins) -> @@ -414,7 +414,7 @@ send_loop(State) -> receive {presence, JID, Pid} -> -@@ -755,11 +408,13 @@ +@@ -784,11 +437,13 @@ LJID = jlib:jid_tolower(JID), BJID = jlib:jid_remove_resource(LJID), lists:foreach(fun (PType) -> @@ -432,7 +432,7 @@ lists:foreach(fun ({Node, subscribed, _, SubJID}) -> if (SubJID == LJID) or -@@ -771,24 +426,14 @@ +@@ -800,24 +455,14 @@ type = Type, id = @@ -459,7 +459,7 @@ true -> % resource not concerned about that subscription ok -@@ -979,7 +624,8 @@ +@@ -1008,7 +653,8 @@ children = []}]; disco_identity(Host, Node, From) -> Action = fun (#pubsub_node{id = Idx, type = Type, @@ -469,7 +469,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, -@@ -1031,7 +677,8 @@ +@@ -1060,7 +706,8 @@ || Feature <- features(<<"pep">>)]]; disco_features(Host, Node, From) -> Action = fun (#pubsub_node{id = Idx, type = Type, @@ -479,7 +479,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, -@@ -1076,9 +723,9 @@ +@@ -1105,9 +752,9 @@ ). disco_items(Host, <<>>, From) -> Action = fun (#pubsub_node{nodeid = {_, NodeID}, @@ -491,7 +491,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> [#xmlel{name = <<"item">>, -@@ -1099,13 +746,14 @@ +@@ -1128,13 +775,14 @@ _ -> Acc end end, @@ -508,7 +508,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of -@@ -1209,9 +857,6 @@ +@@ -1238,9 +886,6 @@ lists:foreach(fun ({#pubsub_node{options = Options, @@ -518,7 +518,7 @@ id = NodeId}, subscribed, _, -@@ -1223,7 +868,7 @@ +@@ -1252,7 +897,7 @@ presence -> case lists:member(BJID, @@ -527,7 +527,7 @@ of true -> node_action(Host, -@@ -1442,7 +1087,8 @@ +@@ -1512,7 +1157,8 @@ IQ -> #xmlel{attrs = QAttrs} = SubEl, Node = xml:get_attr_s(<<"node">>, QAttrs), @@ -537,7 +537,7 @@ {result, IQRes} -> jlib:iq_to_xml(IQ#iq{type = result, sub_el = -@@ -1569,7 +1215,7 @@ +@@ -1639,7 +1285,7 @@ % [] -> % [<<"leaf">>]; %% No sub-nodes: it's a leaf node % _ -> @@ -546,7 +546,7 @@ % {result, []} -> [<<"collection">>]; % {result, _} -> [<<"leaf">>, <<"collection">>]; % _ -> [] -@@ -1591,7 +1237,11 @@ +@@ -1661,7 +1307,11 @@ % [#xmlel{name = <<"feature">>, % attrs = [{<<"var">>, ?NS_PUBSUB}], % children = []} @@ -559,7 +559,7 @@ % #xmlel{name = <<"feature">>, % attrs = % [{<<"var">>, -@@ -1616,7 +1266,7 @@ +@@ -1686,7 +1336,7 @@ [] -> [<<"leaf">>]; _ -> case node_call(Type, get_items, @@ -568,7 +568,7 @@ of {result, []} -> [<<"collection">>]; -@@ -1638,7 +1288,11 @@ +@@ -1708,7 +1358,11 @@ F = [#xmlel{name = <<"feature">>, attrs = [{<<"var">>, ?NS_PUBSUB}], children = []} @@ -581,7 +581,7 @@ #xmlel{name = <<"feature">>, attrs = [{<<"var">>, -@@ -1682,7 +1336,11 @@ +@@ -1752,7 +1406,11 @@ #xmlel{name = <<"feature">>, attrs = [{<<"var">>, ?NS_VCARD}], children = []}] ++ @@ -594,7 +594,7 @@ #xmlel{name = <<"feature">>, attrs = [{<<"var">>, <<(?NS_PUBSUB)/binary, "#", Feature/binary>>}], -@@ -1695,14 +1353,15 @@ +@@ -1765,14 +1423,15 @@ _ -> node_disco_info(Host, Node, From) end. @@ -613,7 +613,7 @@ {result, lists:map(fun (#pubsub_node{nodeid = {_, SubNode}, options = Options}) -> -@@ -1739,7 +1398,7 @@ +@@ -1809,7 +1468,7 @@ % Nodes)}; % Other -> Other % end; @@ -622,7 +622,7 @@ CommandItems = [#xmlel{name = <<"item">>, attrs = [{<<"jid">>, Host}, -@@ -1747,22 +1406,19 @@ +@@ -1817,22 +1476,19 @@ {<<"name">>, <<"Get Pending">>}], children = []}], {result, CommandItems}; @@ -651,7 +651,7 @@ end, Nodes = lists:map(fun (#pubsub_node{nodeid = {_, SubNode}, -@@ -1805,7 +1461,7 @@ +@@ -1875,7 +1531,7 @@ children = []} end, NodeItems), @@ -660,7 +660,7 @@ end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; -@@ -1956,7 +1612,8 @@ +@@ -2026,7 +1682,8 @@ (_, Acc) -> Acc end, [], xml:remove_cdata(Els)), @@ -670,7 +670,7 @@ {get, <<"subscriptions">>} -> get_subscriptions(Host, Node, From, Plugins); {get, <<"affiliations">>} -> -@@ -1991,7 +1648,9 @@ +@@ -2061,7 +1718,9 @@ ). iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) -> #xmlel{children = SubEls} = SubEl, @@ -681,7 +681,7 @@ case Action of [#xmlel{name = Name, attrs = Attrs, children = Els}] -> Node = xml:get_attr_s(<<"node">>, Attrs), -@@ -2121,7 +1780,8 @@ +@@ -2195,7 +1854,8 @@ _ -> [] end end, @@ -691,7 +691,7 @@ {result, lists:flatmap(Tr, Plugins)} end, sync_dirty) -@@ -2163,7 +1823,8 @@ +@@ -2240,7 +1900,8 @@ %%% authorization handling @@ -701,7 +701,7 @@ Subscriber) -> Lang = <<"en">>, Stanza = #xmlel{name = <<"message">>, attrs = [], -@@ -2241,7 +1902,7 @@ +@@ -2318,7 +1979,7 @@ ejabberd_router:route(service_jid(Host), jlib:make_jid(Owner), Stanza) end, @@ -710,7 +710,7 @@ find_authorization_response(Packet) -> #xmlel{children = Els} = Packet, -@@ -2300,11 +1961,11 @@ +@@ -2383,11 +2044,11 @@ <<"true">> -> true; _ -> false end, @@ -724,7 +724,7 @@ {result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, -@@ -2539,7 +2200,7 @@ +@@ -2642,7 +2303,7 @@ children = [#xmlel{name = <<"create">>, attrs = nodeAttr(Node), children = []}]}], @@ -733,7 +733,7 @@ {result, {NodeId, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth), ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), -@@ -2663,7 +2324,7 @@ +@@ -2779,7 +2440,7 @@ %% subscribe_node(Host, Node, From, JID, Configuration) -> SubOpts = case @@ -742,7 +742,7 @@ of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid -@@ -2677,7 +2338,7 @@ +@@ -2793,7 +2454,7 @@ end end, Action = fun (#pubsub_node{options = Options, @@ -751,7 +751,7 @@ Features = features(Type), SubscribeFeature = lists:member(<<"subscribe">>, Features), OptionsFeature = lists:member(<<"subscription-options">>, Features), -@@ -2686,6 +2347,7 @@ +@@ -2802,6 +2463,7 @@ AccessModel = get_option(Options, access_model), SendLast = get_option(Options, send_last_published_item), AllowedGroups = get_option(Options, roster_groups_allowed, []), @@ -759,7 +759,7 @@ {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, Subscriber, Owners, AccessModel, AllowedGroups), -@@ -2808,12 +2470,9 @@ +@@ -2956,12 +2618,9 @@ Features = features(Type), PublishFeature = lists:member(<<"publish">>, Features), PublishModel = get_option(Options, publish_model), @@ -773,7 +773,7 @@ PayloadCount = payload_xmlelements(Payload), PayloadSize = byte_size(term_to_binary(Payload)) - 2, PayloadMaxSize = get_option(Options, max_payload_size), -@@ -2869,7 +2528,7 @@ +@@ -3017,7 +2676,7 @@ false -> ok end, @@ -782,10 +782,10 @@ case Result of default -> {result, Reply}; _ -> {result, Result} -@@ -3040,19 +2699,20 @@ - Error -> Error - end. - +@@ -3210,19 +2869,20 @@ + %%

The permission are not checked in this function.

+ %% @todo We probably need to check that the user doing the query has the right + %% to read the items. --spec(get_items/6 :: +-spec(get_items/7 :: ( @@ -806,7 +806,7 @@ MaxItems = if SMaxItems == <<"">> -> get_max_items_node(Host); true -> -@@ -3064,13 +2724,13 @@ +@@ -3234,13 +2894,13 @@ case MaxItems of {error, Error} -> {error, Error}; _ -> @@ -822,7 +822,7 @@ {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), -@@ -3088,11 +2748,11 @@ +@@ -3258,11 +2918,11 @@ node_call(Type, get_items, [NodeId, From, AccessModel, PresenceSubscription, RosterGroup, @@ -836,7 +836,7 @@ SendItems = case ItemIDs of [] -> Items; _ -> -@@ -3110,8 +2770,8 @@ +@@ -3280,8 +2940,8 @@ children = [#xmlel{name = <<"items">>, attrs = nodeAttr(Node), children = @@ -847,7 +847,7 @@ Error -> Error end end. -@@ -3135,43 +2795,45 @@ +@@ -3305,13 +2965,18 @@ end. get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners) -> @@ -865,6 +865,12 @@ - [NodeIdx, From, AccessModel, PresenceSubscription, RosterGroup, undefined]). + [NodeIdx, From, AccessModel, PresenceSubscription, RosterGroup, undefined, RSM]). + %% @spec (Host, Node, NodeId, Type, LJID, Number) -> any() + %% Host = pubsubHost() +@@ -3322,35 +2987,32 @@ + %% Number = last | integer() + %% @doc

Resend the items of a node to the user.

+ %% @todo use cache-last-item feature -send_items(Host, Node, NodeId, Type, {U, S, R} = LJID, last) -> - case get_cached_item(Host, NodeId) of - undefined -> @@ -916,11 +922,20 @@ send_items(Host, Node, NodeId, Type, {U, S, R} = LJID, Number) -> ToSend = case node_action(Host, Type, get_items, -@@ -3199,20 +2861,7 @@ +@@ -3378,7 +3040,8 @@ attrs = nodeAttr(Node), children = itemsEls(ToSend)}]) end, - case is_tuple(Host) of ++ ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza). ++ + %% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response} + %% Host = host() + %% JID = jid() +@@ -3386,20 +3049,6 @@ + %% Reason = stanzaError() + %% Response = [pubsubIQResponse()] + %% @doc

Return the list of affiliations as an XMPP response.

- false -> - ejabberd_router:route(service_jid(Host), - jlib:make_jid(LJID), Stanza); @@ -934,11 +949,11 @@ - _ -> ok - end - end. -+ ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza). - +- -spec(get_affiliations/4 :: ( -@@ -3400,9 +3049,10 @@ + Host :: mod_pubsub:host(), +@@ -3586,9 +3235,10 @@ case Entities of error -> {error, ?ERR_BAD_REQUEST}; _ -> @@ -950,7 +965,7 @@ case lists:member(Owner, Owners) of true -> OwnerJID = jlib:make_jid(Owner), -@@ -3415,42 +3065,7 @@ +@@ -3601,42 +3251,7 @@ _ -> Entities end, lists:foreach(fun ({JID, Affiliation}) -> @@ -994,7 +1009,7 @@ end, FilteredEntities), {result, []}; -@@ -3509,11 +3124,11 @@ +@@ -3695,11 +3310,11 @@ end. read_sub(Subscriber, Node, NodeID, SubID, Lang) -> @@ -1008,7 +1023,7 @@ OptionsEl = #xmlel{name = <<"options">>, attrs = [{<<"jid">>, jlib:jid_to_string(Subscriber)}, -@@ -3547,7 +3162,7 @@ +@@ -3733,7 +3348,7 @@ end. set_options_helper(Configuration, JID, NodeID, SubID, Type) -> @@ -1017,7 +1032,7 @@ {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, -@@ -3579,7 +3194,7 @@ +@@ -3765,7 +3380,7 @@ write_sub(_Subscriber, _NodeID, _SubID, invalid) -> {error, extended_error(?ERR_BAD_REQUEST, <<"invalid-options">>)}; write_sub(Subscriber, NodeID, SubID, Options) -> @@ -1026,7 +1041,7 @@ {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, <<"invalid-subid">>)}; {result, _} -> -@@ -3800,9 +3415,9 @@ +@@ -3986,9 +3601,9 @@ ejabberd_router:route(service_jid(Host), jlib:make_jid(JID), Stanza) end, @@ -1038,7 +1053,7 @@ true -> Result = lists:foldl(fun ({JID, Subscription, SubId}, -@@ -4181,7 +3796,7 @@ +@@ -4405,7 +4020,7 @@ {Depth, [{N, get_node_subs(N)} || N <- Nodes]} end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))} end, @@ -1047,7 +1062,7 @@ {result, CollSubs} -> CollSubs; _ -> [] end. -@@ -4195,9 +3810,9 @@ +@@ -4419,9 +4034,9 @@ get_options_for_subs(NodeID, Subs) -> lists:foldl(fun({JID, subscribed, SubID}, Acc) -> @@ -1059,7 +1074,7 @@ _ -> Acc end; (_, Acc) -> -@@ -4870,6 +4485,30 @@ +@@ -5121,6 +4736,30 @@ _ -> features() end. @@ -1087,10 +1102,10 @@ + [] + end. + + %% @doc

node tree plugin call.

tree_call({_User, Server, _Resource}, Function, Args) -> tree_call(Server, Function, Args); - tree_call(Host, Function, Args) -> -@@ -4888,7 +4527,13 @@ +@@ -5140,7 +4779,13 @@ tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p", [Host, Function, Args]), Fun = fun () -> tree_call(Host, Function, Args) end, @@ -1103,9 +1118,9 @@ + {error, ?ERR_INTERNAL_SERVER_ERROR} + end. + %% @doc

node plugin call.

node_call(Type, Function, Args) -> - ?DEBUG("node_call ~p ~p ~p", [Type, Function, Args]), -@@ -4912,12 +4557,11 @@ +@@ -5165,13 +4810,12 @@ node_action(Host, Type, Function, Args) -> ?DEBUG("node_action ~p ~p ~p ~p", [Host, Type, Function, Args]), @@ -1114,13 +1129,14 @@ + transaction(Host, fun () -> node_call(Type, Function, Args) end, sync_dirty). + %% @doc

plugin transaction handling.

transaction(Host, Node, Action, Trans) -> - transaction(fun () -> + transaction(Host, fun () -> case tree_call(Host, get_node, [Host, Node]) of N when is_record(N, pubsub_node) -> case Action(N) of -@@ -4931,16 +4575,22 @@ +@@ -5185,16 +4829,22 @@ end, Trans). @@ -1147,7 +1163,7 @@ {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {atomic, {result, Result}} -> {result, Result}; -@@ -4949,6 +4599,15 @@ +@@ -5203,6 +4853,15 @@ ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; @@ -1163,7 +1179,7 @@ {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), -@@ -4959,6 +4618,17 @@ +@@ -5213,6 +4872,17 @@ {error, ?ERR_INTERNAL_SERVER_ERROR} end. @@ -1180,4 +1196,4 @@ + %%%% helpers - extended_error(Error, Ext) -> + %% Add pubsub-specific error element