25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-26 16:26:24 +01:00

o Remove compatibility code. Use the atom 'undefined' in JIDs (normal

and short).
o  Add try/catch blocks where Exmpp can raise exceptions.
o  Remove some unused code.
o  Convert on-disk Mnesia database: JIDs, extra XML elements and
askmessage are concerned.
o  By default, 'askmessage' is now an empty binary instead of an empty
string, for consistency's sake.
o  Fix some bugs.

SVN Revision: 1547
This commit is contained in:
Jean-Sébastien Pédron 2008-08-26 13:59:04 +00:00
parent 9f0d79da9a
commit 4e39f4cab1
3 changed files with 322 additions and 236 deletions

View File

@ -17,6 +17,14 @@
where. Also, in JIDs (normal and short), the atom "undefined' is where. Also, in JIDs (normal and short), the atom "undefined' is
expected, not the empty string anymore! expected, not the empty string anymore!
* src/mod_roster.hrl, src/mod_roster.erl: Remove compatibility code.
Use the atom 'undefined' in JIDs (normal and short). Add try/catch
blocks where Exmpp can raise exceptions. Remove some unused code.
Convert on-disk Mnesia database: JIDs, extra XML elements and
askmessage are concerned. By default, 'askmessage' is now an empty
binary instead of an empty string, for consistency's sake. Fix some
bugs.
2008-08-14 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-08-14 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* translate.erl (ascii_tolower): Accept 'undefined' as a language and * translate.erl (ascii_tolower): Accept 'undefined' as a language and

View File

