mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
does not use slash as default separator in nodename (EJAB-667)
SVN Revision: 2687
This commit is contained in:
parent
a232d16ff4
commit
8ce1e790ac
@ -68,7 +68,9 @@ behaviour_info(callbacks) ->
|
||||
{get_item, 7},
|
||||
{get_item, 2},
|
||||
{set_item, 1},
|
||||
{get_item_name, 3}
|
||||
{get_item_name, 3},
|
||||
{node_to_path, 1},
|
||||
{path_to_node, 1}
|
||||
];
|
||||
behaviour_info(_Other) ->
|
||||
undefined.
|
||||
|
@ -51,7 +51,7 @@ behaviour_info(callbacks) ->
|
||||
{get_parentnodes_tree, 3},
|
||||
{get_subnodes, 3},
|
||||
{get_subnodes_tree, 3},
|
||||
{create_node, 5},
|
||||
{create_node, 6},
|
||||
{delete_node, 2}
|
||||
];
|
||||
behaviour_info(_Other) ->
|
||||
|
@ -268,11 +268,11 @@ terminate_plugins(Host, ServerHost, Plugins, TreePlugin) ->
|
||||
ok.
|
||||
|
||||
init_nodes(Host, ServerHost, _NodeTree, Plugins) ->
|
||||
%% TODO, this call should be done PLugin side
|
||||
%% TODO, this call should be done plugin side
|
||||
case lists:member("hometree", Plugins) of
|
||||
true ->
|
||||
create_node(Host, ServerHost, ["home"], service_jid(Host), "hometree"),
|
||||
create_node(Host, ServerHost, ["home", ServerHost], service_jid(Host), "hometree");
|
||||
create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree"),
|
||||
create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree");
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
@ -403,7 +403,28 @@ update_node_database(Host, ServerHost) ->
|
||||
rename_default_nodeplugin();
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
end,
|
||||
mnesia:transaction(fun() ->
|
||||
case catch mnesia:first(pubsub_node) of
|
||||
{_, L} when is_list(L) ->
|
||||
lists:foreach(
|
||||
fun({H, N}) when is_list(N) ->
|
||||
[Node] = mnesia:read({pubsub_node, {H, N}}),
|
||||
Type = Node#pubsub_node.type,
|
||||
BN = element(2, node_call(Type, path_to_node, [N])),
|
||||
BP = case [element(2, node_call(Type, path_to_node, [P])) || P <- Node#pubsub_node.parents] of
|
||||
[<<>>] -> [];
|
||||
Parents -> Parents
|
||||
end,
|
||||
mnesia:write(Node#pubsub_node{nodeid={H, BN}, parents=BP}),
|
||||
mnesia:delete({pubsub_node, {H, N}});
|
||||
(_) ->
|
||||
ok
|
||||
end, mnesia:all_keys(pubsub_node));
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end).
|
||||
|
||||
rename_default_nodeplugin() ->
|
||||
lists:foreach(fun(Node) ->
|
||||
@ -548,7 +569,7 @@ send_loop(State) ->
|
||||
on_sub_and_presence ->
|
||||
lists:foreach(fun({Resource, Caps}) ->
|
||||
CapsNotify = case catch mod_caps:get_features(ServerHost, Caps) of
|
||||
Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
|
||||
Features when is_list(Features) -> lists:member(node_to_string(Node) ++ "+notify", Features);
|
||||
_ -> false
|
||||
end,
|
||||
case CapsNotify of
|
||||
@ -644,7 +665,7 @@ disco_sm_features(Acc, From, To, Node, _Lang) ->
|
||||
|
||||
disco_sm_items(Acc, From, To, [], _Lang) ->
|
||||
Host = To#jid.lserver,
|
||||
case tree_action(Host, get_subnodes, [Host, [], From]) of
|
||||
case tree_action(Host, get_subnodes, [Host, <<>>, From]) of
|
||||
[] ->
|
||||
Acc;
|
||||
Nodes ->
|
||||
@ -662,8 +683,9 @@ disco_sm_items(Acc, From, To, [], _Lang) ->
|
||||
{result, NodeItems ++ Items}
|
||||
end;
|
||||
|
||||
disco_sm_items(Acc, From, To, Node, _Lang) ->
|
||||
disco_sm_items(Acc, From, To, SNode, _Lang) ->
|
||||
Host = To#jid.lserver,
|
||||
Node = string_to_node(SNode),
|
||||
Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
% TODO call get_items/6 instead for access control (EJAB-1033)
|
||||
case node_call(Type, get_items, [NodeId, From]) of
|
||||
@ -677,13 +699,8 @@ disco_sm_items(Acc, From, To, Node, _Lang) ->
|
||||
end,
|
||||
NodeItems = lists:map(
|
||||
fun(#pubsub_item{itemid = {Id, _}}) ->
|
||||
%% "jid" is required by XEP-0030, and
|
||||
%% "node" is forbidden by XEP-0060.
|
||||
{result, Name} = node_call(Type, get_item_name, [Host, Node, Id]),
|
||||
{xmlelement, "item",
|
||||
[{"jid", SBJID},
|
||||
{"name", Name}],
|
||||
[]}
|
||||
{xmlelement, "item", [{"jid", SBJID}, {"name", Name}], []}
|
||||
end, AllItems),
|
||||
{result, NodeItems ++ Items};
|
||||
_ ->
|
||||
@ -1066,7 +1083,7 @@ iq_disco_info(Host, SNode, From, Lang) ->
|
||||
end,
|
||||
Node = string_to_node(RealSNode),
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
{result,
|
||||
[{xmlelement, "identity",
|
||||
[{"category", "pubsub"},
|
||||
@ -1085,24 +1102,17 @@ iq_disco_info(Host, SNode, From, Lang) ->
|
||||
|
||||
iq_disco_items(Host, [], From) ->
|
||||
{result, lists:map(
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}}) ->
|
||||
SN = node_to_string(SubNode),
|
||||
RN = lists:last(SubNode),
|
||||
%% remove name attribute
|
||||
{xmlelement, "item", [{"jid", Host},
|
||||
{"node", SN},
|
||||
{"name", RN}], []}
|
||||
end, tree_action(Host, get_subnodes, [Host, [], From]))};
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}, type = Type}) ->
|
||||
{result, Path} = node_call(Type, node_to_path, [SubNode]),
|
||||
[Name|_] = lists:reverse(Path),
|
||||
{xmlelement, "item", [{"jid", Host}, {"name", Name}|nodeAttr(SubNode)], []}
|
||||
end, tree_action(Host, get_subnodes, [Host, <<>>, From]))};
|
||||
iq_disco_items(Host, Item, From) ->
|
||||
case string:tokens(Item, "!") of
|
||||
[_SNode, _ItemID] ->
|
||||
{result, []};
|
||||
[SNode] ->
|
||||
Node = string_to_node(SNode),
|
||||
%% Note: Multiple Node Discovery not supported (mask on pubsub#type)
|
||||
%% TODO this code is also back-compatible with pubsub v1.8 (for client issue)
|
||||
%% TODO make it pubsub v1.12 compliant (breaks client compatibility ?)
|
||||
%% TODO That is, remove name attribute (or node?, please check for 2.1)
|
||||
Action =
|
||||
fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
% TODO call get_items/6 instead for access control (EJAB-1033)
|
||||
@ -1112,17 +1122,12 @@ iq_disco_items(Host, Item, From) ->
|
||||
end,
|
||||
Nodes = lists:map(
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}}) ->
|
||||
SN = node_to_string(SubNode),
|
||||
RN = lists:last(SubNode),
|
||||
{xmlelement, "item", [{"jid", Host}, {"node", SN},
|
||||
{"name", RN}], []}
|
||||
{xmlelement, "item", [{"jid", Host}|nodeAttr(SubNode)], []}
|
||||
end, tree_call(Host, get_subnodes, [Host, Node, From])),
|
||||
Items = lists:map(
|
||||
fun(#pubsub_item{itemid = {RN, _}}) ->
|
||||
SN = node_to_string(Node) ++ "!" ++ RN,
|
||||
{result, Name} = node_call(Type, get_item_name, [Host, Node, RN]),
|
||||
{xmlelement, "item", [{"jid", Host}, {"node", SN},
|
||||
{"name", Name}], []}
|
||||
{xmlelement, "item", [{"jid", Host}, {"name", Name}], []}
|
||||
end, NodeItems),
|
||||
{result, Nodes ++ Items}
|
||||
end,
|
||||
@ -1178,10 +1183,7 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) ->
|
||||
{xmlelement, _, _, SubEls} = SubEl,
|
||||
case xml:remove_cdata(SubEls) of
|
||||
[{xmlelement, Name, Attrs, Els} | Rest] ->
|
||||
Node = case Host of
|
||||
{_, _, _} -> xml:get_attr_s("node", Attrs);
|
||||
_ -> string_to_node(xml:get_attr_s("node", Attrs))
|
||||
end,
|
||||
Node = string_to_node(xml:get_attr_s("node", Attrs)),
|
||||
case {IQType, Name} of
|
||||
{set, "create"} ->
|
||||
Config = case Rest of
|
||||
@ -1282,10 +1284,7 @@ iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
|
||||
Action = xml:remove_cdata(SubEls),
|
||||
case Action of
|
||||
[{xmlelement, Name, Attrs, Els}] ->
|
||||
Node = case Host of
|
||||
{_, _, _} -> xml:get_attr_s("node", Attrs);
|
||||
_ -> string_to_node(xml:get_attr_s("node", Attrs))
|
||||
end,
|
||||
Node = string_to_node(xml:get_attr_s("node", Attrs)),
|
||||
case {IQType, Name} of
|
||||
{get, "configure"} ->
|
||||
get_configure(Host, ServerHost, Node, From, Lang);
|
||||
@ -1521,7 +1520,7 @@ send_authorization_approval(Host, JID, SNode, Subscription) ->
|
||||
end,
|
||||
Stanza = event_stanza(
|
||||
[{xmlelement, "subscription",
|
||||
[{"node", SNode}, {"jid", jlib:jid_to_string(JID)}] ++ SubAttrs,
|
||||
[{"jid", jlib:jid_to_string(JID)}|nodeAttr(SNode)] ++ SubAttrs,
|
||||
[]}]),
|
||||
ejabberd_router ! {route, service_jid(Host), JID, Stanza}.
|
||||
|
||||
@ -1531,10 +1530,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
|
||||
lists:keysearch("pubsub#allow", 1, XFields)} of
|
||||
{{value, {_, [SNode]}}, {value, {_, [SSubscriber]}},
|
||||
{value, {_, [SAllow]}}} ->
|
||||
Node = case Host of
|
||||
{_, _, _} -> [SNode];
|
||||
_ -> string:tokens(SNode, "/")
|
||||
end,
|
||||
Node = string_to_node(SNode),
|
||||
Subscriber = jlib:string_to_jid(SSubscriber),
|
||||
Allow = case SAllow of
|
||||
"1" -> true;
|
||||
@ -1664,21 +1660,18 @@ update_auth(Host, Node, Type, NodeId, Subscriber,
|
||||
%%</ul>
|
||||
create_node(Host, ServerHost, Node, Owner, Type) ->
|
||||
create_node(Host, ServerHost, Node, Owner, Type, all, []).
|
||||
create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
|
||||
create_node(Host, ServerHost, <<>>, Owner, Type, Access, Configuration) ->
|
||||
case lists:member("instant-nodes", features(Type)) of
|
||||
true ->
|
||||
{LOU, LOS, _} = jlib:jid_tolower(Owner),
|
||||
HomeNode = ["home", LOS, LOU],
|
||||
create_node(Host, ServerHost,
|
||||
HomeNode, Owner, Type, Access, Configuration),
|
||||
NewNode = HomeNode ++ [randoms:get_string()],
|
||||
NewNode = string_to_node(randoms:get_string()),
|
||||
case create_node(Host, ServerHost,
|
||||
NewNode, Owner, Type, Access, Configuration) of
|
||||
{result, []} ->
|
||||
{result,
|
||||
[{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
|
||||
[{xmlelement, "create", nodeAttr(NewNode), []}]}]};
|
||||
Error -> Error
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
false ->
|
||||
%% Service does not support instant nodes
|
||||
@ -1686,7 +1679,6 @@ create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
|
||||
end;
|
||||
create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
Type = select_type(ServerHost, Host, Node, GivenType),
|
||||
Parent = lists:sublist(Node, length(Node) - 1),
|
||||
%% TODO, check/set node_type = Type
|
||||
ParseOptions = case xml:remove_cdata(Configuration) of
|
||||
[] ->
|
||||
@ -1711,9 +1703,18 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
{result, NodeOptions} ->
|
||||
CreateNode =
|
||||
fun() ->
|
||||
SNode = node_to_string(Node),
|
||||
Parent = case node_call(Type, node_to_path, [Node]) of
|
||||
{result, [SNode]} -> <<>>;
|
||||
{result, Path} -> element(2, node_call(Type, path_to_node, [lists:sublist(Path, length(Path)-1)]))
|
||||
end,
|
||||
Parents = case Parent of
|
||||
<<>> -> [];
|
||||
_ -> [Parent]
|
||||
end,
|
||||
case node_call(Type, create_node_permission, [Host, ServerHost, Node, Parent, Owner, Access]) of
|
||||
{result, true} ->
|
||||
case tree_call(Host, create_node, [Host, Node, Type, Owner, NodeOptions]) of
|
||||
case tree_call(Host, create_node, [Host, Node, Type, Owner, NodeOptions, Parents]) of
|
||||
{ok, NodeId} ->
|
||||
node_call(Type, create_node, [NodeId, Owner]);
|
||||
{error, {virtual, NodeId}} ->
|
||||
@ -2499,9 +2500,8 @@ read_sub(Subscriber, Node, NodeID, SubID, Lang) ->
|
||||
{error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
{result, #pubsub_subscription{options = Options}} ->
|
||||
{result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options),
|
||||
OptionsEl = {xmlelement, "options", [{"node", node_to_string(Node)},
|
||||
{"jid", jlib:jid_to_string(Subscriber)},
|
||||
{"subid", SubID}],
|
||||
OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)},
|
||||
{"subid", SubID}|nodeAttr(Node)],
|
||||
[XdataEl]},
|
||||
PubsubEl = {xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [OptionsEl]},
|
||||
{result, PubsubEl}
|
||||
@ -2591,7 +2591,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
[];
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
[{xmlelement, "subscription",
|
||||
[{"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)],
|
||||
[]}];
|
||||
@ -2606,7 +2606,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
[];
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubID, SubJID}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
[{xmlelement, "subscription",
|
||||
[{"jid", jlib:jid_to_string(SubJID)},
|
||||
{"subid", SubID},
|
||||
@ -2623,7 +2623,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
end;
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubJID}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
[{xmlelement, "subscription",
|
||||
[{"jid", jlib:jid_to_string(SubJID)},
|
||||
{"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)],
|
||||
@ -2805,14 +2805,8 @@ subscription_to_string(_) -> "none".
|
||||
%% Node = pubsubNode()
|
||||
%% NodeStr = string()
|
||||
%% @doc <p>Convert a node type from pubsubNode to string.</p>
|
||||
node_to_string([]) -> "/";
|
||||
node_to_string(Node) ->
|
||||
case Node of
|
||||
[[_ | _] | _] -> string:strip(lists:flatten(["/", lists:map(fun(S) -> [S, "/"] end, Node)]), right, $/);
|
||||
[Head | _] when is_integer(Head) -> Node
|
||||
end.
|
||||
string_to_node(SNode) ->
|
||||
string:tokens(SNode, "/").
|
||||
node_to_string(Node) -> binary_to_list(Node).
|
||||
string_to_node(SNode) -> list_to_binary(SNode).
|
||||
|
||||
%% @spec (Host) -> jid()
|
||||
%% Host = host()
|
||||
@ -3044,7 +3038,7 @@ get_options_for_subs(NodeID, Subs) ->
|
||||
% {result, []} ->
|
||||
% {result, false};
|
||||
% {result, Subs} ->
|
||||
% Stanza = event_stanza([{xmlelement, ElName, [{"node", node_to_string(Node)}], SubEls}]),
|
||||
% Stanza = event_stanza([{xmlelement, ElName, nodeAttr(Node), SubEls}]),
|
||||
% broadcast_stanza(Host, Node, Type, NodeOptions, SubOpts, Stanza),
|
||||
% {result, true};
|
||||
% _ ->
|
||||
@ -3161,7 +3155,7 @@ is_caps_notify(Host, Node, LJID) ->
|
||||
false;
|
||||
Caps ->
|
||||
case catch mod_caps:get_features(Host, Caps) of
|
||||
Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
|
||||
Features when is_list(Features) -> lists:member(node_to_string(Node) ++ "+notify", Features);
|
||||
_ -> false
|
||||
end
|
||||
end.
|
||||
@ -3689,6 +3683,8 @@ uniqid() ->
|
||||
lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])).
|
||||
|
||||
% node attributes
|
||||
nodeAttr(Node) when is_list(Node) ->
|
||||
[{"node", Node}];
|
||||
nodeAttr(Node) ->
|
||||
[{"node", node_to_string(Node)}].
|
||||
|
||||
|
@ -266,11 +266,11 @@ terminate_plugins(Host, ServerHost, Plugins, TreePlugin) ->
|
||||
ok.
|
||||
|
||||
init_nodes(Host, ServerHost, _NodeTree, Plugins) ->
|
||||
%% TODO, this call should be done PLugin side
|
||||
case lists:member("hometree", Plugins) of
|
||||
%% TODO, this call should be done plugin side
|
||||
case lists:member("hometree_odbc", Plugins) of
|
||||
true ->
|
||||
create_node(Host, ServerHost, ["home"], service_jid(Host), "hometree"),
|
||||
create_node(Host, ServerHost, ["home", ServerHost], service_jid(Host), "hometree");
|
||||
create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree_odbc"),
|
||||
create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree_odbc");
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
@ -372,7 +372,7 @@ send_loop(State) ->
|
||||
on_sub_and_presence ->
|
||||
lists:foreach(fun({Resource, Caps}) ->
|
||||
CapsNotify = case catch mod_caps:get_features(ServerHost, Caps) of
|
||||
Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
|
||||
Features when is_list(Features) -> lists:member(node_to_string(Node) ++ "+notify", Features);
|
||||
_ -> false
|
||||
end,
|
||||
case CapsNotify of
|
||||
@ -468,7 +468,7 @@ disco_sm_features(Acc, From, To, Node, _Lang) ->
|
||||
|
||||
disco_sm_items(Acc, From, To, [], _Lang) ->
|
||||
Host = To#jid.lserver,
|
||||
case tree_action(Host, get_subnodes, [Host, [], From]) of
|
||||
case tree_action(Host, get_subnodes, [Host, <<>>, From]) of
|
||||
[] ->
|
||||
Acc;
|
||||
Nodes ->
|
||||
@ -486,8 +486,9 @@ disco_sm_items(Acc, From, To, [], _Lang) ->
|
||||
{result, NodeItems ++ Items}
|
||||
end;
|
||||
|
||||
disco_sm_items(Acc, From, To, Node, _Lang) ->
|
||||
disco_sm_items(Acc, From, To, SNode, _Lang) ->
|
||||
Host = To#jid.lserver,
|
||||
Node = string_to_node(SNode),
|
||||
Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
% TODO call get_items/6 instead for access control (EJAB-1033)
|
||||
case node_call(Type, get_items, [NodeId, From]) of
|
||||
@ -501,13 +502,8 @@ disco_sm_items(Acc, From, To, Node, _Lang) ->
|
||||
end,
|
||||
NodeItems = lists:map(
|
||||
fun(#pubsub_item{itemid = {Id, _}}) ->
|
||||
%% "jid" is required by XEP-0030, and
|
||||
%% "node" is forbidden by XEP-0060.
|
||||
{result, Name} = node_call(Type, get_item_name, [Host, Node, Id]),
|
||||
{xmlelement, "item",
|
||||
[{"jid", SBJID},
|
||||
{"name", Name}],
|
||||
[]}
|
||||
{xmlelement, "item", [{"jid", SBJID}, {"name", Name}], []}
|
||||
end, AllItems),
|
||||
{result, NodeItems ++ Items};
|
||||
_ ->
|
||||
@ -892,7 +888,7 @@ iq_disco_info(Host, SNode, From, Lang) ->
|
||||
end,
|
||||
Node = string_to_node(RealSNode),
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
{result,
|
||||
[{xmlelement, "identity",
|
||||
[{"category", "pubsub"},
|
||||
@ -912,24 +908,17 @@ iq_disco_info(Host, SNode, From, Lang) ->
|
||||
|
||||
iq_disco_items(Host, [], From, _RSM) ->
|
||||
{result, lists:map(
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}}) ->
|
||||
SN = node_to_string(SubNode),
|
||||
RN = lists:last(SubNode),
|
||||
%% remove name attribute
|
||||
{xmlelement, "item", [{"jid", Host},
|
||||
{"node", SN},
|
||||
{"name", RN}], []}
|
||||
end, tree_action(Host, get_subnodes, [Host, [], From]))};
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}, type = Type}) ->
|
||||
{result, Path} = node_call(Type, node_to_path, [SubNode]),
|
||||
[Name|_] = lists:reverse(Path),
|
||||
{xmlelement, "item", [{"jid", Host}, {"name", Name}|nodeAttr(SubNode)], []}
|
||||
end, tree_action(Host, get_subnodes, [Host, <<>>, From]))};
|
||||
iq_disco_items(Host, Item, From, RSM) ->
|
||||
case string:tokens(Item, "!") of
|
||||
[_SNode, _ItemID] ->
|
||||
{result, []};
|
||||
[SNode] ->
|
||||
Node = string_to_node(SNode),
|
||||
%% Note: Multiple Node Discovery not supported (mask on pubsub#type)
|
||||
%% TODO this code is also back-compatible with pubsub v1.8 (for client issue)
|
||||
%% TODO make it pubsub v1.12 compliant (breaks client compatibility ?)
|
||||
%% TODO That is, remove name attribute (or node?, please check for 2.1)
|
||||
Action =
|
||||
fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
%% TODO call get_items/6 instead for access control (EJAB-1033)
|
||||
@ -939,17 +928,12 @@ iq_disco_items(Host, Item, From, RSM) ->
|
||||
end,
|
||||
Nodes = lists:map(
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}}) ->
|
||||
SN = node_to_string(SubNode),
|
||||
RN = lists:last(SubNode),
|
||||
{xmlelement, "item", [{"jid", Host}, {"node", SN},
|
||||
{"name", RN}], []}
|
||||
{xmlelement, "item", [{"jid", Host}|nodeAttr(SubNode)], []}
|
||||
end, tree_call(Host, get_subnodes, [Host, Node, From])),
|
||||
Items = lists:map(
|
||||
fun(#pubsub_item{itemid = {RN, _}}) ->
|
||||
SN = node_to_string(Node) ++ "!" ++ RN,
|
||||
{result, Name} = node_call(Type, get_item_name, [Host, Node, RN]),
|
||||
{xmlelement, "item", [{"jid", Host}, {"node", SN},
|
||||
{"name", Name}], []}
|
||||
{xmlelement, "item", [{"jid", Host}, {"name", Name}], []}
|
||||
end, NodeItems),
|
||||
{result, Nodes ++ Items ++ jlib:rsm_encode(RsmOut)}
|
||||
end,
|
||||
@ -1005,10 +989,7 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) ->
|
||||
{xmlelement, _, _, SubEls} = SubEl,
|
||||
case xml:remove_cdata(SubEls) of
|
||||
[{xmlelement, Name, Attrs, Els} | Rest] ->
|
||||
Node = case Host of
|
||||
{_, _, _} -> xml:get_attr_s("node", Attrs);
|
||||
_ -> string_to_node(xml:get_attr_s("node", Attrs))
|
||||
end,
|
||||
Node = string_to_node(xml:get_attr_s("node", Attrs)),
|
||||
case {IQType, Name} of
|
||||
{set, "create"} ->
|
||||
Config = case Rest of
|
||||
@ -1112,10 +1093,7 @@ iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
|
||||
end, xml:remove_cdata(SubEls)),
|
||||
case Action of
|
||||
[{xmlelement, Name, Attrs, Els}] ->
|
||||
Node = case Host of
|
||||
{_, _, _} -> xml:get_attr_s("node", Attrs);
|
||||
_ -> string_to_node(xml:get_attr_s("node", Attrs))
|
||||
end,
|
||||
Node = string_to_node(xml:get_attr_s("node", Attrs)),
|
||||
case {IQType, Name} of
|
||||
{get, "configure"} ->
|
||||
get_configure(Host, ServerHost, Node, From, Lang);
|
||||
@ -1352,7 +1330,7 @@ send_authorization_approval(Host, JID, SNode, Subscription) ->
|
||||
end,
|
||||
Stanza = event_stanza(
|
||||
[{xmlelement, "subscription",
|
||||
[{"node", SNode}, {"jid", jlib:jid_to_string(JID)}] ++ SubAttrs,
|
||||
[{"jid", jlib:jid_to_string(JID)}|nodeAttr(SNode)] ++ SubAttrs,
|
||||
[]}]),
|
||||
ejabberd_router ! {route, service_jid(Host), JID, Stanza}.
|
||||
|
||||
@ -1362,10 +1340,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
|
||||
lists:keysearch("pubsub#allow", 1, XFields)} of
|
||||
{{value, {_, [SNode]}}, {value, {_, [SSubscriber]}},
|
||||
{value, {_, [SAllow]}}} ->
|
||||
Node = case Host of
|
||||
{_, _, _} -> [SNode];
|
||||
_ -> string:tokens(SNode, "/")
|
||||
end,
|
||||
Node = string_to_node(SNode),
|
||||
Subscriber = jlib:string_to_jid(SSubscriber),
|
||||
Allow = case SAllow of
|
||||
"1" -> true;
|
||||
@ -1495,21 +1470,18 @@ update_auth(Host, Node, Type, NodeId, Subscriber,
|
||||
%%</ul>
|
||||
create_node(Host, ServerHost, Node, Owner, Type) ->
|
||||
create_node(Host, ServerHost, Node, Owner, Type, all, []).
|
||||
create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
|
||||
create_node(Host, ServerHost, <<>>, Owner, Type, Access, Configuration) ->
|
||||
case lists:member("instant-nodes", features(Type)) of
|
||||
true ->
|
||||
{LOU, LOS, _} = jlib:jid_tolower(Owner),
|
||||
HomeNode = ["home", LOS, LOU],
|
||||
create_node(Host, ServerHost,
|
||||
HomeNode, Owner, Type, Access, Configuration),
|
||||
NewNode = HomeNode ++ [randoms:get_string()],
|
||||
NewNode = string_to_node(randoms:get_string()),
|
||||
case create_node(Host, ServerHost,
|
||||
NewNode, Owner, Type, Access, Configuration) of
|
||||
{result, []} ->
|
||||
{result,
|
||||
[{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
|
||||
[{xmlelement, "create", nodeAttr(NewNode), []}]}]};
|
||||
Error -> Error
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
false ->
|
||||
%% Service does not support instant nodes
|
||||
@ -1517,7 +1489,6 @@ create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
|
||||
end;
|
||||
create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
Type = select_type(ServerHost, Host, Node, GivenType),
|
||||
Parent = lists:sublist(Node, length(Node) - 1),
|
||||
%% TODO, check/set node_type = Type
|
||||
ParseOptions = case xml:remove_cdata(Configuration) of
|
||||
[] ->
|
||||
@ -1542,9 +1513,18 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
{result, NodeOptions} ->
|
||||
CreateNode =
|
||||
fun() ->
|
||||
SNode = node_to_string(Node),
|
||||
Parent = case node_call(Type, node_to_path, [Node]) of
|
||||
{result, [SNode]} -> <<>>;
|
||||
{result, Path} -> element(2, node_call(Type, path_to_node, [lists:sublist(Path, length(Path)-1)]))
|
||||
end,
|
||||
Parents = case Parent of
|
||||
<<>> -> [];
|
||||
_ -> [Parent]
|
||||
end,
|
||||
case node_call(Type, create_node_permission, [Host, ServerHost, Node, Parent, Owner, Access]) of
|
||||
{result, true} ->
|
||||
case tree_call(Host, create_node, [Host, Node, Type, Owner, NodeOptions]) of
|
||||
case tree_call(Host, create_node, [Host, Node, Type, Owner, NodeOptions, Parents]) of
|
||||
{ok, NodeId} ->
|
||||
node_call(Type, create_node, [NodeId, Owner]);
|
||||
{error, {virtual, NodeId}} ->
|
||||
@ -2329,9 +2309,8 @@ read_sub(Subscriber, Node, NodeID, SubID, Lang) ->
|
||||
{error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
{result, #pubsub_subscription{options = Options}} ->
|
||||
{result, XdataEl} = pubsub_subscription_odbc:get_options_xform(Lang, Options),
|
||||
OptionsEl = {xmlelement, "options", [{"node", node_to_string(Node)},
|
||||
{"jid", jlib:jid_to_string(Subscriber)},
|
||||
{"subid", SubID}],
|
||||
OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)},
|
||||
{"subid", SubID}|nodeAttr(Node)],
|
||||
[XdataEl]},
|
||||
PubsubEl = {xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [OptionsEl]},
|
||||
{result, PubsubEl}
|
||||
@ -2421,7 +2400,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
[];
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
[{xmlelement, "subscription",
|
||||
[{"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)],
|
||||
[]}];
|
||||
@ -2436,7 +2415,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
[];
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubID, SubJID}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
[{xmlelement, "subscription",
|
||||
[{"jid", jlib:jid_to_string(SubJID)},
|
||||
{"subid", SubID},
|
||||
@ -2453,7 +2432,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
end;
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubJID}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
<<>> ->
|
||||
[{xmlelement, "subscription",
|
||||
[{"jid", jlib:jid_to_string(SubJID)},
|
||||
{"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)],
|
||||
@ -2635,14 +2614,8 @@ subscription_to_string(_) -> "none".
|
||||
%% Node = pubsubNode()
|
||||
%% NodeStr = string()
|
||||
%% @doc <p>Convert a node type from pubsubNode to string.</p>
|
||||
node_to_string([]) -> "/";
|
||||
node_to_string(Node) ->
|
||||
case Node of
|
||||
[[_ | _] | _] -> string:strip(lists:flatten(["/", lists:map(fun(S) -> [S, "/"] end, Node)]), right, $/);
|
||||
[Head | _] when is_integer(Head) -> Node
|
||||
end.
|
||||
string_to_node(SNode) ->
|
||||
string:tokens(SNode, "/").
|
||||
node_to_string(Node) -> binary_to_list(Node).
|
||||
string_to_node(SNode) -> list_to_binary(SNode).
|
||||
|
||||
%% @spec (Host) -> jid()
|
||||
%% Host = host()
|
||||
@ -2874,7 +2847,7 @@ get_options_for_subs(NodeID, Subs) ->
|
||||
% {result, []} ->
|
||||
% {result, false};
|
||||
% {result, Subs} ->
|
||||
% Stanza = event_stanza([{xmlelement, ElName, [{"node", node_to_string(Node)}], SubEls}]),
|
||||
% Stanza = event_stanza([{xmlelement, ElName, nodeAttr(Node), SubEls}]),
|
||||
% broadcast_stanza(Host, Node, Type, NodeOptions, SubOpts, Stanza),
|
||||
% {result, true};
|
||||
% _ ->
|
||||
@ -2991,7 +2964,7 @@ is_caps_notify(Host, Node, LJID) ->
|
||||
false;
|
||||
Caps ->
|
||||
case catch mod_caps:get_features(Host, Caps) of
|
||||
Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
|
||||
Features when is_list(Features) -> lists:member(node_to_string(Node) ++ "+notify", Features);
|
||||
_ -> false
|
||||
end
|
||||
end.
|
||||
@ -3575,6 +3548,8 @@ uniqid() ->
|
||||
lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])).
|
||||
|
||||
% node attributes
|
||||
nodeAttr(Node) when is_list(Node) ->
|
||||
[{"node", Node}];
|
||||
nodeAttr(Node) ->
|
||||
[{"node", node_to_string(Node)}].
|
||||
|
||||
|
@ -68,7 +68,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
|
||||
@ -193,3 +195,10 @@ set_item(Item) ->
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_flat:path_to_node(Path).
|
||||
|
||||
|
@ -68,7 +68,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
|
||||
@ -192,3 +194,10 @@ set_item(Item) ->
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_flat:path_to_node(Path).
|
||||
|
||||
|
@ -52,7 +52,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3]).
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1]).
|
||||
|
||||
|
||||
init(Host, ServerHost, Opts) ->
|
||||
@ -173,3 +175,10 @@ set_item(Item) ->
|
||||
|
||||
get_item_name(Host, Node, ID) ->
|
||||
node_hometree:get_item_name(Host, Node, ID).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_hometree:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_hometree:path_to_node(Path).
|
||||
|
||||
|
@ -66,7 +66,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
|
||||
@ -196,3 +198,10 @@ set_item(Item) ->
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_flat:path_to_node(Path).
|
||||
|
||||
|
@ -59,7 +59,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
|
||||
@ -179,3 +181,16 @@ set_item(Item) ->
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
[binary_to_list(Node)].
|
||||
|
||||
path_to_node(Path) ->
|
||||
case Path of
|
||||
% default slot
|
||||
[Node] -> list_to_binary(Node);
|
||||
% handle old possible entries, used when migrating database content to new format
|
||||
[Node|_] when is_list(Node) -> list_to_binary(string:join([""|Path], "/"));
|
||||
% default case (used by PEP for example)
|
||||
_ -> list_to_binary(Path)
|
||||
end.
|
||||
|
@ -63,7 +63,9 @@
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3,
|
||||
get_last_items/3
|
||||
get_last_items/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
|
||||
@ -196,3 +198,16 @@ get_item_name(Host, Node, Id) ->
|
||||
get_last_items(NodeId, From, Count) ->
|
||||
node_hometree_odbc:get_last_items(NodeId, From, Count).
|
||||
|
||||
node_to_path(Node) ->
|
||||
[binary_to_list(Node)].
|
||||
|
||||
path_to_node(Path) ->
|
||||
case Path of
|
||||
% default slot
|
||||
[Node] -> list_to_binary(Node);
|
||||
% handle old possible entries, used when migrating database content to new format
|
||||
[Node|_] when is_list(Node) -> list_to_binary(string:join([""|Path], "/"));
|
||||
% default case (used by PEP for example)
|
||||
_ -> list_to_binary(Path)
|
||||
end.
|
||||
|
||||
|
@ -75,7 +75,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
%% ================
|
||||
@ -203,7 +205,7 @@ create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
|
||||
_ ->
|
||||
case acl:match_rule(ServerHost, Access, LOwner) of
|
||||
allow ->
|
||||
case Node of
|
||||
case node_to_path(Node) of
|
||||
["home", Server, User | _] -> true;
|
||||
_ -> false
|
||||
end;
|
||||
@ -989,6 +991,14 @@ del_items(NodeId, ItemIds) ->
|
||||
get_item_name(_Host, _Node, Id) ->
|
||||
Id.
|
||||
|
||||
node_to_path(Node) ->
|
||||
string:tokens(binary_to_list(Node), "/").
|
||||
|
||||
path_to_node([]) ->
|
||||
<<>>;
|
||||
path_to_node(Path) ->
|
||||
list_to_binary(string:join([""|Path], "/")).
|
||||
|
||||
%% @spec (Affiliation, Subscription) -> true | false
|
||||
%% Affiliation = owner | member | publisher | outcast | none
|
||||
%% Subscription = subscribed | none
|
||||
@ -1014,3 +1024,4 @@ first_in_list(Pred, [H | T]) ->
|
||||
true -> {value, H};
|
||||
_ -> first_in_list(Pred, T)
|
||||
end.
|
||||
|
||||
|
@ -81,7 +81,9 @@
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3,
|
||||
get_last_items/3
|
||||
get_last_items/3,
|
||||
path_to_node/1,
|
||||
node_to_path/1
|
||||
]).
|
||||
|
||||
-export([
|
||||
@ -210,7 +212,7 @@ create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
|
||||
_ ->
|
||||
case acl:match_rule(ServerHost, Access, LOwner) of
|
||||
allow ->
|
||||
case Node of
|
||||
case node_to_path(Node) of
|
||||
["home", Server, User | _] -> true;
|
||||
_ -> false
|
||||
end;
|
||||
@ -1209,6 +1211,14 @@ del_items(NodeId, ItemIds) ->
|
||||
get_item_name(_Host, _Node, Id) ->
|
||||
Id.
|
||||
|
||||
node_to_path(Node) ->
|
||||
string:tokens(binary_to_list(Node), "/").
|
||||
|
||||
path_to_node([]) ->
|
||||
<<>>;
|
||||
path_to_node(Path) ->
|
||||
list_to_binary(string:join([""|Path], "/")).
|
||||
|
||||
%% @spec (Affiliation, Subscription) -> true | false
|
||||
%% Affiliation = owner | member | publisher | outcast | none
|
||||
%% Subscription = subscribed | none
|
||||
|
@ -71,7 +71,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
init(Host, ServerHost, Opts) ->
|
||||
@ -201,3 +203,9 @@ set_item(Item) ->
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_pep:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_pep:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_pep:path_to_node(Path).
|
||||
|
||||
|
@ -64,7 +64,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
init(Host, ServerHost, Opts) ->
|
||||
@ -268,6 +270,12 @@ set_item(Item) ->
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_flat:path_to_node(Path).
|
||||
|
||||
|
||||
%%%
|
||||
%%% Internal
|
||||
|
@ -70,7 +70,9 @@
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3,
|
||||
get_last_items/3
|
||||
get_last_items/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
init(Host, ServerHost, Opts) ->
|
||||
@ -305,6 +307,11 @@ set_item(Item) ->
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree_odbc:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat_odbc:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_flat_odbc:path_to_node(Path).
|
||||
|
||||
%%%
|
||||
%%% Internal
|
||||
|
@ -68,7 +68,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
|
||||
@ -196,3 +198,10 @@ set_item(Item) ->
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_flat:path_to_node(Path).
|
||||
|
||||
|
@ -68,7 +68,9 @@
|
||||
get_item/7,
|
||||
get_item/2,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
get_item_name/3,
|
||||
node_to_path/1,
|
||||
path_to_node/1
|
||||
]).
|
||||
|
||||
|
||||
@ -194,3 +196,10 @@ set_item(Item) ->
|
||||
%% node id.</p>
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_hometree:get_item_name(Host, Node, Id).
|
||||
|
||||
node_to_path(Node) ->
|
||||
node_flat:node_to_path(Node).
|
||||
|
||||
path_to_node(Path) ->
|
||||
node_flat:path_to_node(Path).
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
get_parentnodes_tree/3,
|
||||
get_subnodes/3,
|
||||
get_subnodes_tree/3,
|
||||
create_node/5,
|
||||
create_node/6,
|
||||
delete_node/2]).
|
||||
|
||||
-include_lib("stdlib/include/qlc.hrl").
|
||||
@ -53,14 +53,12 @@
|
||||
%% API
|
||||
%%====================================================================
|
||||
init(Host, ServerHost, Opts) ->
|
||||
nodetree_tree:init(Host, ServerHost, Opts),
|
||||
mnesia:transaction(fun create_node/5,
|
||||
[Host, [], "default", service_jid(ServerHost), []]).
|
||||
nodetree_tree:init(Host, ServerHost, Opts).
|
||||
|
||||
terminate(Host, ServerHost) ->
|
||||
nodetree_tree:terminate(Host, ServerHost).
|
||||
|
||||
create_node(Key, NodeID, Type, Owner, Options) ->
|
||||
create_node(Key, NodeID, Type, Owner, Options, Parents) ->
|
||||
OwnerJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
case find_node(Key, NodeID) of
|
||||
false ->
|
||||
@ -68,6 +66,7 @@ create_node(Key, NodeID, Type, Owner, Options) ->
|
||||
N = #pubsub_node{nodeid = oid(Key, NodeID),
|
||||
id = ID,
|
||||
type = Type,
|
||||
parents = Parents,
|
||||
owners = [OwnerJID],
|
||||
options = Options},
|
||||
case set_node(N) of
|
||||
|
@ -56,7 +56,7 @@
|
||||
get_parentnodes_tree/3,
|
||||
get_subnodes/3,
|
||||
get_subnodes_tree/3,
|
||||
create_node/5,
|
||||
create_node/6,
|
||||
delete_node/2
|
||||
]).
|
||||
|
||||
@ -160,13 +160,13 @@ get_parentnodes_tree(Host, Node, From) ->
|
||||
%% From = mod_pubsub:jid()
|
||||
get_subnodes(Host, Node, _From) ->
|
||||
get_subnodes(Host, Node).
|
||||
get_subnodes(Host, <<>>) ->
|
||||
Q = qlc:q([N || #pubsub_node{nodeid = {NHost, _},
|
||||
parents = Parents} = N <- mnesia:table(pubsub_node),
|
||||
Host == NHost,
|
||||
Parents == []]),
|
||||
qlc:e(Q);
|
||||
get_subnodes(Host, Node) ->
|
||||
% mnesia:foldl(fun(#pubsub_node{nodeid = {H, _}, parents = Parents} = N, Acc) ->
|
||||
% case lists:member(Node, Parents) and (Host == H) of
|
||||
% true -> [N | Acc];
|
||||
% false -> Acc
|
||||
% end
|
||||
% end, [], pubsub_node).
|
||||
Q = qlc:q([N || #pubsub_node{nodeid = {NHost, _},
|
||||
parents = Parents} = N <- mnesia:table(pubsub_node),
|
||||
Host == NHost,
|
||||
@ -181,12 +181,21 @@ get_subnodes_tree(Host, Node, _From) ->
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% From = mod_pubsub:jid()
|
||||
get_subnodes_tree(Host, Node) ->
|
||||
case get_node(Host, Node) of
|
||||
{error, _} ->
|
||||
[];
|
||||
Rec ->
|
||||
BasePlugin = list_to_atom("node_"++Rec#pubsub_node.type),
|
||||
BasePath = BasePlugin:node_to_path(Node),
|
||||
mnesia:foldl(fun(#pubsub_node{nodeid = {H, N}} = R, Acc) ->
|
||||
case lists:prefix(Node, N) and (H == Host) of
|
||||
Plugin = list_to_atom("node_"++R#pubsub_node.type),
|
||||
Path = Plugin:node_to_path(N),
|
||||
case lists:prefix(BasePath, Path) and (H == Host) of
|
||||
true -> [R | Acc];
|
||||
false -> Acc
|
||||
end
|
||||
end, [], pubsub_node).
|
||||
end, [], pubsub_node)
|
||||
end.
|
||||
|
||||
%% @spec (Host, Node, Type, Owner, Options) -> ok | {error, Reason}
|
||||
%% Host = mod_pubsub:host() | mod_pubsub:jid()
|
||||
@ -194,26 +203,27 @@ get_subnodes_tree(Host, Node) ->
|
||||
%% NodeType = mod_pubsub:nodeType()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Options = list()
|
||||
create_node(Host, Node, Type, Owner, Options) ->
|
||||
create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
BJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
case catch mnesia:read({pubsub_node, {Host, Node}}) of
|
||||
[] ->
|
||||
{ParentNode, ParentExists} =
|
||||
ParentExists =
|
||||
case Host of
|
||||
{_U, _S, _R} ->
|
||||
%% This is special case for PEP handling
|
||||
%% PEP does not uses hierarchy
|
||||
{[], true};
|
||||
true;
|
||||
_ ->
|
||||
case lists:sublist(Node, length(Node) - 1) of
|
||||
[] ->
|
||||
{[], true};
|
||||
Parent ->
|
||||
case Parents of
|
||||
[] -> true;
|
||||
[Parent|_] ->
|
||||
case catch mnesia:read({pubsub_node, {Host, Parent}}) of
|
||||
[#pubsub_node{owners = [{[], Host, []}]}] -> {Parent, true};
|
||||
[#pubsub_node{owners = Owners}] -> {Parent, lists:member(BJID, Owners)};
|
||||
_ -> {Parent, false}
|
||||
end
|
||||
[#pubsub_node{owners = [{[], Host, []}]}] -> true;
|
||||
[#pubsub_node{owners = Owners}] -> lists:member(BJID, Owners);
|
||||
_ -> false
|
||||
end;
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
case ParentExists of
|
||||
@ -221,7 +231,7 @@ create_node(Host, Node, Type, Owner, Options) ->
|
||||
NodeId = pubsub_index:new(node),
|
||||
mnesia:write(#pubsub_node{nodeid = {Host, Node},
|
||||
id = NodeId,
|
||||
parents = [ParentNode],
|
||||
parents = Parents,
|
||||
type = Type,
|
||||
owners = [BJID],
|
||||
options = Options}),
|
||||
|
@ -57,7 +57,7 @@
|
||||
get_parentnodes_tree/3,
|
||||
get_subnodes/3,
|
||||
get_subnodes_tree/3,
|
||||
create_node/5,
|
||||
create_node/6,
|
||||
delete_node/2
|
||||
]).
|
||||
|
||||
@ -209,30 +209,39 @@ get_subnodes_tree(Host, Node) ->
|
||||
%% NodeType = mod_pubsub:nodeType()
|
||||
%% Owner = mod_pubsub:jid()
|
||||
%% Options = list()
|
||||
create_node(Host, Node, Type, _Owner, Options) ->
|
||||
%% Parents = list()
|
||||
create_node(Host, Node, Type, Owner, Options, Parents) ->
|
||||
BJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
case nodeid(Host, Node) of
|
||||
{error, ?ERR_ITEM_NOT_FOUND} ->
|
||||
{ParentNode, ParentExists} = case Host of
|
||||
ParentExists =
|
||||
case Host of
|
||||
{_U, _S, _R} ->
|
||||
%% This is special case for PEP handling
|
||||
%% PEP does not uses hierarchy
|
||||
{[], true};
|
||||
true;
|
||||
_ ->
|
||||
case lists:sublist(Node, length(Node) - 1) of
|
||||
[] ->
|
||||
{[], true};
|
||||
Parent ->
|
||||
case Parents of
|
||||
[] -> true;
|
||||
[Parent|_] ->
|
||||
case nodeid(Host, Parent) of
|
||||
{result, _} -> {Parent, true};
|
||||
_ -> {Parent, false}
|
||||
end
|
||||
{result, PNodeId} ->
|
||||
case nodeowners(PNodeId) of
|
||||
[{[], Host, []}] -> true;
|
||||
Owners -> lists:member(BJID, Owners)
|
||||
end;
|
||||
_ ->
|
||||
false
|
||||
end;
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
case ParentExists of
|
||||
true ->
|
||||
case set_node(#pubsub_node{
|
||||
nodeid={Host, Node},
|
||||
parents=[ParentNode],
|
||||
parents=Parents,
|
||||
type=Type,
|
||||
options=Options}) of
|
||||
{result, NodeId} -> {ok, NodeId};
|
||||
@ -285,8 +294,8 @@ raw_to_node(Host, {Node, Parent, Type, NodeId}) ->
|
||||
[]
|
||||
end,
|
||||
#pubsub_node{
|
||||
nodeid = {Host, string_to_node(Host, Node)},
|
||||
parents = [string_to_node(Host, Parent)],
|
||||
nodeid = {Host, ?PUBSUB:string_to_node(Node)},
|
||||
parents = [?PUBSUB:string_to_node(Parent)],
|
||||
id = NodeId,
|
||||
type = Type,
|
||||
options = Options}.
|
||||
@ -295,7 +304,10 @@ raw_to_node(Host, {Node, Parent, Type, NodeId}) ->
|
||||
%% Record = mod_pubsub:pubsub_node()
|
||||
set_node(Record) ->
|
||||
{Host, Node} = Record#pubsub_node.nodeid,
|
||||
[Parent] = Record#pubsub_node.parents,
|
||||
Parent = case Record#pubsub_node.parents of
|
||||
[] -> <<>>;
|
||||
[First|_] -> First
|
||||
end,
|
||||
Type = Record#pubsub_node.type,
|
||||
H = ?PUBSUB:escape(Host),
|
||||
N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)),
|
||||
@ -352,5 +364,8 @@ nodeid(Host, Node) ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
end.
|
||||
|
||||
string_to_node({_, _, _}, Node) -> Node;
|
||||
string_to_node(_, Node) -> ?PUBSUB:string_to_node(Node).
|
||||
nodeowners(NodeId) ->
|
||||
{result, Res} = node_hometree_odbc:get_node_affiliations(NodeId),
|
||||
lists:foldl(fun({LJID, owner}, Acc) -> [LJID|Acc];
|
||||
(_, Acc) -> Acc
|
||||
end, [], Res).
|
||||
|
@ -51,7 +51,7 @@
|
||||
get_parentnodes_tree/3,
|
||||
get_subnodes/3,
|
||||
get_subnodes_tree/3,
|
||||
create_node/5,
|
||||
create_node/6,
|
||||
delete_node/2
|
||||
]).
|
||||
|
||||
@ -157,7 +157,7 @@ get_subnodes_tree(_Host, _Node) ->
|
||||
%% @doc <p>No node record is stored on database. Any valid node
|
||||
%% is considered as already created.</p>
|
||||
%% <p>default allowed nodes: /home/host/user/any/node/name</p>
|
||||
create_node(Host, Node, _Type, _Owner, _Options) ->
|
||||
create_node(Host, Node, _Type, _Owner, _Options, _Parents) ->
|
||||
{error, {virtual, {Host, Node}}}.
|
||||
|
||||
%% @spec (Host, Node) -> [mod_pubsub:node()]
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- mod_pubsub.erl 2009-10-13 18:30:32.000000000 +0200
|
||||
+++ mod_pubsub_odbc.erl 2009-10-13 18:30:47.000000000 +0200
|
||||
--- mod_pubsub.erl 2009-10-20 16:33:47.000000000 +0200
|
||||
+++ mod_pubsub_odbc.erl 2009-10-20 16:33:26.000000000 +0200
|
||||
@@ -42,7 +42,7 @@
|
||||
%%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see
|
||||
%%% XEP-0060 section 12.18.
|
||||
@ -49,7 +49,18 @@
|
||||
init_nodes(Host, ServerHost, NodeTree, Plugins),
|
||||
State = #state{host = Host,
|
||||
server_host = ServerHost,
|
||||
@@ -277,178 +275,6 @@
|
||||
@@ -269,207 +267,14 @@
|
||||
|
||||
init_nodes(Host, ServerHost, _NodeTree, Plugins) ->
|
||||
%% TODO, this call should be done plugin side
|
||||
- case lists:member("hometree", Plugins) of
|
||||
+ case lists:member("hometree_odbc", Plugins) of
|
||||
true ->
|
||||
- create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree"),
|
||||
- create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree");
|
||||
+ create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree_odbc"),
|
||||
+ create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree_odbc");
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
|
||||
@ -179,7 +190,28 @@
|
||||
- rename_default_nodeplugin();
|
||||
- _ ->
|
||||
- ok
|
||||
- end.
|
||||
- end,
|
||||
- mnesia:transaction(fun() ->
|
||||
- case catch mnesia:first(pubsub_node) of
|
||||
- {_, L} when is_list(L) ->
|
||||
- lists:foreach(
|
||||
- fun({H, N}) when is_list(N) ->
|
||||
- [Node] = mnesia:read({pubsub_node, {H, N}}),
|
||||
- Type = Node#pubsub_node.type,
|
||||
- BN = element(2, node_call(Type, path_to_node, [N])),
|
||||
- BP = case [element(2, node_call(Type, path_to_node, [P])) || P <- Node#pubsub_node.parents] of
|
||||
- [<<>>] -> [];
|
||||
- Parents -> Parents
|
||||
- end,
|
||||
- mnesia:write(Node#pubsub_node{nodeid={H, BN}, parents=BP}),
|
||||
- mnesia:delete({pubsub_node, {H, N}});
|
||||
- (_) ->
|
||||
- ok
|
||||
- end, mnesia:all_keys(pubsub_node));
|
||||
- _ ->
|
||||
- ok
|
||||
- end
|
||||
- end).
|
||||
-
|
||||
-rename_default_nodeplugin() ->
|
||||
- lists:foreach(fun(Node) ->
|
||||
@ -228,7 +260,7 @@
|
||||
send_queue(State, Msg) ->
|
||||
Pid = State#state.send_loop,
|
||||
case is_process_alive(Pid) of
|
||||
@@ -471,17 +297,15 @@
|
||||
@@ -492,17 +297,15 @@
|
||||
%% for each node From is subscribed to
|
||||
%% and if the node is so configured, send the last published item to From
|
||||
lists:foreach(fun(PType) ->
|
||||
@ -252,7 +284,7 @@
|
||||
true ->
|
||||
% resource not concerned about that subscription
|
||||
ok
|
||||
@@ -808,10 +632,10 @@
|
||||
@@ -825,10 +628,10 @@
|
||||
{result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Subscriber]),
|
||||
lists:foreach(fun
|
||||
({Node, subscribed, _, JID}) ->
|
||||
@ -265,7 +297,7 @@
|
||||
true ->
|
||||
node_action(Host, Type, unsubscribe_node, [NodeId, Subscriber, JID, all]);
|
||||
false ->
|
||||
@@ -926,7 +750,8 @@
|
||||
@@ -943,7 +746,8 @@
|
||||
sub_el = SubEl} = IQ ->
|
||||
{xmlelement, _, QAttrs, _} = SubEl,
|
||||
Node = xml:get_attr_s("node", QAttrs),
|
||||
@ -275,7 +307,7 @@
|
||||
{result, IQRes} ->
|
||||
jlib:iq_to_xml(
|
||||
IQ#iq{type = result,
|
||||
@@ -1031,7 +856,7 @@
|
||||
@@ -1048,7 +852,7 @@
|
||||
[] ->
|
||||
["leaf"]; %% No sub-nodes: it's a leaf node
|
||||
_ ->
|
||||
@ -284,7 +316,7 @@
|
||||
{result, []} -> ["collection"];
|
||||
{result, _} -> ["leaf", "collection"];
|
||||
_ -> []
|
||||
@@ -1047,8 +872,9 @@
|
||||
@@ -1064,8 +868,9 @@
|
||||
[];
|
||||
true ->
|
||||
[{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []} |
|
||||
@ -296,7 +328,7 @@
|
||||
end, features(Type))]
|
||||
end,
|
||||
%% TODO: add meta-data info (spec section 5.4)
|
||||
@@ -1076,14 +902,15 @@
|
||||
@@ -1093,21 +898,22 @@
|
||||
{xmlelement, "feature", [{"var", ?NS_DISCO_ITEMS}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []},
|
||||
{xmlelement, "feature", [{"var", ?NS_VCARD}], []}] ++
|
||||
@ -313,19 +345,18 @@
|
||||
-iq_disco_items(Host, [], From) ->
|
||||
+iq_disco_items(Host, [], From, _RSM) ->
|
||||
{result, lists:map(
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}}) ->
|
||||
SN = node_to_string(SubNode),
|
||||
@@ -1093,7 +920,7 @@
|
||||
{"node", SN},
|
||||
{"name", RN}], []}
|
||||
end, tree_action(Host, get_subnodes, [Host, [], From]))};
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}, type = Type}) ->
|
||||
{result, Path} = node_call(Type, node_to_path, [SubNode]),
|
||||
[Name|_] = lists:reverse(Path),
|
||||
{xmlelement, "item", [{"jid", Host}, {"name", Name}|nodeAttr(SubNode)], []}
|
||||
end, tree_action(Host, get_subnodes, [Host, <<>>, From]))};
|
||||
-iq_disco_items(Host, Item, From) ->
|
||||
+iq_disco_items(Host, Item, From, RSM) ->
|
||||
case string:tokens(Item, "!") of
|
||||
[_SNode, _ItemID] ->
|
||||
{result, []};
|
||||
@@ -1105,10 +932,10 @@
|
||||
%% TODO That is, remove name attribute (or node?, please check for 2.1)
|
||||
@@ -1115,10 +921,10 @@
|
||||
Node = string_to_node(SNode),
|
||||
Action =
|
||||
fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||
- % TODO call get_items/6 instead for access control (EJAB-1033)
|
||||
@ -338,16 +369,16 @@
|
||||
end,
|
||||
Nodes = lists:map(
|
||||
fun(#pubsub_node{nodeid = {_, SubNode}}) ->
|
||||
@@ -1124,7 +951,7 @@
|
||||
{xmlelement, "item", [{"jid", Host}, {"node", SN},
|
||||
{"name", Name}], []}
|
||||
@@ -1129,7 +935,7 @@
|
||||
{result, Name} = node_call(Type, get_item_name, [Host, Node, RN]),
|
||||
{xmlelement, "item", [{"jid", Host}, {"name", Name}], []}
|
||||
end, NodeItems),
|
||||
- {result, Nodes ++ Items}
|
||||
+ {result, Nodes ++ Items ++ jlib:rsm_encode(RsmOut)}
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
{result, {_, Result}} -> {result, Result};
|
||||
@@ -1256,7 +1083,8 @@
|
||||
@@ -1258,7 +1064,8 @@
|
||||
(_, Acc) ->
|
||||
Acc
|
||||
end, [], xml:remove_cdata(Els)),
|
||||
@ -357,7 +388,7 @@
|
||||
{get, "subscriptions"} ->
|
||||
get_subscriptions(Host, Node, From, Plugins);
|
||||
{get, "affiliations"} ->
|
||||
@@ -1279,7 +1107,9 @@
|
||||
@@ -1281,7 +1088,9 @@
|
||||
|
||||
iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
|
||||
{xmlelement, _, _, SubEls} = SubEl,
|
||||
@ -367,8 +398,8 @@
|
||||
+ end, xml:remove_cdata(SubEls)),
|
||||
case Action of
|
||||
[{xmlelement, Name, Attrs, Els}] ->
|
||||
Node = case Host of
|
||||
@@ -1405,7 +1235,8 @@
|
||||
Node = string_to_node(xml:get_attr_s("node", Attrs)),
|
||||
@@ -1404,7 +1213,8 @@
|
||||
_ -> []
|
||||
end
|
||||
end,
|
||||
@ -378,7 +409,7 @@
|
||||
sync_dirty) of
|
||||
{result, Res} -> Res;
|
||||
Err -> Err
|
||||
@@ -1445,7 +1276,7 @@
|
||||
@@ -1444,7 +1254,7 @@
|
||||
|
||||
%%% authorization handling
|
||||
|
||||
@ -387,7 +418,7 @@
|
||||
Lang = "en", %% TODO fix
|
||||
Stanza = {xmlelement, "message",
|
||||
[],
|
||||
@@ -1474,7 +1305,7 @@
|
||||
@@ -1473,7 +1283,7 @@
|
||||
[{xmlelement, "value", [], [{xmlcdata, "false"}]}]}]}]},
|
||||
lists:foreach(fun(Owner) ->
|
||||
ejabberd_router ! {route, service_jid(Host), jlib:make_jid(Owner), Stanza}
|
||||
@ -396,7 +427,7 @@
|
||||
|
||||
find_authorization_response(Packet) ->
|
||||
{xmlelement, _Name, _Attrs, Els} = Packet,
|
||||
@@ -1541,8 +1372,8 @@
|
||||
@@ -1537,8 +1347,8 @@
|
||||
"true" -> true;
|
||||
_ -> false
|
||||
end,
|
||||
@ -407,7 +438,7 @@
|
||||
{result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]),
|
||||
if
|
||||
not IsApprover ->
|
||||
@@ -1728,7 +1559,7 @@
|
||||
@@ -1729,7 +1539,7 @@
|
||||
Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
|
||||
[{xmlelement, "create", nodeAttr(Node),
|
||||
[]}]}],
|
||||
@ -416,7 +447,7 @@
|
||||
{result, {Result, broadcast}} ->
|
||||
%%Lang = "en", %% TODO: fix
|
||||
%%OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
@@ -1836,7 +1667,7 @@
|
||||
@@ -1837,7 +1647,7 @@
|
||||
%%<li>The node does not exist.</li>
|
||||
%%</ul>
|
||||
subscribe_node(Host, Node, From, JID, Configuration) ->
|
||||
@ -425,7 +456,7 @@
|
||||
{result, GoodSubOpts} -> GoodSubOpts;
|
||||
_ -> invalid
|
||||
end,
|
||||
@@ -1844,7 +1675,7 @@
|
||||
@@ -1845,7 +1655,7 @@
|
||||
error -> {"", "", ""};
|
||||
J -> jlib:jid_tolower(J)
|
||||
end,
|
||||
@ -434,7 +465,7 @@
|
||||
Features = features(Type),
|
||||
SubscribeFeature = lists:member("subscribe", Features),
|
||||
OptionsFeature = lists:member("subscription-options", Features),
|
||||
@@ -1863,9 +1694,13 @@
|
||||
@@ -1864,9 +1674,13 @@
|
||||
{"", "", ""} ->
|
||||
{false, false};
|
||||
_ ->
|
||||
@ -451,7 +482,7 @@
|
||||
end
|
||||
end,
|
||||
if
|
||||
@@ -2196,7 +2031,7 @@
|
||||
@@ -2197,7 +2011,7 @@
|
||||
%% <p>The permission are not checked in this function.</p>
|
||||
%% @todo We probably need to check that the user doing the query has the right
|
||||
%% to read the items.
|
||||
@ -460,7 +491,7 @@
|
||||
MaxItems =
|
||||
if
|
||||
SMaxItems == "" -> get_max_items_node(Host);
|
||||
@@ -2235,11 +2070,11 @@
|
||||
@@ -2236,11 +2050,11 @@
|
||||
node_call(Type, get_items,
|
||||
[NodeId, From,
|
||||
AccessModel, PresenceSubscription, RosterGroup,
|
||||
@ -474,7 +505,7 @@
|
||||
SendItems = case ItemIDs of
|
||||
[] ->
|
||||
Items;
|
||||
@@ -2252,7 +2087,8 @@
|
||||
@@ -2253,7 +2067,8 @@
|
||||
%% number of items sent to MaxItems:
|
||||
{result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
|
||||
[{xmlelement, "items", nodeAttr(Node),
|
||||
@ -484,7 +515,7 @@
|
||||
Error ->
|
||||
Error
|
||||
end
|
||||
@@ -2284,16 +2120,27 @@
|
||||
@@ -2285,16 +2100,27 @@
|
||||
%% @doc <p>Resend the items of a node to the user.</p>
|
||||
%% @todo use cache-last-item feature
|
||||
send_items(Host, Node, NodeId, Type, LJID, last) ->
|
||||
@ -518,7 +549,7 @@
|
||||
send_items(Host, Node, NodeId, Type, LJID, Number) ->
|
||||
ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of
|
||||
{result, []} ->
|
||||
@@ -2419,29 +2266,12 @@
|
||||
@@ -2420,29 +2246,12 @@
|
||||
error ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
_ ->
|
||||
@ -551,7 +582,7 @@
|
||||
end, Entities),
|
||||
{result, []};
|
||||
_ ->
|
||||
@@ -2494,11 +2324,11 @@
|
||||
@@ -2495,11 +2304,11 @@
|
||||
end.
|
||||
|
||||
read_sub(Subscriber, Node, NodeID, SubID, Lang) ->
|
||||
@ -562,10 +593,10 @@
|
||||
{result, #pubsub_subscription{options = Options}} ->
|
||||
- {result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options),
|
||||
+ {result, XdataEl} = pubsub_subscription_odbc:get_options_xform(Lang, Options),
|
||||
OptionsEl = {xmlelement, "options", [{"node", node_to_string(Node)},
|
||||
{"jid", jlib:jid_to_string(Subscriber)},
|
||||
{"subid", SubID}],
|
||||
@@ -2525,7 +2355,7 @@
|
||||
OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)},
|
||||
{"subid", SubID}|nodeAttr(Node)],
|
||||
[XdataEl]},
|
||||
@@ -2525,7 +2334,7 @@
|
||||
end.
|
||||
|
||||
set_options_helper(Configuration, JID, NodeID, SubID, Type) ->
|
||||
@ -574,7 +605,7 @@
|
||||
{result, GoodSubOpts} -> GoodSubOpts;
|
||||
_ -> invalid
|
||||
end,
|
||||
@@ -2554,7 +2384,7 @@
|
||||
@@ -2554,7 +2363,7 @@
|
||||
write_sub(_Subscriber, _NodeID, _SubID, invalid) ->
|
||||
{error, extended_error(?ERR_BAD_REQUEST, "invalid-options")};
|
||||
write_sub(Subscriber, NodeID, SubID, Options) ->
|
||||
@ -583,7 +614,7 @@
|
||||
{error, notfound} ->
|
||||
{error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
{result, _} ->
|
||||
@@ -2722,8 +2552,8 @@
|
||||
@@ -2722,8 +2531,8 @@
|
||||
{"subscription", subscription_to_string(Sub)} | nodeAttr(Node)], []}]}]},
|
||||
ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza}
|
||||
end,
|
||||
@ -594,7 +625,7 @@
|
||||
true ->
|
||||
Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) ->
|
||||
|
||||
@@ -3013,7 +2843,7 @@
|
||||
@@ -3007,7 +2816,7 @@
|
||||
{Depth, [{N, get_node_subs(N)} || N <- Nodes]}
|
||||
end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))}
|
||||
end,
|
||||
@ -603,7 +634,7 @@
|
||||
{result, CollSubs} -> CollSubs;
|
||||
_ -> []
|
||||
end.
|
||||
@@ -3027,9 +2857,9 @@
|
||||
@@ -3021,9 +2830,9 @@
|
||||
|
||||
get_options_for_subs(NodeID, Subs) ->
|
||||
lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
|
||||
@ -615,7 +646,7 @@
|
||||
_ -> Acc
|
||||
end;
|
||||
(_, Acc) ->
|
||||
@@ -3227,6 +3057,30 @@
|
||||
@@ -3221,6 +3030,30 @@
|
||||
Result
|
||||
end.
|
||||
|
||||
@ -646,7 +677,7 @@
|
||||
%% @spec (Host, Options) -> MaxItems
|
||||
%% Host = host()
|
||||
%% Options = [Option]
|
||||
@@ -3613,7 +3467,13 @@
|
||||
@@ -3607,7 +3440,13 @@
|
||||
tree_action(Host, Function, Args) ->
|
||||
?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]),
|
||||
Fun = fun() -> tree_call(Host, Function, Args) end,
|
||||
@ -661,7 +692,7 @@
|
||||
|
||||
%% @doc <p>node plugin call.</p>
|
||||
node_call(Type, Function, Args) ->
|
||||
@@ -3633,13 +3493,13 @@
|
||||
@@ -3627,13 +3466,13 @@
|
||||
|
||||
node_action(Host, Type, Function, Args) ->
|
||||
?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]),
|
||||
@ -677,7 +708,7 @@
|
||||
case tree_call(Host, get_node, [Host, Node]) of
|
||||
N when is_record(N, pubsub_node) ->
|
||||
case Action(N) of
|
||||
@@ -3652,8 +3512,14 @@
|
||||
@@ -3646,8 +3485,14 @@
|
||||
end
|
||||
end, Trans).
|
||||
|
||||
@ -694,7 +725,7 @@
|
||||
{result, Result} -> {result, Result};
|
||||
{error, Error} -> {error, Error};
|
||||
{atomic, {result, Result}} -> {result, Result};
|
||||
@@ -3661,6 +3527,15 @@
|
||||
@@ -3655,6 +3500,15 @@
|
||||
{aborted, Reason} ->
|
||||
?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
@ -710,7 +741,7 @@
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
@@ -3669,6 +3544,17 @@
|
||||
@@ -3663,6 +3517,17 @@
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR}
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user