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