@ -123,9 +123,7 @@ process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
process_iq_get(From, To, IQ_Rec) -> process_iq_get(From, To, IQ_Rec) ->
LUser = From#jid.lnode, US = {From#jid.lnode, From#jid.ldomain},
LServer = From#jid.ldomain,
US = {LUser, LServer},
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
Items when is_list(Items) -> Items when is_list(Items) ->
XItems = lists:map(fun item_to_xml/1, Items), XItems = lists:map(fun item_to_xml/1, Items),
@ -188,14 +186,12 @@ process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
end, end,
exmpp_iq:result(IQ_Rec). exmpp_iq:result(IQ_Rec).
process_item_set(From, To, #xmlel{} = Item) -> process_item_set(From, To, #xmlel{} = El) ->
try try
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(Item, 'jid', "")), JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
% XXX OLD FORMAT: old JID (with empty strings). #jid{node = User, lnode = LUser, ldomain = LServer} = From,
#jid{node = User, lnode = LUser, ldomain = LServer} = JID = jlib:short_jid(JID1),
jlib:to_old_jid(From), LJID = jlib:short_prepd_jid(JID1),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
LJID = jlib:short_jid(JID1),
F = fun() -> F = fun() ->
Res = mnesia:read({roster, {LUser, LServer, LJID}}), Res = mnesia:read({roster, {LUser, LServer, LJID}}),
Item = case Res of Item = case Res of
@ -209,8 +205,8 @@ process_item_set(From, To, #xmlel{} = Item) ->
groups = [], groups = [],
xs = []} xs = []}
end, end,
Item1 = process_item_attrs(Item, Item#xmlel.attrs), Item1 = process_item_attrs(Item, El#xmlel.attrs),
Item2 = process_item_els(Item1, Item#xmlel.children), Item2 = process_item_els(Item1, El#xmlel.children),
case Item2#roster.subscription of case Item2#roster.subscription of
remove -> remove ->
mnesia:delete({roster, {LUser, LServer, LJID}}); mnesia:delete({roster, {LUser, LServer, LJID}});
@ -270,15 +266,6 @@ process_item_set(_From, _To, _) ->
process_item_attrs(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) -> process_item_attrs(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of case Attr of
'jid' ->
try
JID1 = exmpp_jid:list_to_jid(Val),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
process_item_attrs(Item#roster{jid = JID}, Attrs)
catch
_ ->
process_item_attrs(Item, Attrs)
end;
'name' -> 'name' ->
process_item_attrs(Item#roster{name = Val}, Attrs); process_item_attrs(Item#roster{name = Val}, Attrs);
'subscription' -> 'subscription' ->
@ -319,7 +306,7 @@ process_item_els(Item, []) ->
push_item(User, Server, From, Item) -> push_item(User, Server, From, Item) ->
ejabberd_sm:route(exmpp_jid:make_bare_jid(""), ejabberd_sm:route(#jid{},
exmpp_jid:make_bare_jid(User, Server), exmpp_jid:make_bare_jid(User, Server),
#xmlel{name = 'broadcast', children = #xmlel{name = 'broadcast', children =
[{item, [{item,
@ -340,6 +327,7 @@ push_item(User, Server, Resource, From, Item) ->
ResIQ). ResIQ).
get_subscription_lists(_, User, Server) -> get_subscription_lists(_, User, Server) ->
try
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer}, US = {LUser, LServer},
@ -348,6 +336,10 @@ get_subscription_lists(_, User, Server) ->
fill_subscription_lists(Items, [], []); fill_subscription_lists(Items, [], []);
_ -> _ ->
{[], []} {[], []}
end
catch
_ ->
{[], []}
end. end.
fill_subscription_lists([I | Is], F, T) -> fill_subscription_lists([I | Is], F, T) ->
@ -378,16 +370,15 @@ out_subscription(User, Server, JID, Type) ->
process_subscription(out, User, Server, JID, Type, []). process_subscription(out, User, Server, JID, Type, []).
process_subscription(Direction, User, Server, JID1, Type, Reason) -> process_subscription(Direction, User, Server, JID1, Type, Reason) ->
try
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer}, US = {LUser, LServer},
LJID = jlib:short_jid(JID1), LJID = jlib:short_prepd_jid(JID1),
F = fun() -> F = fun() ->
Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
[] -> [] ->
JID = {JID1#jid.node, JID = jlib:short_jid(JID1),
JID1#jid.domain,
JID1#jid.resource},
#roster{usj = {LUser, LServer, LJID}, #roster{usj = {LUser, LServer, LJID},
us = US, us = US,
jid = JID}; jid = JID};
@ -458,6 +449,10 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
end; end;
_ -> _ ->
false false
end
catch
_ ->
false
end. end.
%% in_state_change(Subscription, Pending, Type) -> NewState %% in_state_change(Subscription, Pending, Type) -> NewState
@ -557,6 +552,7 @@ in_auto_reply(_, _, _) -> none.
remove_user(User, Server) -> remove_user(User, Server) ->
try
LUser = exmpp_stringpre:nodeprep(User), LUser = exmpp_stringpre:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer}, US = {LUser, LServer},
@ -566,12 +562,16 @@ remove_user(User, Server) ->
end, end,
mnesia:index_read(roster, US, #roster.us)) mnesia:index_read(roster, US, #roster.us))
end, end,
mnesia:transaction(F). mnesia:transaction(F)
catch
_ ->
ok
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set_items(User, Server, SubEl) -> set_items(User, Server, #xmlel{children = Els}) ->
{xmlelement, _Name, _Attrs, Els} = SubEl, try
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
F = fun() -> F = fun() ->
@ -579,13 +579,17 @@ set_items(User, Server, SubEl) ->
process_item_set_t(LUser, LServer, El) process_item_set_t(LUser, LServer, El)
end, Els) end, Els)
end, end,
mnesia:transaction(F). mnesia:transaction(F)
catch
_ ->
ok
end.
process_item_set_t(LUser, LServer, #xmlel{} = El) -> process_item_set_t(LUser, LServer, #xmlel{} = El) ->
try try
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")), JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource}, JID = jlib:short_jid(JID1),
LJID = {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource}, LJID = jlib:short_prepd_jid(JID1),
Item = #roster{usj = {LUser, LServer, LJID}, Item = #roster{usj = {LUser, LServer, LJID},
us = {LUser, LServer}, us = {LUser, LServer},
jid = JID}, jid = JID},
@ -606,15 +610,6 @@ process_item_set_t(_LUser, _LServer, _) ->
process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) -> process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of case Attr of
'jid' ->
try
JID1 = exmpp_jid:list_to_jid(Val),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
catch
_ ->
process_item_attrs_ws(Item, Attrs)
end;
'name' -> 'name' ->
process_item_attrs_ws(Item#roster{name = Val}, Attrs); process_item_attrs_ws(Item#roster{name = Val}, Attrs);
'subscription' -> 'subscription' ->
@ -653,11 +648,6 @@ get_in_pending_subscriptions(Ls, User, Server) ->
Ls ++ lists:map( Ls ++ lists:map(
fun(R) -> fun(R) ->
Message = R#roster.askmessage, Message = R#roster.askmessage,
Status = if is_binary(Message) ->
binary_to_list(Message);
true ->
""
end,
{U, S, R} = R#roster.jid, {U, S, R} = R#roster.jid,
Attrs1 = exmpp_stanza:set_sender_in_list([], Attrs1 = exmpp_stanza:set_sender_in_list([],
exmpp_jid:jid_to_list(U, S, R)), exmpp_jid:jid_to_list(U, S, R)),
@ -665,7 +655,7 @@ get_in_pending_subscriptions(Ls, User, Server) ->
exmpp_jid:jid_to_list(JID)), exmpp_jid:jid_to_list(JID)),
Pres1 = exmpp_presence:subscribe(), Pres1 = exmpp_presence:subscribe(),
Pres2 = Pres1#xmlel{attrs = Attrs2}, Pres2 = Pres1#xmlel{attrs = Attrs2},
exmpp_presence:set_status(Pres2, Status) exmpp_presence:set_status(Pres2, Message)
end, end,
lists:filter( lists:filter(
fun(R) -> fun(R) ->
@ -684,14 +674,15 @@ get_in_pending_subscriptions(Ls, User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_jid_info(_, User, Server, JID) -> get_jid_info(_, User, Server, JID) ->
try
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
LJID = jlib:short_jid(JID),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
LJID = jlib:short_prepd_jid(JID),
case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
[#roster{subscription = Subscription, groups = Groups}] -> [#roster{subscription = Subscription, groups = Groups}] ->
{Subscription, Groups}; {Subscription, Groups};
_ -> _ ->
LRJID = jlib:short_jid(exmpp_jid:jid_to_bare_jid(JID)), LRJID = jlib:short_prepd_bare_jid(JID),
if if
LRJID == LJID -> LRJID == LJID ->
{none, []}; {none, []};
@ -705,6 +696,10 @@ get_jid_info(_, User, Server, JID) ->
{none, []} {none, []}
end end
end end
end
catch
_ ->
{none, []}
end. end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -714,7 +709,7 @@ update_table() ->
Fields = record_info(fields, roster), Fields = record_info(fields, roster),
case mnesia:table_info(roster, attributes) of case mnesia:table_info(roster, attributes) of
Fields -> Fields ->
ok; convert_to_exmpp();
[uj, user, jid, name, subscription, ask, groups, xattrs, xs] -> [uj, user, jid, name, subscription, ask, groups, xattrs, xs] ->
convert_table1(Fields); convert_table1(Fields);
[usj, us, jid, name, subscription, ask, groups, xattrs, xs] -> [usj, us, jid, name, subscription, ask, groups, xattrs, xs] ->
@ -742,11 +737,18 @@ convert_table1(Fields) ->
F1 = fun() -> F1 = fun() ->
mnesia:write_lock_table(mod_roster_tmp_table), mnesia:write_lock_table(mod_roster_tmp_table),
mnesia:foldl( mnesia:foldl(
fun(#roster{usj = {U, JID}, us = U} = R, _) -> fun(#roster{usj = {U, {JID_U, JID_S, JID_R}}, us = U, xs = XS, askmessage = AM} = R, _) ->
U1 = convert_jid_to_exmpp(U),
JID_U1 = convert_jid_to_exmpp(JID_U),
JID_R1 = convert_jid_to_exmpp(JID_R),
JID1 = {JID_U1, JID_S, JID_R1},
XS1 = convert_xs_to_exmpp(XS),
AM1 = convert_askmessage_to_exmpp(AM),
mnesia:dirty_write( mnesia:dirty_write(
mod_roster_tmp_table, mod_roster_tmp_table,
R#roster{usj = {U, Host, JID}, R#roster{usj = {U1, Host, JID1},
us = {U, Host}}) us = {U1, Host}, xs = XS1,
askmessage = AM1})
end, ok, roster) end, ok, roster)
end, end,
mnesia:transaction(F1), mnesia:transaction(F1),
@ -766,9 +768,74 @@ convert_table1(Fields) ->
convert_table2(Fields) -> convert_table2(Fields) ->
?INFO_MSG("Converting roster table from " ?INFO_MSG("Converting roster table from "
"{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []), "{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []),
mnesia:transform_table(roster, ignore, Fields). mnesia:transform_table(roster, ignore, Fields),
convert_to_exmpp().
convert_to_exmpp() ->
Fun = fun() ->
case mnesia:first(roster) of
'$end_of_table' ->
none;
Key ->
case mnesia:read({roster, Key}) of
[#roster{jid = {_, _, undefined}}] ->
none;
[#roster{jid = {_, _, ""}}] ->
mnesia:foldl(fun convert_to_exmpp2/2,
done, roster, write)
end
end
end,
Ret = mnesia:transaction(Fun),
io:format("Conversion return value: ~p~n", [Ret]).
convert_to_exmpp2(#roster{
usj = {USJ_U, USJ_S, {USJ_JU, USJ_JS, USJ_JR}} = Key,
us = {US_U, US_S},
jid = {JID_U, JID_S, JID_R},
xs = XS, askmessage = AM} = R, Acc) ->
% Remove old entry.
mnesia:delete({roster, Key}),
% Convert "" to undefined in JIDs.
USJ_U1 = convert_jid_to_exmpp(USJ_U),
USJ_JU1 = convert_jid_to_exmpp(USJ_JU),
USJ_JR1 = convert_jid_to_exmpp(USJ_JR),
US_U1 = convert_jid_to_exmpp(US_U),
JID_U1 = convert_jid_to_exmpp(JID_U),
JID_R1 = convert_jid_to_exmpp(JID_R),
% Convert xs.
XS1 = convert_xs_to_exmpp(XS),
% Convert askmessage.
AM1 = convert_askmessage_to_exmpp(AM),
% Prepare the new record.
New_R = R#roster{
usj = {USJ_U1, USJ_S, {USJ_JU1, USJ_JS, USJ_JR1}},
us = {US_U1, US_S},
jid = {JID_U1, JID_S, JID_R1},
xs = XS1, askmessage = AM1},
% Write the new record.
mnesia:write(New_R),
Acc.
convert_jid_to_exmpp("") -> undefined;
convert_jid_to_exmpp(V) -> V.
convert_xs_to_exmpp(Els) ->
convert_xs_to_exmpp(Els, []).
convert_xs_to_exmpp([El | Rest], Result) ->
New_El = exmpp_xml:xmlelement_to_xmlel(El,
[?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
convert_xs_to_exmpp(Rest, [New_El | Result]);
convert_xs_to_exmpp([], Result) ->
lists:reverse(Result).
convert_askmessage_to_exmpp(AM) when is_binary(AM) ->
AM;
convert_askmessage_to_exmpp(AM) ->
list_to_binary(AM).
webadmin_page(_, Host, webadmin_page(_, Host,
#request{us = _US, #request{us = _US,
path = ["user", U, "roster"], path = ["user", U, "roster"],
@ -780,6 +847,7 @@ webadmin_page(_, Host,
webadmin_page(Acc, _, _) -> Acc. webadmin_page(Acc, _, _) -> Acc.
user_roster(User, Server, Query, Lang) -> user_roster(User, Server, Query, Lang) ->
try
US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)}, US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
Items1 = mnesia:dirty_index_read(roster, US, #roster.us), Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
Res = user_roster_parse_query(User, Server, Items1, Query), Res = user_roster_parse_query(User, Server, Items1, Query),
@ -847,7 +915,17 @@ user_roster(User, Server, Query, Lang) ->
[?P, [?P,
?INPUT("text", "newjid", ""), ?C(" "), ?INPUT("text", "newjid", ""), ?C(" "),
?INPUTT("submit", "addjid", "Add Jabber ID") ?INPUTT("submit", "addjid", "Add Jabber ID")
])]. ])]
catch
_ ->
[?XC("h1", ?T("Roster of ") ++ us_to_list({User, Server}))] ++
[?CT("Bad format"), ?P] ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
[?P,
?INPUT("text", "newjid", ""), ?C(" "),
?INPUTT("submit", "addjid", "Add Jabber ID")
])]
end.
user_roster_parse_query(User, Server, Items, Query) -> user_roster_parse_query(User, Server, Items, Query) ->
case lists:keysearch("addjid", 1, Query) of case lists:keysearch("addjid", 1, Query) of

View File

@ -26,6 +26,6 @@
subscription = none, subscription = none,
ask = none, ask = none,
groups = [], groups = [],
askmessage = [], askmessage = <<>>,
xs = []}). xs = []}).