diff --git a/ChangeLog b/ChangeLog
index 17685cbf8..be5e8d772 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,13 @@
* src/gen_iq_handler.erl: Add the module and function names to the
error message, when a module crash.
+ * src/mod_pubsub/mod_pubsub.erl, src/mod_pubsub/nodetree_default.erl,
+ src/mod_pubsub/node_default.erl, src/mod_pubsub/node_pep.erl: First
+ pass of Exmpp conversion for mod_pubsub. Several modules aren't
+ converted yet. Existent Mnesia tables written to disc are not
+ updated. There must be bugs, mostly because of the mix between #jid
+ record and short JIDs.
+
2008-12-03 Jean-Sébastien Pédron
* src/mod_proxy65/mod_proxy65_stream.erl,
diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl
index a1d6febf2..fed1c3aff 100644
--- a/src/mod_pubsub/mod_pubsub.erl
+++ b/src/mod_pubsub/mod_pubsub.erl
@@ -45,8 +45,9 @@
-behaviour(gen_server).
-behaviour(gen_mod).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("pubsub.hrl").
-define(STDTREE, "default").
@@ -157,7 +158,7 @@ init([ServerHost, Opts]) ->
?DEBUG("pubsub init ~p ~p",[ServerHost,Opts]),
Host = gen_mod:get_opt_host(ServerHost, Opts, "pubsub.@HOST@"),
Access = gen_mod:get_opt(access_createnode, Opts, all),
- mod_disco:register_feature(ServerHost, ?NS_PUBSUB),
+ mod_disco:register_feature(ServerHost, ?NS_PUBSUB_s),
ejabberd_hooks:add(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75),
ejabberd_hooks:add(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75),
ejabberd_hooks:add(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75),
@@ -305,24 +306,24 @@ update_database(Host) ->
identity(Host) ->
Identity = case lists:member(?PEPNODE, plugins(Host)) of
- true -> [{"category", "pubsub"}, {"type", "pep"}];
- false -> [{"category", "pubsub"}, {"type", "service"}]
+ true -> [#xmlattr{name = 'category', value = "pubsub"}, #xmlattr{name = 'type', value = "pep"}];
+ false -> [#xmlattr{name = 'category', value = "pubsub"}, #xmlattr{name = 'type', value = "service"}]
end,
- {xmlelement, "identity", Identity, []}.
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs = Identity}.
disco_local_identity(Acc, _From, To, [], _Lang) ->
- Acc ++ [identity(To#jid.lserver)];
+ Acc ++ [identity(To#jid.ldomain)];
disco_local_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
disco_local_features(Acc, _From, To, [], _Lang) ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
Feats = case Acc of
{result, I} -> I;
_ -> []
end,
{result, Feats ++ lists:map(fun(Feature) ->
- ?NS_PUBSUB++"#"++Feature
+ ?NS_PUBSUB_s++"#"++Feature
end, features(Host, []))};
disco_local_features(Acc, _From, _To, _Node, _Lang) ->
Acc.
@@ -333,9 +334,9 @@ disco_local_items(Acc, _From, _To, _Node, _Lang) ->
Acc.
disco_sm_identity(Acc, _From, To, [], _Lang) ->
- Acc ++ [identity(To#jid.lserver)];
+ Acc ++ [identity(To#jid.ldomain)];
disco_sm_identity(Acc, From, To, Node, _Lang) ->
- LOwner = jlib:jid_tolower(jlib:jid_remove_resource(To)),
+ LOwner = jlib:short_prepd_bare_jid(To),
Acc ++ case node_disco_identity(LOwner, From, Node) of
{result, I} -> I;
_ -> []
@@ -344,7 +345,7 @@ disco_sm_identity(Acc, From, To, Node, _Lang) ->
disco_sm_features(Acc, _From, _To, [], _Lang) ->
Acc;
disco_sm_features(Acc, From, To, Node, _Lang) ->
- LOwner = jlib:jid_tolower(jlib:jid_remove_resource(To)),
+ LOwner = jlib:short_prepd_bare_jid(To),
Features = node_disco_features(LOwner, From, Node),
case {Acc, Features} of
{{result, AccFeatures}, {result, AddFeatures}} ->
@@ -357,8 +358,8 @@ disco_sm_features(Acc, From, To, Node, _Lang) ->
disco_sm_items(Acc, _From, To, [], _Lang) ->
%% TODO, use iq_disco_items(Host, [], From)
- Host = To#jid.lserver,
- LJID = jlib:jid_tolower(jlib:jid_remove_resource(To)),
+ Host = To#jid.ldomain,
+ LJID = jlib:short_prepd_bare_jid(To),
case tree_action(Host, get_nodes, [Host]) of
[] ->
Acc;
@@ -369,18 +370,17 @@ disco_sm_items(Acc, _From, To, [], _Lang) ->
end,
NodeItems = lists:map(
fun(Node) ->
- {xmlelement, "item",
- [{"jid", jlib:jid_to_string(LJID)},
- {"node", node_to_string(Node)}],
- []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(LJID)},
+ #xmlattr{name = 'node', value = node_to_string(Node)}]}
end, Nodes),
{result, NodeItems ++ Items}
end;
disco_sm_items(Acc, From, To, Node, _Lang) ->
%% TODO, use iq_disco_items(Host, Node, From)
- Host = To#jid.lserver,
- LJID = jlib:jid_tolower(jlib:jid_remove_resource(To)),
+ Host = To#jid.ldomain,
+ LJID = jlib:short_prepd_bare_jid(To),
case get_items(Host, Node, From) of
[] ->
Acc;
@@ -393,10 +393,9 @@ disco_sm_items(Acc, From, To, Node, _Lang) ->
fun(#pubsub_item{itemid = Id}) ->
%% "jid" is required by XEP-0030, and
%% "node" is forbidden by XEP-0060.
- {xmlelement, "item",
- [{"jid", jlib:jid_to_string(LJID)},
- {"name", get_item_name(Host, Node, Id)}],
- []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(LJID)},
+ #xmlattr{name = 'name', value = get_item_name(Host, Node, Id)}]}
end, AllItems),
{result, NodeItems ++ Items}
end.
@@ -405,7 +404,7 @@ disco_sm_items(Acc, From, To, Node, _Lang) ->
%% presence hooks handling functions
%%
-presence_probe(#jid{lserver = Host} = JID, JID, Pid) ->
+presence_probe(#jid{ldomain = Host} = JID, JID, Pid) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:cast(Proc, {presence, JID, Pid});
presence_probe(_, _, _) ->
@@ -416,8 +415,8 @@ presence_probe(_, _, _) ->
%%
remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
Proc = gen_mod:get_module_proc(Server, ?PROCNAME),
gen_server:cast(Proc, {remove_user, LUser, LServer}).
@@ -452,7 +451,7 @@ handle_call(stop, _From, State) ->
%% @private
handle_cast({presence, JID, Pid}, State) ->
%% A new resource is available. send last published items
- LJID = jlib:jid_tolower(JID),
+ LJID = jlib:short_prepd_jid(JID),
Host = State#state.host,
ServerHost = State#state.server_host,
%% for each node From is subscribed to
@@ -484,7 +483,7 @@ handle_cast({presence, JID, Pid}, State) ->
fun({{User, Server, _}, _}) -> {User, Server} end, ContactsWithCaps)),
lists:foreach(
fun({User, Server}) ->
- PepKey = {User, Server, ""},
+ PepKey = {User, Server, undefined},
lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, options = Options}) ->
case get_option(Options, send_last_published_item) of
on_sub_and_presence ->
@@ -500,7 +499,7 @@ handle_cast({presence, JID, Pid}, State) ->
element(2, get_roster_info(User, Server, LJID, Grps))
end,
if Subscribed ->
- ?DEBUG("send ~s's ~s event to ~s",[jlib:jid_to_string(PepKey),Node,jlib:jid_to_string(LJID)]),
+ ?DEBUG("send ~s's ~s event to ~s",[exmpp_jid:jid_to_list(User, Server),Node,exmpp_jid:jid_to_list(JID)]),
send_last_item(PepKey, Node, LJID);
true ->
ok
@@ -520,14 +519,14 @@ handle_cast({presence, JID, Pid}, State) ->
handle_cast({remove_user, LUser, LServer}, State) ->
Host = State#state.host,
- Owner = jlib:make_jid(LUser, LServer, ""),
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ Owner = exmpp_jid:make_bare_jid(LUser, LServer),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
%% remove user's subscriptions
lists:foreach(fun(Type) ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, Owner]),
lists:foreach(fun
({Node, subscribed}) ->
- JID = jlib:jid_to_string(Owner),
+ JID = exmpp_jid:jid_to_list(LUser, LServer),
unsubscribe_node(Host, Node, Owner, JID, all);
(_) ->
ok
@@ -555,7 +554,7 @@ handle_info({route, From, To, Packet},
#state{server_host = ServerHost,
access = Access,
plugins = Plugins} = State) ->
- case catch do_route(ServerHost, Access, Plugins, To#jid.lserver, From, To, Packet) of
+ case catch do_route(ServerHost, Access, Plugins, To#jid.ldomain, From, To, Packet) of
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
_ -> ok
end,
@@ -591,7 +590,7 @@ terminate(_Reason, #state{host = Host,
{?NS_PUBSUB_OWNER, ejabberd_local},
{?NS_PUBSUB, ejabberd_sm},
{?NS_PUBSUB_OWNER, ejabberd_sm}]),
- mod_disco:unregister_feature(ServerHost, ?NS_PUBSUB),
+ mod_disco:unregister_feature(ServerHost, ?NS_PUBSUB_s),
ok.
%%--------------------------------------------------------------------
@@ -606,89 +605,86 @@ code_change(_OldVsn, State, _Extra) ->
%%% Internal functions
%%--------------------------------------------------------------------
do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
- {xmlelement, Name, Attrs, _Els} = Packet,
+ #xmlel{name = Name} = Packet,
case To of
- #jid{luser = "", lresource = ""} ->
+ #jid{lnode = undefined, lresource = undefined} ->
case Name of
- "iq" ->
- case jlib:iq_query_info(Packet) of
- #iq{type = get, xmlns = ?NS_DISCO_INFO,
- sub_el = SubEl, lang = Lang} = IQ ->
- {xmlelement, _, QAttrs, _} = SubEl,
- Node = xml:get_attr_s("node", QAttrs),
+ 'iq' ->
+ case exmpp_iq:xmlel_to_iq(Packet) of
+ #iq{type = get, ns = ?NS_DISCO_INFO,
+ payload = SubEl, lang = Lang} ->
+ QAttrs = SubEl#xmlel.attrs,
+ Node = exmpp_xml:get_attribute_from_list(QAttrs,
+ 'node', ""),
Res = case iq_disco_info(Host, Node, From, Lang) of
{result, IQRes} ->
- jlib:iq_to_xml(
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- QAttrs, IQRes}]});
+ Result = #xmlel{ns = ?NS_DISCO_INFO,
+ name = 'query', attrs = QAttrs,
+ children = IQRes},
+ exmpp_iq:result(Packet, Result);
{error, Error} ->
- jlib:make_error_reply(Packet, Error)
+ exmpp_iq:error(Packet, Error)
end,
ejabberd_router:route(To, From, Res);
- #iq{type = get, xmlns = ?NS_DISCO_ITEMS,
- sub_el = SubEl} = IQ ->
- {xmlelement, _, QAttrs, _} = SubEl,
- Node = xml:get_attr_s("node", QAttrs),
+ #iq{type = get, ns = ?NS_DISCO_ITEMS,
+ payload = SubEl} ->
+ QAttrs = SubEl#xmlel.attrs,
+ Node = exmpp_xml:get_attribute_from_list(QAttrs,
+ 'node', ""),
Res = case iq_disco_items(Host, Node, From) of
{result, IQRes} ->
- jlib:iq_to_xml(
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- QAttrs, IQRes}]});
+ Result = #xmlel{ns = ?NS_DISCO_ITEMS,
+ name = 'query', attrs = QAttrs,
+ children = IQRes},
+ exmpp_iq:result(Packet, Result);
{error, Error} ->
- jlib:make_error_reply(Packet, Error)
+ exmpp_iq:error(Packet, Error)
end,
ejabberd_router:route(To, From, Res);
- #iq{type = IQType, xmlns = ?NS_PUBSUB,
- lang = Lang, sub_el = SubEl} = IQ ->
+ #iq{type = IQType, ns = ?NS_PUBSUB,
+ lang = Lang, payload = SubEl} ->
Res =
case iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) of
{result, IQRes} ->
- jlib:iq_to_xml(
- IQ#iq{type = result,
- sub_el = IQRes});
+ exmpp_iq:result(Packet, IQRes);
{error, Error} ->
- jlib:make_error_reply(Packet, Error)
+ exmpp_iq:error(Packet, Error)
end,
ejabberd_router:route(To, From, Res);
- #iq{type = IQType, xmlns = ?NS_PUBSUB_OWNER,
- lang = Lang, sub_el = SubEl} = IQ ->
+ #iq{type = IQType, ns = ?NS_PUBSUB_OWNER,
+ lang = Lang, payload = SubEl} ->
Res =
case iq_pubsub_owner(Host, From, IQType, SubEl, Lang) of
{result, IQRes} ->
- jlib:iq_to_xml(
- IQ#iq{type = result,
- sub_el = IQRes});
+ exmpp_iq:result(Packet, IQRes);
{error, Error} ->
- jlib:make_error_reply(Packet, Error)
+ exmpp_iq:error(Packet, Error)
end,
ejabberd_router:route(To, From, Res);
- #iq{type = get, xmlns = ?NS_VCARD = XMLNS,
- lang = Lang, sub_el = _SubEl} = IQ ->
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To, From, jlib:iq_to_xml(Res));
+ #iq{type = get, ns = ?NS_VCARD = XMLNS,
+ lang = Lang} ->
+ VCard = #xmlel{ns = XMLNS, name = 'vCard',
+ children = iq_get_vcard(Lang)},
+ Res = exmpp_iq:result(Packet, VCard),
+ ejabberd_router:route(To, From, Res);
#iq{} ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_FEATURE_NOT_IMPLEMENTED),
+ Err = exmpp_iq:error(Packet,
+ 'feature-not-implemented'),
ejabberd_router:route(To, From, Err);
_ ->
ok
end;
- "message" ->
- case xml:get_attr_s("type", Attrs) of
- "error" ->
+ 'message' ->
+ case exmpp_stanza:is_stanza_error(Packet) of
+ true ->
ok;
- _ ->
+ false ->
case find_authorization_response(Packet) of
none ->
ok;
invalid ->
ejabberd_router:route(To, From,
- jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST));
+ exmpp_message:error(Packet, 'bad-request'));
XFields ->
handle_authorization_response(Host, From, To, Packet, XFields)
end
@@ -697,13 +693,14 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
ok
end;
_ ->
- case xml:get_attr_s("type", Attrs) of
+ case exmpp_stanza:get_type(Packet) of
"error" ->
ok;
"result" ->
ok;
_ ->
- Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
+ Err = exmpp_stanza:reply_with_error(Packet,
+ 'item-not-found'),
ejabberd_router:route(To, From, Err)
end
end.
@@ -733,17 +730,17 @@ node_disco_info(Host, Node, From, Identity, Features) ->
end
end,
lists:map(fun(T) ->
- {xmlelement, "identity", [{"category", "pubsub"},
- {"type", T}], []}
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs = [#xmlattr{name = 'category', value = "pubsub"},
+ #xmlattr{name = 'type', value = T}]}
end, Types)
end,
F = case Features of
false ->
[];
true ->
- [{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []} |
+ [#xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [#xmlattr{name = 'var', value = ?NS_PUBSUB_s}]} |
lists:map(fun(T) ->
- {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++T}], []}
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [#xmlattr{name = 'var', value = ?NS_PUBSUB_s++"#"++T}]}
end, features(Type))]
end,
%% TODO: add meta-data info (spec section 5.4)
@@ -756,16 +753,16 @@ iq_disco_info(Host, SNode, From, Lang) ->
case Node of
[] ->
{result,
- [{xmlelement, "identity",
- [{"category", "pubsub"},
- {"type", "service"},
- {"name", translate:translate(Lang, "Publish-Subscribe")}], []},
- {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []},
- {xmlelement, "feature", [{"var", ?NS_DISCO_ITEMS}], []},
- {xmlelement, "feature", [{"var", ?NS_PUBSUB}], []},
- {xmlelement, "feature", [{"var", ?NS_VCARD}], []}] ++
+ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs =
+ [#xmlattr{name = 'category', value = "pubsub"},
+ #xmlattr{name = 'type', value = "service"},
+ #xmlattr{name = 'name', value = translate:translate(Lang, "Publish-Subscribe")}]},
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [#xmlattr{name = 'var', value = ?NS_DISCO_INFO_s}]},
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [#xmlattr{name = 'var', value = ?NS_DISCO_ITEMS_s}]},
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [#xmlattr{name = 'var', value = ?NS_PUBSUB_s}]},
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [#xmlattr{name = 'var', value = ?NS_VCARD_s}]}] ++
lists:map(fun(Feature) ->
- {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++Feature}], []}
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [#xmlattr{name = 'var', value = ?NS_PUBSUB_s++"#"++Feature}]}
end, features(Host, SNode))};
_ ->
node_disco_info(Host, Node, From)
@@ -777,9 +774,9 @@ iq_disco_items(Host, [], From) ->
SN = node_to_string(SubNode),
RN = lists:last(SubNode),
%% remove name attribute
- {xmlelement, "item", [{"jid", Host},
- {"node", SN},
- {"name", RN}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [#xmlattr{name = 'jid', value = Host},
+ #xmlattr{name = 'node', value = SN},
+ #xmlattr{name = 'name', value = RN}]}
end, tree_action(Host, get_subnodes, [Host, [], From]))};
iq_disco_items(Host, Item, From) ->
case string:tokens(Item, "!") of
@@ -801,14 +798,14 @@ iq_disco_items(Host, Item, From) ->
fun(#pubsub_node{nodeid = {_, SubNode}}) ->
SN = node_to_string(SubNode),
RN = lists:last(SubNode),
- {xmlelement, "item", [{"jid", Host}, {"node", SN},
- {"name", RN}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [#xmlattr{name = 'jid', value = Host}, #xmlattr{name = 'node', value = SN},
+ #xmlattr{name = 'name', value = RN}]}
end, tree_call(Host, get_subnodes, [Host, Node, From])),
Items = lists:map(
fun(#pubsub_item{itemid = {RN, _}}) ->
SN = node_to_string(Node) ++ "!" ++ RN,
- {xmlelement, "item", [{"jid", Host}, {"node", SN},
- {"name", get_item_name(Host, Node, RN)}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [#xmlattr{name = 'jid', value = Host}, #xmlattr{name = 'node', value = SN},
+ #xmlattr{name = 'name', value = get_item_name(Host, Node, RN)}]}
end, NodeItems),
{result, Nodes ++ Items}
end,
@@ -816,69 +813,70 @@ iq_disco_items(Host, Item, From) ->
end.
iq_local(From, To, #iq{type = Type,
- sub_el = SubEl,
- xmlns = XMLNS,
- lang = Lang} = IQ) ->
- ServerHost = To#jid.lserver,
+ payload = SubEl,
+ ns = XMLNS,
+ lang = Lang} = IQ_Rec) ->
+ ServerHost = To#jid.ldomain,
%% Accept IQs to server only from our own users.
if
- From#jid.lserver /= ServerHost ->
- IQ#iq{type = error, sub_el = [?ERR_FORBIDDEN, SubEl]};
+ From#jid.ldomain /= ServerHost ->
+ exmpp_iq:error(IQ_Rec, 'forbidden');
true ->
- LOwner = jlib:jid_tolower(jlib:jid_remove_resource(From)),
+ LOwner = jlib:short_prepd_bare_jid(From),
Res = case XMLNS of
?NS_PUBSUB -> iq_pubsub(LOwner, ServerHost, From, Type, SubEl, Lang);
?NS_PUBSUB_OWNER -> iq_pubsub_owner(LOwner, From, Type, SubEl, Lang)
end,
case Res of
- {result, IQRes} -> IQ#iq{type = result, sub_el = IQRes};
- {error, Error} -> IQ#iq{type = error, sub_el = [Error, SubEl]}
+ {result, []} -> exmpp_iq:result(IQ_Rec);
+ {result, [IQRes]} -> exmpp_iq:result(IQ_Rec, IQRes);
+ {error, Error} -> exmpp_iq:error(IQ_Rec, Error)
end
end.
-iq_sm(From, To, #iq{type = Type, sub_el = SubEl, xmlns = XMLNS, lang = Lang} = IQ) ->
- ServerHost = To#jid.lserver,
- LOwner = jlib:jid_tolower(jlib:jid_remove_resource(To)),
+iq_sm(From, To, #iq{type = Type, payload = SubEl, ns = XMLNS, lang = Lang} = IQ_Rec) ->
+ ServerHost = To#jid.ldomain,
+ LOwner = jlib:short_prepd_bare_jid(To),
Res = case XMLNS of
?NS_PUBSUB -> iq_pubsub(LOwner, ServerHost, From, Type, SubEl, Lang);
?NS_PUBSUB_OWNER -> iq_pubsub_owner(LOwner, From, Type, SubEl, Lang)
end,
case Res of
- {result, IQRes} -> IQ#iq{type = result, sub_el = IQRes};
- {error, Error} -> IQ#iq{type = error, sub_el = [Error, SubEl]}
+ {result, []} -> exmpp_iq:result(IQ_Rec);
+ {result, [IQRes]} -> exmpp_iq:result(IQ_Rec, IQRes);
+ {error, Error} -> exmpp_iq:error(IQ_Rec, Error)
end.
iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_pubsub"}]},
- {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]},
- {xmlelement, "DESC", [],
- [{xmlcdata,
+ [#xmlel{ns = ?NS_VCARD, name = 'FN', children = [#xmlcdata{cdata = <<"ejabberd/mod_pubsub">>}]},
+ #xmlel{ns = ?NS_VCARD, name = 'URL', children = [#xmlcdata{cdata = list_to_binary(?EJABBERD_URI)}]},
+ #xmlel{ns = ?NS_VCARD, name = 'DESC', children =
+ [#xmlcdata{cdata = list_to_binary(
translate:translate(Lang,
"ejabberd Publish-Subscribe module") ++
- "\nCopyright (c) 2004-2008 Process-One"}]}].
+ "\nCopyright (c) 2004-2008 Process-One")}]}].
iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang) ->
iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, all, plugins(ServerHost)).
iq_pubsub(Host, ServerHost, From, IQType, SubEl, _Lang, Access, Plugins) ->
- {xmlelement, _, _, SubEls} = SubEl,
- WithoutCdata = xml:remove_cdata(SubEls),
- Configuration = lists:filter(fun({xmlelement, Name, _, _}) ->
- Name == "configure"
+ WithoutCdata = exmpp_xml:remove_cdata_from_list(SubEl#xmlel.children),
+ Configuration = lists:filter(fun(#xmlel{name = 'configure'}) -> true;
+ (_) -> false
end, WithoutCdata),
Action = WithoutCdata -- Configuration,
case Action of
- [{xmlelement, Name, Attrs, Els}] ->
+ [#xmlel{name = Name, attrs = Attrs, children = Els}] ->
Node = case Host of
- {_, _, _} -> xml:get_attr_s("node", Attrs);
- _ -> string_to_node(xml:get_attr_s("node", Attrs))
+ {_, _, _} -> exmpp_xml:get_attribute_from_list(Attrs, 'node', false);
+ _ -> string_to_node(exmpp_xml:get_attribute_from_list(Attrs, 'node', false))
end,
case {IQType, Name} of
- {set, "create"} ->
+ {set, 'create'} ->
case Configuration of
- [{xmlelement, "configure", _, Config}] ->
+ [#xmlel{name = 'configure', children = Config}] ->
%% Get the type of the node
- Type = case xml:get_attr_s("type", Attrs) of
+ Type = case exmpp_xml:get_attribute_from_list(Attrs, 'type', "") of
[] -> hd(Plugins);
T -> T
end,
@@ -887,7 +885,7 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, _Lang, Access, Plugins) ->
case lists:member(Type, Plugins) of
false ->
{error, extended_error(
- ?ERR_FEATURE_NOT_IMPLEMENTED,
+ 'feature-not-implemented',
unsupported, "create-nodes")};
true ->
create_node(Host, ServerHost, Node, From,
@@ -898,139 +896,139 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, _Lang, Access, Plugins) ->
%% can not create node without
%% but this is the new spec anyway
?INFO_MSG("Node ~p ; invalid configuration: ~p", [Node, Configuration]),
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
- {set, "publish"} ->
- case xml:remove_cdata(Els) of
- [{xmlelement, "item", ItemAttrs, Payload}] ->
- ItemId = xml:get_attr_s("id", ItemAttrs),
+ {set, 'publish'} ->
+ case exmpp_xml:remove_cdata_from_list(Els) of
+ [#xmlel{name = 'item', attrs = ItemAttrs, children = Payload}] ->
+ ItemId = exmpp_xml:get_attribute_from_list(ItemAttrs, 'id', ""),
publish_item(Host, ServerHost, Node, From, ItemId, Payload);
[] ->
%% Publisher attempts to publish to persistent node with no item
- {error, extended_error(?ERR_BAD_REQUEST,
+ {error, extended_error('bad-request',
"item-required")};
_ ->
%% Entity attempts to publish item with multiple payload elements or namespace does not match
- {error, extended_error(?ERR_BAD_REQUEST,
+ {error, extended_error('bad-request',
"invalid-payload")}
end;
- {set, "retract"} ->
- ForceNotify = case xml:get_attr_s("notify", Attrs) of
+ {set, 'retract'} ->
+ ForceNotify = case exmpp_xml:get_attribute_from_list(Attrs, 'notify', "") of
"1" -> true;
"true" -> true;
_ -> false
end,
- case xml:remove_cdata(Els) of
- [{xmlelement, "item", ItemAttrs, _}] ->
- ItemId = xml:get_attr_s("id", ItemAttrs),
+ case exmpp_xml:remove_cdata_from_list(Els) of
+ [#xmlel{name = 'item', attrs = ItemAttrs}] ->
+ ItemId = exmpp_xml:get_attribute_from_list(ItemAttrs, 'id', ""),
delete_item(Host, Node, From, ItemId, ForceNotify);
_ ->
%% Request does not specify an item
- {error, extended_error(?ERR_BAD_REQUEST,
+ {error, extended_error('bad-request',
"item-required")}
end;
- {set, "subscribe"} ->
- JID = xml:get_attr_s("jid", Attrs),
+ {set, 'subscribe'} ->
+ JID = exmpp_xml:get_attribute_from_list(Attrs, 'jid', ""),
subscribe_node(Host, Node, From, JID);
- {set, "unsubscribe"} ->
- JID = xml:get_attr_s("jid", Attrs),
- SubId = xml:get_attr_s("subid", Attrs),
+ {set, 'unsubscribe'} ->
+ JID = exmpp_xml:get_attribute_from_list(Attrs, 'jid', ""),
+ SubId = exmpp_xml:get_attribute_from_list(Attrs, 'subid', ""),
unsubscribe_node(Host, Node, From, JID, SubId);
- {get, "items"} ->
- MaxItems = xml:get_attr_s("max_items", Attrs),
- SubId = xml:get_attr_s("subid", Attrs),
+ {get, 'items'} ->
+ MaxItems = exmpp_xml:get_attribute_from_list(Attrs, 'max_items', ""),
+ SubId = exmpp_xml:get_attribute_from_list(Attrs, 'subid', ""),
ItemIDs = lists:foldl(fun
- ({xmlelement, "item", ItemAttrs, _}, Acc) ->
- case xml:get_attr_s("id", ItemAttrs) of
+ (#xmlel{name = 'item', attrs = ItemAttrs}, Acc) ->
+ case exmpp_xml:get_attribute_from_list(ItemAttrs, 'id', "") of
"" -> Acc;
ItemID -> [ItemID|Acc]
end;
(_, Acc) ->
Acc
- end, [], xml:remove_cdata(Els)),
+ end, [], exmpp_xml:remove_cdata_from_list(Els)),
get_items(Host, Node, From, SubId, MaxItems, ItemIDs);
- {get, "subscriptions"} ->
+ {get, 'subscriptions'} ->
get_subscriptions(Host, From, Plugins);
- {get, "affiliations"} ->
+ {get, 'affiliations'} ->
get_affiliations(Host, From, Plugins);
_ ->
- {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
+ {error, 'feature-not-implemented'}
end;
_ ->
?INFO_MSG("Too many actions: ~p", [Action]),
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end.
iq_pubsub_owner(Host, From, IQType, SubEl, Lang) ->
- {xmlelement, _, _, SubEls} = SubEl,
- Action = xml:remove_cdata(SubEls),
+ SubEls = SubEl#xmlel.children,
+ Action = exmpp_xml:remove_cdata_from_list(SubEls),
case Action of
- [{xmlelement, Name, Attrs, Els}] ->
+ [#xmlel{name = Name, attrs = Attrs, children = Els}] ->
Node = case Host of
- {_, _, _} -> xml:get_attr_s("node", Attrs);
- _ -> string_to_node(xml:get_attr_s("node", Attrs))
+ {_, _, _} -> exmpp_xml:get_attribute_from_list(Attrs, 'node', "");
+ _ -> string_to_node(exmpp_xml:get_attribute_from_list(Attrs, 'node', ""))
end,
case {IQType, Name} of
- {get, "configure"} ->
+ {get, 'configure'} ->
get_configure(Host, Node, From, Lang);
- {set, "configure"} ->
+ {set, 'configure'} ->
set_configure(Host, Node, From, Els, Lang);
- {get, "default"} ->
+ {get, 'default'} ->
get_default(Host, Node, From, Lang);
- {set, "delete"} ->
+ {set, 'delete'} ->
delete_node(Host, Node, From);
- {set, "purge"} ->
+ {set, 'purge'} ->
purge_node(Host, Node, From);
- {get, "subscriptions"} ->
+ {get, 'subscriptions'} ->
get_subscriptions(Host, Node, From);
- {set, "subscriptions"} ->
- set_subscriptions(Host, Node, From, xml:remove_cdata(Els));
- {get, "affiliations"} ->
+ {set, 'subscriptions'} ->
+ set_subscriptions(Host, Node, From, exmpp_xml:remove_cdata_from_list(Els));
+ {get, 'affiliations'} ->
get_affiliations(Host, Node, From);
- {set, "affiliations"} ->
- set_affiliations(Host, Node, From, xml:remove_cdata(Els));
+ {set, 'affiliations'} ->
+ set_affiliations(Host, Node, From, exmpp_xml:remove_cdata_from_list(Els));
_ ->
- {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
+ {error, 'feature-not-implemented'}
end;
_ ->
?INFO_MSG("Too many actions: ~p", [Action]),
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end.
%%% authorization handling
send_authorization_request(Host, Node, Subscriber) ->
Lang = "en", %% TODO fix
- Stanza = {xmlelement, "message",
- [],
- [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "PubSub subscriber request")}]},
- {xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "Choose whether to approve this entity's subscription.")}]},
- {xmlelement, "field",
- [{"var", "FORM_TYPE"}, {"type", "hidden"}],
- [{xmlelement, "value", [], [{xmlcdata, ?NS_PUBSUB_SUB_AUTH}]}]},
- {xmlelement, "field",
- [{"var", "pubsub#node"}, {"type", "text-single"},
- {"label", translate:translate(Lang, "Node ID")}],
- [{xmlelement, "value", [],
- [{xmlcdata, node_to_string(Node)}]}]},
- {xmlelement, "field", [{"var", "pubsub#subscriber_jid"},
- {"type", "jid-single"},
- {"label", translate:translate(Lang, "Subscriber Address")}],
- [{xmlelement, "value", [],
- [{xmlcdata, jlib:jid_to_string(Subscriber)}]}]},
- {xmlelement, "field",
- [{"var", "pubsub#allow"},
- {"type", "boolean"},
- {"label", translate:translate(Lang, "Allow this JID to subscribe to this pubsub node?")}],
- [{xmlelement, "value", [], [{xmlcdata, "false"}]}]}]}]},
+ {U, S, R} = Subscriber,
+ Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs = [#xmlattr{name = 'type', value = "form"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "PubSub subscriber request"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "Choose whether to approve this entity's subscription."))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "FORM_TYPE"}, #xmlattr{name = 'type', value = "hidden"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(?NS_PUBSUB_SUBSCRIBE_AUTH_s)}]}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "pubsub#node"}, #xmlattr{name = 'type', value = "text-single"},
+ #xmlattr{name = 'label', value = translate:translate(Lang, "Node ID")}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =
+ [#xmlcdata{cdata = node_to_string(Node)}]}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'var', value = "pubsub#subscriber_jid"},
+ #xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = translate:translate(Lang, "Subscriber Address")}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =
+ [#xmlcdata{cdata = exmpp_jid:jid_to_binary(U, S, R)}]}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "pubsub#allow"},
+ #xmlattr{name = 'type', value = "boolean"},
+ #xmlattr{name = 'label', value = translate:translate(Lang, "Allow this JID to subscribe to this pubsub node?")}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"false">>}]}]}]}]},
case tree_action(Host, get_node, [Host, Node]) of
#pubsub_node{owners = Owners} ->
lists:foreach(
- fun(Owner) ->
- ejabberd_router ! {route, service_jid(Host), jlib:make_jid(Owner), Stanza}
+ fun({U1, S1, R1}) ->
+ ejabberd_router ! {route, service_jid(Host), exmpp_jid:make_jid(U1, S1, R1), Stanza}
end, Owners),
ok;
_ ->
@@ -1038,29 +1036,24 @@ send_authorization_request(Host, Node, Subscriber) ->
end.
find_authorization_response(Packet) ->
- {xmlelement, _Name, _Attrs, Els} = Packet,
- XData1 = lists:map(fun({xmlelement, "x", XAttrs, _} = XEl) ->
- case xml:get_attr_s("xmlns", XAttrs) of
- ?NS_XDATA ->
- case xml:get_attr_s("type", XAttrs) of
- "cancel" ->
- none;
- _ ->
- jlib:parse_xdata_submit(XEl)
- end;
+ Els = Packet#xmlel.children,
+ XData1 = lists:map(fun(#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs = XAttrs} = XEl) ->
+ case exmpp_xml:get_attribute_from_list(XAttrs, 'type', "") of
+ "cancel" ->
+ none;
_ ->
- none
+ jlib:parse_xdata_submit(XEl)
end;
(_) ->
none
- end, xml:remove_cdata(Els)),
+ end, exmpp_xml:remove_cdata(Els)),
XData = lists:filter(fun(E) -> E /= none end, XData1),
case XData of
[invalid] -> invalid;
[] -> none;
[XFields] when is_list(XFields) ->
case lists:keysearch("FORM_TYPE", 1, XFields) of
- {value, {_, ?NS_PUBSUB_SUB_AUTH}} ->
+ {value, {_, ?NS_PUBSUB_SUBSCRIBE_AUTH_s}} ->
XFields;
_ ->
invalid
@@ -1077,7 +1070,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
{_, _, _} -> [SNode];
_ -> string:tokens(SNode, "/")
end,
- Subscriber = jlib:string_to_jid(SSubscriber),
+ Subscriber = exmpp_jid:list_to_jid(SSubscriber),
Allow = case SAllow of
"1" -> true;
"true" -> true;
@@ -1086,13 +1079,13 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
Action = fun(#pubsub_node{type = Type,
%%options = Options,
owners = Owners}) ->
- IsApprover = lists:member(jlib:jid_tolower(jlib:jid_remove_resource(From)), Owners),
+ IsApprover = lists:member(jlib:short_prepd_bare_jid(From), Owners),
Subscription = node_call(Type, get_subscription, [Host, Node, Subscriber]),
if
not IsApprover ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
Subscription /= pending ->
- {error, ?ERR_UNEXPECTED_REQUEST};
+ {error, 'unexpected-request'};
true ->
NewSubscription = case Allow of
true -> subscribed;
@@ -1105,26 +1098,26 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
{error, Error} ->
ejabberd_router:route(
To, From,
- jlib:make_error_reply(Packet, Error));
+ exmpp_stanza:reply_with_error(Packet, Error));
{result, _NewSubscription} ->
%% XXX: notify about subscription state change, section 12.11
ok;
_ ->
ejabberd_router:route(
To, From,
- jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR))
+ exmpp_stanza:reply_with_error(Packet, 'internal-server-error'))
end;
_ ->
ejabberd_router:route(
To, From,
- jlib:make_error_reply(Packet, ?ERR_NOT_ACCEPTABLE))
+ exmpp_stanza:reply_with_error(Packet, 'not-acceptable'))
end.
-define(XFIELD(Type, Label, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'label', value = translate:translate(Lang, Label)},
+ #xmlattr{name = 'var', value = Var}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Val)}]}]}).
-define(BOOLXFIELD(Label, Var, Val),
?XFIELD("boolean", Label, Var,
@@ -1137,15 +1130,15 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
?XFIELD("text-single", Label, Var, Val)).
-define(XFIELDOPT(Type, Label, Var, Val, Opts),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}],
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'label', value = translate:translate(Lang, Label)},
+ #xmlattr{name = 'var', value = Var}], children =
lists:map(fun(Opt) ->
- {xmlelement, "option", [],
- [{xmlelement, "value", [],
- [{xmlcdata, Opt}]}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =
+ [#xmlcdata{cdata = list_to_binary(Opt)}]}]}
end, Opts) ++
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Val)}]}]}).
-define(LISTXFIELD(Label, Var, Val, Opts),
?XFIELDOPT("list-single", Label, Var, Val, Opts)).
@@ -1176,7 +1169,7 @@ create_node(Host, ServerHost, Node, Owner, Type) ->
create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
case lists:member("instant-nodes", features(Type)) of
true ->
- {LOU, LOS, _} = jlib:jid_tolower(Owner),
+ {LOU, LOS, _} = jlib:short_prepd_jid(Owner),
HomeNode = ["home", LOS, LOU],
create_node(Host, ServerHost,
HomeNode, Owner, Type, Access, Configuration),
@@ -1185,25 +1178,25 @@ create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
NewNode, Owner, Type, Access, Configuration) of
{result, []} ->
{result,
- [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "create", [{"node", node_to_string(NewNode)}], []}]}]};
+ [#xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB, name = 'create', attrs = [#xmlattr{name = 'node', value = node_to_string(NewNode)}]}]}]};
Error -> Error
end;
false ->
%% Service does not support instant nodes
- {error, extended_error(?ERR_NOT_ACCEPTABLE, "nodeid-required")}
+ {error, extended_error('not-acceptable', "nodeid-required")}
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
+ ParseOptions = case exmpp_xml:remove_cdata_from_list(Configuration) of
[] ->
{result, node_options(Type)};
- [{xmlelement, "x", _Attrs, _SubEls} = XEl] ->
+ [#xmlel{name = 'x'} = XEl] ->
case jlib:parse_xdata_submit(XEl) of
invalid ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
XData ->
case set_xoption(XData, node_options(Type)) of
NewOpts when is_list(NewOpts) ->
@@ -1214,7 +1207,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
end;
_ ->
?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]),
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end,
case ParseOptions of
{result, NodeOptions} ->
@@ -1225,21 +1218,20 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
case tree_call(Host, create_node, [Host, Node, Type, Owner, NodeOptions]) of
ok ->
node_call(Type, create_node, [Host, Node, Owner]);
- {error, ?ERR_CONFLICT} ->
+ {error, 'conflict'} ->
case ets:lookup(gen_mod:get_module_proc(ServerHost, pubsub_state), nodetree) of
[{nodetree, nodetree_virtual}] -> node_call(Type, create_node, [Host, Node, Owner]);
- _ -> {error, ?ERR_CONFLICT}
+ _ -> {error, 'conflict'}
end;
Error ->
Error
end;
_ ->
- {error, ?ERR_FORBIDDEN}
+ {error, 'forbidden'}
end
end,
- Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "create", [{"node", node_to_string(Node)}],
- []}]}],
+ Reply = [#xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB, name = 'create', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}]}]}],
case transaction(CreateNode, transaction) of
{error, Error} ->
%% in case we change transaction to sync_dirty...
@@ -1251,7 +1243,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
%%Lang = "en", %% TODO: fix
%%OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
%%broadcast_publish_item(Host, Node, uniqid(), Owner,
- %% [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}],
+ %% [{xmlelement, "x", [{"xmlns", ?NS_DATA_FORMS}, {"type", "result"}],
%% [?XFIELD("hidden", "", "FORM_TYPE", ?NS_PUBSUB_NMI),
%% ?XFIELD("jid-single", "Node Creator", "creator", jlib:jid_to_string(OwnerKey))]}]),
%% todo publish_item(Host, ServerHost, ["pubsub", "nodes"], node_to_string(Node)),
@@ -1283,7 +1275,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
%%
delete_node(_Host, [], _Owner) ->
%% Node is the root
- {error, ?ERR_NOT_ALLOWED};
+ {error, 'not-allowed'};
delete_node(Host, Node, Owner) ->
Action = fun(#pubsub_node{type = Type}) ->
case node_call(Type, get_affiliation, [Host, Node, Owner]) of
@@ -1292,7 +1284,7 @@ delete_node(Host, Node, Owner) ->
node_call(Type, delete_node, [Host, Removed]);
_ ->
%% Entity is not an owner
- {error, ?ERR_FORBIDDEN}
+ {error, 'forbidden'}
end
end,
Reply = [],
@@ -1341,10 +1333,12 @@ delete_node(Host, Node, Owner) ->
%%The node does not exist.
%%
subscribe_node(Host, Node, From, JID) ->
- Subscriber = case jlib:string_to_jid(JID) of
- error -> {"", "", ""};
- J -> jlib:jid_tolower(J)
- end,
+ Subscriber = try
+ jlib:short_prepd_jid(exmpp_jid:list_to_jid(JID))
+ catch
+ _:_ ->
+ {undefined, undefined, undefined}
+ end,
SubId = uniqid(),
Action = fun(#pubsub_node{options = Options, type = Type}) ->
Features = features(Type),
@@ -1364,10 +1358,10 @@ subscribe_node(Host, Node, From, JID) ->
if
not SubscribeFeature ->
%% Node does not support subscriptions
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscribe")};
+ {error, extended_error('feature-not-implemented', unsupported, "subscribe")};
not SubscribeConfig ->
%% Node does not support subscriptions
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscribe")};
+ {error, extended_error('feature-not-implemented', unsupported, "subscribe")};
true ->
node_call(Type, subscribe_node,
[Host, Node, From, Subscriber,
@@ -1378,15 +1372,15 @@ subscribe_node(Host, Node, From, JID) ->
Reply = fun(Subscription) ->
%% TODO, this is subscription-notification, should depends on node features
Fields =
- [{"node", node_to_string(Node)},
- {"jid", jlib:jid_to_string(Subscriber)},
- {"subscription", subscription_to_string(Subscription)}],
- [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "subscription",
+ [#xmlattr{name = 'node', value = node_to_string(Node)},
+ #xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(Subscriber)},
+ #xmlattr{name = 'subscription', value = subscription_to_string(Subscription)}],
+ [#xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB, name = 'subscription', attrs =
case Subscription of
- subscribed -> [{"subid", SubId}|Fields];
+ subscribed -> [#xmlattr{name = 'subid', value = SubId}|Fields];
_ -> Fields
- end, []}]}]
+ end}]}]
end,
case transaction(Host, Node, Action, sync_dirty) of
{error, Error} ->
@@ -1428,10 +1422,12 @@ subscribe_node(Host, Node, From, JID) ->
%%The request specifies a subscription ID that is not valid or current.
%%
unsubscribe_node(Host, Node, From, JID, SubId) ->
- Subscriber = case jlib:string_to_jid(JID) of
- error -> {"", "", ""};
- J -> jlib:jid_tolower(J)
- end,
+ Subscriber = try
+ jlib:short_prepd_jid(exmpp_jid:list_to_jid(JID))
+ catch
+ _:_ ->
+ {undefined, undefined, undefined}
+ end,
case node_action(Host, Node, unsubscribe_node,
[Host, Node, From, Subscriber, SubId]) of
{error, Error} ->
@@ -1470,21 +1466,21 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
if
not PublishFeature ->
%% Node does not support item publication
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "publish")};
+ {error, extended_error('feature-not-implemented', unsupported, "publish")};
PayloadSize > PayloadMaxSize ->
%% Entity attempts to publish very large payload
- {error, extended_error(?ERR_NOT_ACCEPTABLE, "payload-too-big")};
+ {error, extended_error('not-acceptable', "payload-too-big")};
%%?? -> iq_pubsub just does that matchs
%% % Entity attempts to publish item with multiple payload elements or namespace does not match
- %% {error, extended_error(?ERR_BAD_REQUEST, "invalid-payload")};
+ %% {error, extended_error('bad-request', "invalid-payload")};
%% % Publisher attempts to publish to persistent node with no item
- %% {error, extended_error(?ERR_BAD_REQUEST, "item-required")};
+ %% {error, extended_error('bad-request', "item-required")};
Payload == "" ->
%% Publisher attempts to publish to payload node with no payload
- {error, extended_error(?ERR_BAD_REQUEST, "payload-required")};
+ {error, extended_error('bad-request', "payload-required")};
%%?? ->
%% % Publisher attempts to publish to transient notification node with item
- %% {error, extended_error(?ERR_BAD_REQUEST, "item-forbidden")};
+ %% {error, extended_error('bad-request', "item-forbidden")};
true ->
node_call(Type, publish_item, [Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload])
end
@@ -1492,7 +1488,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
ejabberd_hooks:run(pubsub_publish_item, ServerHost, [ServerHost, Node, Publisher, service_jid(Host), ItemId, Payload]),
Reply = [],
case transaction(Host, Node, Action, sync_dirty) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
%% handles auto-create feature
%% for automatic node creation. we'll take the default node type:
%% first listed into the plugins configuration option, or pep
@@ -1503,10 +1499,10 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
{result, _} ->
publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload);
_ ->
- {error, ?ERR_ITEM_NOT_FOUND}
+ {error, 'item-not-found'}
end;
false ->
- {error, ?ERR_ITEM_NOT_FOUND}
+ {error, 'item-not-found'}
end;
{error, Reason} ->
{error, Reason};
@@ -1514,7 +1510,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
lists:foreach(fun(OldItem) ->
broadcast_retract_item(Host, Node, OldItem)
end, Removed),
- broadcast_publish_item(Host, Node, ItemId, jlib:jid_tolower(Publisher), Payload),
+ broadcast_publish_item(Host, Node, ItemId, jlib:short_prepd_jid(Publisher), Payload),
case Result of
default -> {result, Reply};
_ -> {result, Result}
@@ -1553,7 +1549,7 @@ delete_item(Host, Node, Publisher, ItemId) ->
delete_item(Host, Node, Publisher, ItemId, false).
delete_item(_, "", _, _, _) ->
%% Request does not specify a node
- {error, extended_error(?ERR_BAD_REQUEST, "node-required")};
+ {error, extended_error('bad-request', "node-required")};
delete_item(Host, Node, Publisher, ItemId, ForceNotify) ->
Action = fun(#pubsub_node{type = Type}) ->
Features = features(Type),
@@ -1562,13 +1558,13 @@ delete_item(Host, Node, Publisher, ItemId, ForceNotify) ->
if
%%?? -> iq_pubsub just does that matchs
%% %% Request does not specify an item
- %% {error, extended_error(?ERR_BAD_REQUEST, "item-required")};
+ %% {error, extended_error('bad-request', "item-required")};
not PersistentFeature ->
%% Node does not support persistent items
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")};
+ {error, extended_error('feature-not-implemented', unsupported, "persistent-items")};
not DeleteFeature ->
%% Service does not support item deletion
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "delete-nodes")};
+ {error, extended_error('feature-not-implemented', unsupported, "delete-nodes")};
true ->
node_call(Type, delete_item, [Host, Node, Publisher, ItemId])
end
@@ -1612,13 +1608,13 @@ purge_node(Host, Node, Owner) ->
if
not PurgeFeature ->
%% Service does not support node purging
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "purge-nodes")};
+ {error, extended_error('feature-not-implemented', unsupported, "purge-nodes")};
not PersistentFeature ->
%% Node does not support persistent items
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")};
+ {error, extended_error('feature-not-implemented', unsupported, "persistent-items")};
not PersistentConfig ->
%% Node is not configured for persistent items
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")};
+ {error, extended_error('feature-not-implemented', unsupported, "persistent-items")};
true ->
node_call(Type, purge_node, [Host, Node, Owner])
end
@@ -1650,7 +1646,7 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
SMaxItems == "" -> ?MAXITEMS;
true ->
case catch list_to_integer(SMaxItems) of
- {'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
+ {'EXIT', _} -> {error, 'bad-request'};
Val -> Val
end
end,
@@ -1668,17 +1664,17 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
case Host of
{OUser, OServer, _} ->
get_roster_info(OUser, OServer,
- jlib:jid_tolower(From), AllowedGroups);
+ jlib:short_prepd_jid(From), AllowedGroups);
_ ->
{true, true}
end,
if
not RetreiveFeature ->
%% Item Retrieval Not Supported
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-items")};
+ {error, extended_error('feature-not-implemented', unsupported, "retrieve-items")};
not PersistentFeature ->
%% Persistent Items Not Supported
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")};
+ {error, extended_error('feature-not-implemented', unsupported, "persistent-items")};
true ->
node_call(Type, get_items,
[Host, Node, From,
@@ -1705,12 +1701,12 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
payload = Payload}) ->
ItemAttrs = case ItemId of
"" -> [];
- _ -> [{"id", ItemId}]
+ _ -> [#xmlattr{name = 'id', value = ItemId}]
end,
- {xmlelement, "item", ItemAttrs, Payload}
+ #xmlel{ns = ?NS_PUBSUB, name = 'item', attrs = ItemAttrs, children = Payload}
end, lists:sublist(SendItems, MaxItems)),
- {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "items", [{"node", node_to_string(Node)}],
+ {result, [#xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB, name = 'items', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
ItemsEls}]}]}
end
end.
@@ -1733,7 +1729,7 @@ send_last_item(Host, Node, LJID) ->
send_items(Host, Node, LJID, last).
%% TODO use cache-last-item feature
-send_items(Host, Node, LJID, Number) ->
+send_items(Host, Node, {LU, LS, LR} = LJID, Number) ->
ToSend = case get_items(Host, Node, LJID) of
[] ->
[];
@@ -1749,15 +1745,15 @@ send_items(Host, Node, LJID, Number) ->
fun(#pubsub_item{itemid = {ItemId, _}, payload = Payload}) ->
ItemAttrs = case ItemId of
"" -> [];
- _ -> [{"id", ItemId}]
+ _ -> [#xmlattr{name = 'id', value = ItemId}]
end,
- {xmlelement, "item", ItemAttrs, Payload}
+ #xmlel{ns = ?NS_PUBSUB_EVENT, name = 'item', attrs = ItemAttrs, children = Payload}
end, ToSend),
- Stanza = {xmlelement, "message", [],
- [{xmlelement, "event", [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items", [{"node", node_to_string(Node)}],
+ Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'event', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
ItemsEls}]}]},
- ejabberd_router ! {route, service_jid(Host), jlib:make_jid(LJID), Stanza}.
+ ejabberd_router ! {route, service_jid(Host), exmpp_jid:make_jid(LU, LS, LR), Stanza}.
%% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response}
%% Host = host()
@@ -1774,7 +1770,7 @@ get_affiliations(Host, JID, Plugins) when is_list(Plugins) ->
if
not RetrieveFeature ->
%% Service does not support retreive affiliatons
- {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-affiliations")}, Acc};
+ {{error, extended_error('feature-not-implemented', unsupported, "retrieve-affiliations")}, Acc};
true ->
{result, Affiliations} = node_action(Type, get_entity_affiliations, [Host, JID]),
{Status, [Affiliations|Acc]}
@@ -1785,13 +1781,12 @@ get_affiliations(Host, JID, Plugins) when is_list(Plugins) ->
Entities = lists:flatmap(
fun({_, none}) -> [];
({Node, Affiliation}) ->
- [{xmlelement, "affiliation",
- [{"node", node_to_string(Node)},
- {"affiliation", affiliation_to_string(Affiliation)}],
- []}]
+ [#xmlel{ns = ?NS_PUBSUB, name = 'affiliation', attrs =
+ [#xmlattr{name = 'node', value = node_to_string(Node)},
+ #xmlattr{name = 'affiliation', value = affiliation_to_string(Affiliation)}]}]
end, lists:usort(lists:flatten(Affiliations))),
- {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "affiliations", [],
+ {result, [#xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB, name = 'affiliations', children =
Entities}]}]};
{Error, _} ->
Error
@@ -1804,10 +1799,10 @@ get_affiliations(Host, Node, JID) ->
if
not RetrieveFeature ->
%% Service does not support modify affiliations
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "modify-affiliations")};
+ {error, extended_error('feature-not-implemented', unsupported, "modify-affiliations")};
Affiliation /= {result, owner} ->
%% Entity is not an owner
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
true ->
node_call(Type, get_node_affiliations, [Host, Node])
end
@@ -1816,23 +1811,22 @@ get_affiliations(Host, Node, JID) ->
{error, Reason} ->
{error, Reason};
{result, []} ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
{result, Affiliations} ->
Entities = lists:flatmap(
fun({_, none}) -> [];
- ({AJID, Affiliation}) ->
- [{xmlelement, "affiliation",
- [{"jid", jlib:jid_to_string(AJID)},
- {"affiliation", affiliation_to_string(Affiliation)}],
- []}]
+ ({{AU, AS, AR}, Affiliation}) ->
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'affiliation', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(AU, AS, AR)},
+ #xmlattr{name = 'affiliation', value = affiliation_to_string(Affiliation)}]}]
end, Affiliations),
- {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}],
- [{xmlelement, "affiliations", [{"node", node_to_string(Node)}],
+ {result, [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'affiliations', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
Entities}]}]}
end.
set_affiliations(Host, Node, From, EntitiesEls) ->
- Owner = jlib:jid_tolower(jlib:jid_remove_resource(From)),
+ Owner = jlib:short_prepd_bare_jid(From),
Entities =
lists:foldl(
fun(El, Acc) ->
@@ -1841,24 +1835,28 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
error;
_ ->
case El of
- {xmlelement, "affiliation", Attrs, _} ->
- JID = jlib:string_to_jid(
- xml:get_attr_s("jid", Attrs)),
+ #xmlel{name = 'affiliation', attrs = Attrs} ->
+ JID = try
+ exmpp_jid:list_to_jid(
+ exmpp_xml:get_attribute_from_list(Attrs, 'jid', ""))
+ catch
+ _:_ -> error
+ end,
Affiliation = string_to_affiliation(
- xml:get_attr_s("affiliation", Attrs)),
+ exmpp_xml:get_attribute_from_list(Attrs, 'affiliation', false)),
if
(JID == error) or
(Affiliation == false) ->
error;
true ->
- [{jlib:jid_tolower(JID), Affiliation} | Acc]
+ [{jlib:short_prepd_jid(JID), Affiliation} | Acc]
end
end
end
end, [], EntitiesEls),
case Entities of
error ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
_ ->
Action = fun(#pubsub_node{type = Type, owners = Owners}) ->
case lists:member(Owner, Owners) of
@@ -1871,7 +1869,7 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
end, Entities),
{result, []};
_ ->
- {error, ?ERR_FORBIDDEN}
+ {error, 'forbidden'}
end
end,
transaction(Host, Node, Action, sync_dirty)
@@ -1893,7 +1891,7 @@ get_subscriptions(Host, JID, Plugins) when is_list(Plugins) ->
if
not RetrieveFeature ->
%% Service does not support retreive subscriptions
- {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-subscriptions")}, Acc};
+ {{error, extended_error('feature-not-implemented', unsupported, "retrieve-subscriptions")}, Acc};
true ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, JID]),
{Status, [Subscriptions|Acc]}
@@ -1904,20 +1902,18 @@ get_subscriptions(Host, JID, Plugins) when is_list(Plugins) ->
Entities = lists:flatmap(
fun({_, none}) -> [];
({Node, Subscription}) ->
- [{xmlelement, "subscription",
- [{"node", node_to_string(Node)},
- {"subscription", subscription_to_string(Subscription)}],
- []}];
+ [#xmlel{ns = ?NS_PUBSUB, name = 'subscription', attrs =
+ [#xmlattr{name = 'node', value = node_to_string(Node)},
+ #xmlattr{name = 'subscription', value = subscription_to_string(Subscription)}]}];
({_, none, _}) -> [];
({Node, Subscription, SubJID}) ->
- [{xmlelement, "subscription",
- [{"node", node_to_string(Node)},
- {"jid", jlib:jid_to_string(SubJID)},
- {"subscription", subscription_to_string(Subscription)}],
- []}]
+ [#xmlel{ns = ?NS_PUBSUB, name = 'subscription', attrs =
+ [#xmlattr{name = 'node', value = node_to_string(Node)},
+ #xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(SubJID)},
+ #xmlattr{name = 'subscription', value = subscription_to_string(Subscription)}]}]
end, lists:usort(lists:flatten(Subscriptions))),
- {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "subscriptions", [],
+ {result, [#xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB, name = 'subscriptions', children =
Entities}]}]};
{Error, _} ->
Error
@@ -1930,10 +1926,10 @@ get_subscriptions(Host, Node, JID) ->
if
not RetrieveFeature ->
%% Service does not support manage subscriptions
- {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "manage-affiliations")};
+ {error, extended_error('feature-not-implemented', unsupported, "manage-affiliations")};
Affiliation /= {result, owner} ->
%% Entity is not an owner
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
true ->
node_call(Type, get_node_subscriptions, [Host, Node])
end
@@ -1942,29 +1938,27 @@ get_subscriptions(Host, Node, JID) ->
{error, Reason} ->
{error, Reason};
{result, []} ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
{result, Subscriptions} ->
Entities = lists:flatmap(
fun({_, none}) -> [];
- ({AJID, Subscription}) ->
- [{xmlelement, "subscription",
- [{"jid", jlib:jid_to_string(AJID)},
- {"subscription", subscription_to_string(Subscription)}],
- []}];
- ({AJID, Subscription, SubId}) ->
- [{xmlelement, "subscription",
- [{"jid", jlib:jid_to_string(AJID)},
- {"subscription", subscription_to_string(Subscription)},
- {"subid", SubId}],
- []}]
+ ({{AU, AS, AR}, Subscription}) ->
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'subscription', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(AU, AS, AR)},
+ #xmlattr{name = 'subscription', value = subscription_to_string(Subscription)}]}];
+ ({{AU, AS, AR}, Subscription, SubId}) ->
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'subscription', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(AU, AS, AR)},
+ #xmlattr{name = 'subscription', value = subscription_to_string(Subscription)},
+ #xmlattr{name = 'subid', value =SubId}]}]
end, Subscriptions),
- {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}],
- [{xmlelement, "subscriptions", [{"node", node_to_string(Node)}],
+ {result, [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'subscriptions', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
Entities}]}]}
end.
set_subscriptions(Host, Node, From, EntitiesEls) ->
- Owner = jlib:jid_tolower(jlib:jid_remove_resource(From)),
+ Owner = jlib:short_prepd_bare_jid(From),
Entities =
lists:foldl(
fun(El, Acc) ->
@@ -1973,24 +1967,29 @@ set_subscriptions(Host, Node, From, EntitiesEls) ->
error;
_ ->
case El of
- {xmlelement, "subscription", Attrs, _} ->
- JID = jlib:string_to_jid(
- xml:get_attr_s("jid", Attrs)),
+ #xmlel{name = 'subscription', attrs = Attrs} ->
+ JID = try
+ exmpp_jid:list_to_jid(
+ exmpp_xml:get_attribute_from_list(Attrs, 'jid', ""))
+ catch
+ _:_ ->
+ error
+ end,
Subscription = string_to_subscription(
- xml:get_attr_s("subscription", Attrs)),
+ exmpp_xml:get_attribute_from_list(Attrs, 'subscription', false)),
if
(JID == error) or
(Subscription == false) ->
error;
true ->
- [{jlib:jid_tolower(JID), Subscription} | Acc]
+ [{jlib:short_prepd_jid(JID), Subscription} | Acc]
end
end
end
end, [], EntitiesEls),
case Entities of
error ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
_ ->
Action = fun(#pubsub_node{type = Type, owners = Owners}) ->
case lists:member(Owner, Owners) of
@@ -2000,7 +1999,7 @@ set_subscriptions(Host, Node, From, EntitiesEls) ->
end, Entities),
{result, []};
_ ->
- {error, ?ERR_FORBIDDEN}
+ {error, 'forbidden'}
end
end,
transaction(Host, Node, Action, sync_dirty)
@@ -2014,7 +2013,7 @@ get_roster_info(OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, _}, A
ejabberd_hooks:run_fold(
roster_get_jid_info, OwnerServer,
{none, []},
- [OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, ""}]),
+ [OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, undefined}]),
PresenceSubscription = (Subscription == both) orelse (Subscription == from)
orelse ({OwnerUser, OwnerServer} == {SubscriberUser, SubscriberServer}),
RosterGroup = lists:any(fun(Group) ->
@@ -2078,8 +2077,8 @@ string_to_node(SNode) ->
%% @doc Generate pubsub service JID.
service_jid(Host) ->
case Host of
- {U,S,_} -> {jid, U, S, "", U, S, ""};
- _ -> {jid, "", Host, "", "", Host, ""}
+ {U,S,_} -> #jid{node = U, domain = S, lnode = U, ldomain = S};
+ _ -> #jid{domain = Host, ldomain = Host}
end.
%% @spec (LJID, Subscription, PresenceDelivery) -> boolean()
@@ -2116,7 +2115,7 @@ broadcast_publish_item(Host, Node, ItemId, _From, Payload) ->
end,
ItemAttrs = case ItemId of
"" -> [];
- _ -> [{"id", ItemId}]
+ _ -> [#xmlattr{name = 'id', value = ItemId}]
end,
Stanza = make_stanza(Node, ItemAttrs, Content),
lists:foreach(
@@ -2142,17 +2141,16 @@ broadcast_publish_item(Host, Node, ItemId, _From, Payload) ->
%% ItemAttrs is a list of tuples:
%% For example: [{"id", ItemId}]
make_stanza(Node, ItemAttrs, Payload) ->
- {xmlelement, "message", [],
- [{xmlelement, "event",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items", [{"node", node_to_string(Node)}],
- [{xmlelement, "item", ItemAttrs, Payload}]}]}]}.
+ #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'event', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'item', attrs = ItemAttrs, children = Payload}]}]}]}.
%% DestJIDs = [{LUser, LServer, LResource}]
route_stanza(Host, DestJIDs, Stanza) ->
lists:foreach(
- fun(DestJID) ->
- ejabberd_router ! {route, service_jid(Host), jlib:make_jid(DestJID), Stanza}
+ fun({DU, DS, DR}) ->
+ ejabberd_router ! {route, service_jid(Host), exmpp_jid:make_jid(DU, DS, DR), Stanza}
end, DestJIDs).
broadcast_retract_item(Host, Node, ItemId) ->
@@ -2170,21 +2168,20 @@ broadcast_retract_item(Host, Node, ItemId, ForceNotify) ->
end,
ItemAttrs = case ItemId of
"" -> [];
- _ -> [{"id", ItemId}]
+ _ -> [#xmlattr{name = 'id', value = ItemId}]
end,
- Stanza = {xmlelement, "message", [],
- [{xmlelement, "event",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items", [{"node", node_to_string(Node)}],
- [{xmlelement, "retract", ItemAttrs, []}]}]}]},
+ Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'event', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'retract', attrs = ItemAttrs}]}]}]},
case Notify of
true ->
lists:foreach(
- fun(#pubsub_state{stateid = {JID, _},
+ fun(#pubsub_state{stateid = {{U, S, R}, _},
subscription = Subscription}) ->
if (Subscription /= none) and
(Subscription /= pending) ->
- ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza};
+ ejabberd_router ! {route, service_jid(Host), exmpp_jid:make_jid(U, S, R), Stanza};
true ->
ok
end
@@ -2205,19 +2202,17 @@ broadcast_purge_node(Host, Node) ->
{error, _} -> {result, false};
{result, []} -> {result, false};
{result, States} ->
- Stanza = {xmlelement, "message", [],
- [{xmlelement, "event",
- [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "purge", [{"node", node_to_string(Node)}],
- []}]}]},
+ Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'event', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'purge', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}]}]}]},
case get_option(Options, notify_retract) of
true ->
lists:foreach(
- fun(#pubsub_state{stateid = {JID,_},
+ fun(#pubsub_state{stateid = {{U, S, R},_},
subscription = Subscription}) ->
if (Subscription /= none) and
(Subscription /= pending) ->
- ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza};
+ ejabberd_router ! {route, service_jid(Host), exmpp_jid:make_jid(U, S, R), Stanza};
true ->
ok
end
@@ -2236,20 +2231,19 @@ broadcast_removed_node(Host, Removed) ->
fun(Node) ->
Action =
fun(#pubsub_node{options = Options, type = Type}) ->
- Stanza = {xmlelement, "message", [],
- [{xmlelement, "event", [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "delete", [{"node", node_to_string(Node)}],
- []}]}]},
+ Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'event', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'delete', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}]}]}]},
case get_option(Options, notify_delete) of
true ->
case node_call(Type, get_states, [Host, Node]) of
{result, States} ->
lists:foreach(
- fun(#pubsub_state{stateid = {JID, _},
+ fun(#pubsub_state{stateid = {{U, S, R}, _},
subscription = Subscription}) ->
if (Subscription /= none) and
(Subscription /= pending) ->
- ejabberd_router ! {route, service_jid(Host), jlib:make_jid(JID), Stanza};
+ ejabberd_router ! {route, service_jid(Host), jlib:make_jid(U, S, R), Stanza};
true ->
ok
end
@@ -2278,22 +2272,22 @@ broadcast_config_notification(Host, Node, Lang) ->
PresenceDelivery = get_option(Options, presence_based_delivery),
Content = case get_option(Options, deliver_payloads) of
true ->
- [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs = [#xmlattr{name = 'type', value = "form"}], children =
get_configure_xfields(Type, Options, Lang, Owners)}];
false ->
[]
end,
- Stanza = {xmlelement, "message", [],
- [{xmlelement, "event", [{"xmlns", ?NS_PUBSUB_EVENT}],
- [{xmlelement, "items", [{"node", node_to_string(Node)}],
- [{xmlelement, "item", [{"id", "configuration"}],
+ Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'event', children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
+ [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'item', attrs = [#xmlattr{name = 'id', value = "configuration"}], children =
Content}]}]}]},
lists:foreach(
- fun(#pubsub_state{stateid = {LJID, _},
+ fun(#pubsub_state{stateid = {{U, S, R} = LJID, _},
subscription = Subscription}) ->
case is_to_delivered(LJID, Subscription, PresenceDelivery) of
true ->
- ejabberd_router ! {route, service_jid(Host), jlib:make_jid(LJID), Stanza};
+ ejabberd_router ! {route, service_jid(Host), exmpp_jid:make_jid(U, S, R), Stanza};
false ->
ok
end
@@ -2333,19 +2327,19 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
?DEBUG("looking for pid of ~p@~p/~p", [LUser, LServer, LResource]),
%% We need to know the resource, so we can ask for presence data.
SenderResource = case LResource of
- "" ->
+ undefined ->
%% If we don't know the resource, just pick one.
case ejabberd_sm:get_user_resources(LUser, LServer) of
[R|_] ->
R;
[] ->
- ""
+ undefined
end;
_ ->
LResource
end,
case SenderResource of
- "" ->
+ undefined ->
?DEBUG("~p@~p is offline; can't deliver ~p to contacts", [LUser, LServer, Stanza]),
ok;
_ ->
@@ -2354,16 +2348,16 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
%% set the from address on the notification to the bare JID of the account owner
%% Also, add "replyto" if entity has presence subscription to the account owner
%% See XEP-0163 1.1 section 4.3.1
- Sender = jlib:make_jid(LUser, LServer, ""),
+ Sender = exmpp_jid:make_jid(LUser, LServer),
%%ReplyTo = jlib:make_jid(LUser, LServer, SenderResource), % This has to be used
case catch ejabberd_c2s:get_subscribed_and_online(C2SPid) of
ContactsWithCaps when is_list(ContactsWithCaps) ->
?DEBUG("found contacts with caps: ~p", [ContactsWithCaps]),
lists:foreach(
- fun({JID, Caps}) ->
+ fun({{U1, S1, R1}, Caps}) ->
case is_caps_notify(LServer, Node, Caps) of
true ->
- To = jlib:make_jid(JID),
+ To = exmpp_jid:make_jid(U1, S1, R1),
ejabberd_router ! {route, Sender, To, Stanza};
false ->
ok
@@ -2400,16 +2394,15 @@ get_configure(Host, Node, From, Lang) ->
case node_call(Type, get_affiliation, [Host, Node, From]) of
{result, owner} ->
{result,
- [{xmlelement, "pubsub",
- [{"xmlns", ?NS_PUBSUB_OWNER}],
- [{xmlelement, "configure",
- [{"node", node_to_string(Node)}],
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA}, {"type", "form"}],
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'configure', attrs =
+ [#xmlattr{name = 'node', value = node_to_string(Node)}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs =
+ [#xmlattr{name = 'type', value = "form"}], children =
get_configure_xfields(Type, Options, Lang, Owners)
}]}]}]};
_ ->
- {error, ?ERR_FORBIDDEN}
+ {error, 'forbidden'}
end
end,
transaction(Host, Node, Action, sync_dirty).
@@ -2417,9 +2410,9 @@ get_configure(Host, Node, From, Lang) ->
get_default(Host, Node, _From, Lang) ->
Type=select_type(Host, Host, Node),
Options = node_options(Type),
- {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}],
- [{xmlelement, "default", [],
- [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
+ {result, [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'pubsub', children =
+ [#xmlel{ns = ?NS_PUBSUB_OWNER, name = 'default', children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs = [#xmlattr{name = 'type', value = "form"}], children =
get_configure_xfields(Type, Options, Lang, [])
}]}]}]}.
@@ -2484,8 +2477,8 @@ max_items(Options) ->
-define(JLIST_CONFIG_FIELD(Label, Var, Opts),
?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var),
- jlib:jid_to_string(get_option(Options, Var)),
- [jlib:jid_to_string(O) || O <- Opts])).
+ exmpp_jid:jid_to_list(get_option(Options, Var)),
+ [exmpp_jid:jid_to_list(O) || O <- Opts])).
-define(ALIST_CONFIG_FIELD(Label, Var, Opts),
?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var),
@@ -2493,7 +2486,7 @@ max_items(Options) ->
[atom_to_list(O) || O <- Opts])).
get_configure_xfields(_Type, Options, Lang, _Owners) ->
- [?XFIELD("hidden", "", "FORM_TYPE", ?NS_PUBSUB_NODE_CONFIG),
+ [?XFIELD("hidden", "", "FORM_TYPE", ?NS_PUBSUB_NODE_CONFIG_s),
?BOOL_CONFIG_FIELD("Deliver payloads with event notifications", deliver_payloads),
?BOOL_CONFIG_FIELD("Deliver event notifications", deliver_notifications),
?BOOL_CONFIG_FIELD("Notify subscribers when the node configuration changes", notify_config),
@@ -2506,10 +2499,10 @@ get_configure_xfields(_Type, Options, Lang, _Owners) ->
?ALIST_CONFIG_FIELD("Specify the access model", access_model,
[open, authorize, presence, roster, whitelist]),
%% XXX: change to list-multi, include current roster groups as options
- {xmlelement, "field", [{"type", "text-multi"},
- {"label", translate:translate(Lang, "Roster groups allowed to subscribe")},
- {"var", "pubsub#roster_groups_allowed"}],
- [{xmlelement, "value", [], [{xmlcdata, Value}]} ||
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = "text-multi"},
+ #xmlattr{name = 'label', value = translate:translate(Lang, "Roster groups allowed to subscribe")},
+ #xmlattr{name = 'var', value = "pubsub#roster_groups_allowed"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Value)}]} ||
Value <- get_option(Options, roster_groups_allowed, [])]},
?ALIST_CONFIG_FIELD("Specify the publisher model", publish_model,
[publishers, subscribers, open]),
@@ -2528,12 +2521,12 @@ get_configure_xfields(_Type, Options, Lang, _Owners) ->
%%The specified node does not exist.
%%
set_configure(Host, Node, From, Els, Lang) ->
- case xml:remove_cdata(Els) of
- [{xmlelement, "x", _Attrs1, _Els1} = XEl] ->
- case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of
- {?NS_XDATA, "cancel"} ->
+ case exmpp_xml:remove_cdata_from_list(Els) of
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'x'} = XEl] ->
+ case exmpp_xml:get_attribute(XEl, 'type', undefined) of
+ "cancel" ->
{result, []};
- {?NS_XDATA, "submit"} ->
+ "submit" ->
Action =
fun(#pubsub_node{options = Options, type = Type}=N) ->
case node_call(Type, get_affiliation,
@@ -2541,7 +2534,7 @@ set_configure(Host, Node, From, Els, Lang) ->
{result, owner} ->
case jlib:parse_xdata_submit(XEl) of
invalid ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
XData ->
OldOpts = case Options of
[] -> node_options(Type);
@@ -2557,7 +2550,7 @@ set_configure(Host, Node, From, Els, Lang) ->
end
end;
_ ->
- {error, ?ERR_FORBIDDEN}
+ {error, 'forbidden'}
end
end,
case transaction(Host, Node, Action, transaction) of
@@ -2568,10 +2561,10 @@ set_configure(Host, Node, From, Els, Lang) ->
Other
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end.
add_opt(Key, Value, Opts) ->
@@ -2587,7 +2580,7 @@ add_opt(Key, Value, Opts) ->
_ -> error
end,
case BoolVal of
- error -> {error, ?ERR_NOT_ACCEPTABLE};
+ error -> {error, 'not-acceptable'};
_ -> set_xoption(Opts, add_opt(Opt, BoolVal, NewOpts))
end).
@@ -2601,13 +2594,13 @@ add_opt(Key, Value, Opts) ->
IVal =< Max ->
set_xoption(Opts, add_opt(Opt, IVal, NewOpts));
_ ->
- {error, ?ERR_NOT_ACCEPTABLE}
+ {error, 'not-acceptable'}
end).
-define(SET_ALIST_XOPT(Opt, Val, Vals),
case lists:member(Val, [atom_to_list(V) || V <- Vals]) of
true -> set_xoption(Opts, add_opt(Opt, list_to_atom(Val), NewOpts));
- false -> {error, ?ERR_NOT_ACCEPTABLE}
+ false -> {error, 'not-acceptable'}
end).
-define(SET_LIST_XOPT(Opt, Val),
@@ -2654,7 +2647,7 @@ set_xoption([{"pubsub#type", Value} | Opts], NewOpts) ->
set_xoption([{"pubsub#body_xslt", Value} | Opts], NewOpts) ->
?SET_STRING_XOPT(body_xslt, Value);
set_xoption([_ | _Opts], _NewOpts) ->
- {error, ?ERR_NOT_ACCEPTABLE}.
+ {error, 'not-acceptable'}.
%%%% plugin handling
@@ -2793,27 +2786,27 @@ transaction(Fun, Trans) ->
{atomic, {error, Error}} -> {error, Error};
{aborted, Reason} ->
?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
{'EXIT', Reason} ->
?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
Other ->
?ERROR_MSG("transaction return internal error: ~p~n", [Other]),
- {error, ?ERR_INTERNAL_SERVER_ERROR}
+ {error, 'internal-server-error'}
end.
%%%% helpers
%% Add pubsub-specific error element
extended_error(Error, Ext) ->
- extended_error(Error, Ext, [{"xmlns", ?NS_PUBSUB_ERRORS}]).
+ extended_error(Error, Ext, []).
extended_error(Error, unsupported, Feature) ->
- extended_error(Error, "unsupported",
- [{"xmlns", ?NS_PUBSUB_ERRORS},
- {"feature", Feature}]);
-extended_error({xmlelement, Error, Attrs, SubEls}, Ext, ExtAttrs) ->
- {xmlelement, Error, Attrs,
- lists:reverse([{xmlelement, Ext, ExtAttrs, []} | SubEls])}.
+ extended_error(Error, unsupported,
+ [#xmlattr{name = 'feature', value = Feature}]);
+extended_error(Error, Ext, ExtAttrs) ->
+ Pubsub_Err = #xmlel{ns = ?NS_PUBSUB_ERRORS, name = Ext, attrs = ExtAttrs},
+ exmpp_xml:append_child(exmpp_stanza:error(?NS_JABBER_CLIENT, Error),
+ Pubsub_Err).
%% Give a uniq identifier
uniqid() ->
diff --git a/src/mod_pubsub/node_default.erl b/src/mod_pubsub/node_default.erl
index 97e363f79..122b76e91 100644
--- a/src/mod_pubsub/node_default.erl
+++ b/src/mod_pubsub/node_default.erl
@@ -41,8 +41,9 @@
-module(node_default).
-author('christophe.romain@process-one.net').
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("pubsub.hrl").
--include("jlib.hrl").
-behaviour(gen_pubsub_node).
@@ -194,10 +195,10 @@ features() ->
%% ```check_create_user_permission(Host, Node, Owner, Access) ->
%% node_default:check_create_user_permission(Host, Node, Owner, Access).'''
create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
- LOwner = jlib:jid_tolower(Owner),
+ LOwner = jlib:short_prepd_jid(Owner),
{User, Server, _Resource} = LOwner,
Allowed = case LOwner of
- {"", Host, ""} ->
+ {undefined, Host, undefined} ->
true; % pubsub service always allowed
_ ->
case acl:match_rule(ServerHost, Access, LOwner) of
@@ -219,7 +220,7 @@ create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
%% Owner = mod_pubsub:jid()
%% @doc
create_node(Host, Node, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
mnesia:write(#pubsub_state{stateid = {OwnerKey, {Host, Node}},
affiliation = owner, subscription = none}),
{result, {default, broadcast}}.
@@ -281,11 +282,10 @@ delete_node(Host, Removed) ->
%% In the default plugin module, the record is unchanged.
subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
SendLast, PresenceSubscription, RosterGroup) ->
- SenderKey = jlib:jid_tolower(Sender),
- Authorized = (jlib:jid_remove_resource(SenderKey) == jlib:jid_remove_resource(Subscriber)),
+ Authorized = (jlib:short_prepd_bare_jid(Sender) == jlib:short_bare_jid(Subscriber)),
% TODO add some acl check for Authorized ?
State = case get_state(Host, Node, Subscriber) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
#pubsub_state{stateid = {Subscriber, {Host, Node}}}; % TODO: bug on Key ?
{result, S} -> S
end,
@@ -294,31 +294,31 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
if
not Authorized ->
%% JIDs do not match
- {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "invalid-jid")};
+ {error, ?ERR_EXTENDED('bad-request', "invalid-jid")};
Affiliation == outcast ->
%% Requesting entity is blocked
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
Subscription == pending ->
%% Requesting entity has pending subscription
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")};
+ {error, ?ERR_EXTENDED('not-authorized', "pending-subscription")};
(AccessModel == presence) and (not PresenceSubscription) ->
%% Entity is not authorized to create a subscription (presence subscription required)
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
+ {error, ?ERR_EXTENDED('not-authorized', "presence-subscription-required")};
(AccessModel == roster) and (not RosterGroup) ->
%% Entity is not authorized to create a subscription (not in roster group)
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")};
+ {error, ?ERR_EXTENDED('not-authorized', "not-in-roster-group")};
(AccessModel == whitelist) -> % TODO: to be done
%% Node has whitelist access model
- {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")};
+ {error, ?ERR_EXTENDED('not-allowed', "closed-node")};
(AccessModel == authorize) -> % TODO: to be done
%% Node has authorize access model
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
%%MustPay ->
%% % Payment is required for a subscription
%% {error, ?ERR_PAYMENT_REQUIRED};
%%ForbiddenAnonymous ->
%% % Requesting entity is anonymous
- %% {error, ?ERR_FORBIDDEN};
+ %% {error, 'forbidden'};
true ->
NewSubscription =
if
@@ -352,8 +352,8 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
%% Reason = mod_pubsub:stanzaError()
%% @doc Unsubscribe the Subscriber from the Node.
unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
- SenderKey = jlib:jid_tolower(Sender),
- Match = jlib:jid_remove_resource(SenderKey) == jlib:jid_remove_resource(Subscriber),
+ SenderKey = jlib:short_prepd_jid(Sender),
+ Match = jlib:short_prepd_bare_jid(Sender) == jlib:short_bare_jid(Subscriber),
Authorized = case Match of
true ->
true;
@@ -364,23 +364,23 @@ unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
end
end,
case get_state(Host, Node, Subscriber) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
%% Requesting entity is not a subscriber
- {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST, "not-subscribed")};
+ {error, ?ERR_EXTENDED('unexpected-request', "not-subscribed")};
{result, State} ->
if
%% Entity did not specify SubID
%%SubID == "", ?? ->
- %% {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
+ %% {error, ?ERR_EXTENDED('bad-request', "subid-required")};
%% Invalid subscription identifier
%%InvalidSubID ->
- %% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
+ %% {error, ?ERR_EXTENDED('not-acceptable', "invalid-subid")};
%% Requesting entity is not a subscriber
State#pubsub_state.subscription == none ->
- {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST, "not-subscribed")};
+ {error, ?ERR_EXTENDED('unexpected-request', "not-subscribed")};
%% Requesting entity is prohibited from unsubscribing entity
not Authorized ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
true ->
set_state(State#pubsub_state{subscription = none}),
{result, default}
@@ -427,9 +427,9 @@ unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
%%
%% In the default plugin module, the record is unchanged.
publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
- PublisherKey = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)),
+ PublisherKey = jlib:short_prepd_bare_jid(Publisher),
State = case get_state(Host, Node, PublisherKey) of
- {error, ?ERR_ITEM_NOT_FOUND} -> #pubsub_state{stateid={PublisherKey, {Host, Node}}};
+ {error, 'item-not-found'} -> #pubsub_state{stateid={PublisherKey, {Host, Node}}};
{result, S} -> S
end,
#pubsub_state{affiliation = Affiliation,
@@ -441,12 +441,12 @@ publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
or ((PublishModel == subscribers)
and (Subscription == subscribed))) ->
%% Entity does not have sufficient privileges to publish to node
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
true ->
PubId = {PublisherKey, now()},
%% TODO: check creation, presence, roster (EJAB-663)
Item = case get_item(Host, Node, ItemId) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
#pubsub_item{itemid = {ItemId, {Host, Node}},
creation = PubId,
modification = PubId,
@@ -504,9 +504,9 @@ remove_extra_items(Host, Node, MaxItems, ItemIds) ->
%% Default plugin: The user performing the deletion must be the node owner
%% or a publisher.
delete_item(Host, Node, Publisher, ItemId) ->
- PublisherKey = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)),
+ PublisherKey = jlib:short_prepd_bare_jid(Publisher),
State = case get_state(Host, Node, PublisherKey) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
#pubsub_state{stateid = {PublisherKey, {Host, Node}}};
{result, S} ->
S
@@ -520,7 +520,7 @@ delete_item(Host, Node, Publisher, ItemId) ->
if
not Allowed ->
%% Requesting entity does not have sufficient privileges
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
true ->
case get_item(Host, Node, ItemId) of
{result, _} ->
@@ -530,7 +530,7 @@ delete_item(Host, Node, Publisher, ItemId) ->
{result, {default, broadcast}};
_ ->
%% Non-existent node or item
- {error, ?ERR_ITEM_NOT_FOUND}
+ {error, 'item-not-found'}
end
end.
@@ -541,7 +541,7 @@ delete_item(Host, Node, Publisher, ItemId) ->
%% Node = mod_pubsub:pubsubNode()
%% Owner = mod_pubsub:jid()
purge_node(Host, Node, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
case get_state(Host, Node, OwnerKey) of
{result, #pubsub_state{items = Items, affiliation = owner}} ->
lists:foreach(fun(ItemId) ->
@@ -550,9 +550,9 @@ purge_node(Host, Node, Owner) ->
{result, {default, broadcast}};
{result, _} ->
%% Entity is not owner
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
_ ->
- {error, ?ERR_ITEM_NOT_FOUND}
+ {error, 'item-not-found'}
end.
%% @spec (Host, JID) -> [{Node,Affiliation}]
@@ -566,7 +566,7 @@ purge_node(Host, Node, Owner) ->
%% that will be added to the affiliation stored in the main
%% pubsub_state table.
get_entity_affiliations(Host, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
States = mnesia:match_object(
#pubsub_state{stateid = {OwnerKey, {Host, '_'}},
_ = '_'}),
@@ -585,7 +585,7 @@ get_node_affiliations(Host, Node) ->
{result, lists:map(Tr, States)}.
get_affiliation(Host, Node, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
Affiliation = case get_state(Host, Node, OwnerKey) of
{result, #pubsub_state{affiliation = A}} -> A;
_ -> none
@@ -593,9 +593,9 @@ get_affiliation(Host, Node, Owner) ->
{result, Affiliation}.
set_affiliation(Host, Node, Owner, Affiliation) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
Record = case get_state(Host, Node, OwnerKey) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
#pubsub_state{stateid = {OwnerKey, {Host, Node}},
affiliation = Affiliation};
{result, State} ->
@@ -616,7 +616,7 @@ set_affiliation(Host, Node, Owner, Affiliation) ->
%% that will be added to the affiliation stored in the main
%% pubsub_state table.
get_entity_subscriptions(Host, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
States = mnesia:match_object(
#pubsub_state{stateid = {OwnerKey, {Host, '_'}},
_ = '_'}),
@@ -635,7 +635,7 @@ get_node_subscriptions(Host, Node) ->
{result, lists:map(Tr, States)}.
get_subscription(Host, Node, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
Subscription = case get_state(Host, Node, OwnerKey) of
{result, #pubsub_state{subscription = S}} -> S;
_ -> none
@@ -643,9 +643,9 @@ get_subscription(Host, Node, Owner) ->
{result, Subscription}.
set_subscription(Host, Node, Owner, Subscription) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
Record = case get_state(Host, Node, OwnerKey) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
#pubsub_state{stateid = {OwnerKey, {Host, Node}},
subscription = Subscription};
{result, State} ->
@@ -684,7 +684,7 @@ get_state(Host, Node, JID) ->
[State] when is_record(State, pubsub_state) ->
{result, State};
_ ->
- {error, ?ERR_ITEM_NOT_FOUND}
+ {error, 'item-not-found'}
end.
%% @spec (State) -> ok | {error, Reason::stanzaError()}
@@ -693,7 +693,7 @@ get_state(Host, Node, JID) ->
set_state(State) when is_record(State, pubsub_state) ->
mnesia:write(State);
set_state(_) ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}.
+ {error, 'internal-server-error'}.
%% @spec (Host, Node) -> [Items] | []
%% Host = mod_pubsub:host()
@@ -715,7 +715,7 @@ get_items(Host, Node, _From) ->
{result, Items}.
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
{Affiliation, Subscription} =
- case get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))) of
+ case get_state(Host, Node, jlib:short_prepd_bare_jid(JID)) of
{result, #pubsub_state{affiliation = A, subscription = S}} -> {A, S};
_ -> {none, none}
end,
@@ -723,28 +723,28 @@ get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubI
if
%%SubID == "", ?? ->
%% Entity has multiple subscriptions to the node but does not specify a subscription ID
- %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
+ %{error, ?ERR_EXTENDED('bad-request', "subid-required")};
%%InvalidSubID ->
%% Entity is subscribed but specifies an invalid subscription ID
- %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
+ %{error, ?ERR_EXTENDED('not-acceptable', "invalid-subid")};
Affiliation == outcast ->
%% Requesting entity is blocked
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
(AccessModel == open) and (not Subscribed) ->
%% Entity is not subscribed
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
+ {error, ?ERR_EXTENDED('not-authorized', "not-subscribed")};
(AccessModel == presence) and (not PresenceSubscription) ->
%% Entity is not authorized to create a subscription (presence subscription required)
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
+ {error, ?ERR_EXTENDED('not-authorized', "presence-subscription-required")};
(AccessModel == roster) and (not RosterGroup) ->
%% Entity is not authorized to create a subscription (not in roster group)
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")};
+ {error, ?ERR_EXTENDED('not-authorized', "not-in-roster-group")};
(AccessModel == whitelist) -> % TODO: to be done
%% Node has whitelist access model
- {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")};
+ {error, ?ERR_EXTENDED('not-allowed', "closed-node")};
(AccessModel == authorize) -> % TODO: to be done
%% Node has authorize access model
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
%%MustPay ->
%% % Payment is required for a subscription
%% {error, ?ERR_PAYMENT_REQUIRED};
@@ -763,11 +763,11 @@ get_item(Host, Node, ItemId) ->
[Item] when is_record(Item, pubsub_item) ->
{result, Item};
_ ->
- {error, ?ERR_ITEM_NOT_FOUND}
+ {error, 'item-not-found'}
end.
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
{Affiliation, Subscription} =
- case get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))) of
+ case get_state(Host, Node, jlib:short_prepd_bare_jid(JID)) of
{result, #pubsub_state{affiliation = A, subscription = S}} -> {A, S};
_ -> {none, none}
end,
@@ -775,28 +775,28 @@ get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup
if
%%SubID == "", ?? ->
%% Entity has multiple subscriptions to the node but does not specify a subscription ID
- %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
+ %{error, ?ERR_EXTENDED('bad-request', "subid-required")};
%%InvalidSubID ->
%% Entity is subscribed but specifies an invalid subscription ID
- %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
+ %{error, ?ERR_EXTENDED('not-acceptable', "invalid-subid")};
Affiliation == outcast ->
%% Requesting entity is blocked
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
(AccessModel == open) and (not Subscribed) ->
%% Entity is not subscribed
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
+ {error, ?ERR_EXTENDED('not-authorized', "not-subscribed")};
(AccessModel == presence) and (not PresenceSubscription) ->
%% Entity is not authorized to create a subscription (presence subscription required)
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
+ {error, ?ERR_EXTENDED('not-authorized', "presence-subscription-required")};
(AccessModel == roster) and (not RosterGroup) ->
%% Entity is not authorized to create a subscription (not in roster group)
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")};
+ {error, ?ERR_EXTENDED('not-authorized', "not-in-roster-group")};
(AccessModel == whitelist) -> % TODO: to be done
%% Node has whitelist access model
- {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")};
+ {error, ?ERR_EXTENDED('not-allowed', "closed-node")};
(AccessModel == authorize) -> % TODO: to be done
%% Node has authorize access model
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
%%MustPay ->
%% % Payment is required for a subscription
%% {error, ?ERR_PAYMENT_REQUIRED};
@@ -810,7 +810,7 @@ get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup
set_item(Item) when is_record(Item, pubsub_item) ->
mnesia:write(Item);
set_item(_) ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}.
+ {error, 'internal-server-error'}.
%% @doc Return the name of the node if known: Default is to return
%% node id.
diff --git a/src/mod_pubsub/node_pep.erl b/src/mod_pubsub/node_pep.erl
index 1c1bff7d7..28f20d5c3 100644
--- a/src/mod_pubsub/node_pep.erl
+++ b/src/mod_pubsub/node_pep.erl
@@ -29,9 +29,10 @@
-module(node_pep).
-author('christophe.romain@process-one.net').
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
-include("pubsub.hrl").
--include("jlib.hrl").
-behaviour(gen_pubsub_node).
@@ -111,10 +112,10 @@ features() ->
].
create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) ->
- LOwner = jlib:jid_tolower(Owner),
+ LOwner = jlib:short_prepd_jid(Owner),
{User, Server, _Resource} = LOwner,
Allowed = case LOwner of
- {"", Host, ""} ->
+ {undefined, Host, undefined} ->
true; % pubsub service always allowed
_ ->
case acl:match_rule(ServerHost, Access, LOwner) of
@@ -167,21 +168,21 @@ purge_node(Host, Node, Owner) ->
node_default:purge_node(Host, Node, Owner).
get_entity_affiliations(_Host, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
node_default:get_entity_affiliations(OwnerKey, Owner).
get_node_affiliations(Host, Node) ->
- OwnerKey = jlib:jid_remove_resource(Host),
+ OwnerKey = jlib:short_bare_jid(Host),
node_default:get_node_affiliations(OwnerKey, Node).
get_affiliation(_Host, Node, Owner) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
node_default:get_affiliation(OwnerKey, Node, Owner).
set_affiliation(_Host, Node, Owner, Affiliation) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
Record = case get_state(OwnerKey, Node, OwnerKey) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
+ {error, 'item-not-found'} ->
#pubsub_state{stateid = {OwnerKey, {OwnerKey, Node}},
affiliation = Affiliation};
{result, State} ->
diff --git a/src/mod_pubsub/nodetree_default.erl b/src/mod_pubsub/nodetree_default.erl
index 700397edb..f3dea3eb9 100644
--- a/src/mod_pubsub/nodetree_default.erl
+++ b/src/mod_pubsub/nodetree_default.erl
@@ -92,7 +92,7 @@ options() ->
set_node(Record) when is_record(Record, pubsub_node) ->
mnesia:write(Record);
set_node(_) ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}.
+ {error, 'internal-server-error'}.
%% @spec (Host, Node) -> pubsubNode() | {error, Reason}
%% Host = mod_pubsub:host()
@@ -100,7 +100,7 @@ set_node(_) ->
get_node(Host, Node) ->
case catch mnesia:read({pubsub_node, {Host, Node}}) of
[Record] when is_record(Record, pubsub_node) -> Record;
- [] -> {error, ?ERR_ITEM_NOT_FOUND};
+ [] -> {error, 'item-not-found'};
Error -> Error
end.
@@ -134,7 +134,7 @@ get_subnodes_tree(Host, Node) ->
%% Owner = mod_pubsub:jid()
%% Options = list()
create_node(Key, Node, Type, Owner, Options) ->
- OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
+ OwnerKey = jlib:short_prepd_bare_jid(Owner),
case mnesia:read({pubsub_node, {Key, Node}}) of
[] ->
{ParentNode, ParentExists} =
@@ -166,11 +166,11 @@ create_node(Key, Node, Type, Owner, Options) ->
options = Options});
false ->
%% Requesting entity is prohibited from creating nodes
- {error, ?ERR_FORBIDDEN}
+ {error, 'forbidden'}
end;
_ ->
%% NodeID already exists
- {error, ?ERR_CONFLICT}
+ {error, 'conflict'}
end.
%% @spec (Key, Node) -> [mod_pubsub:node()]