From fea7eac245507b65423800983870144d5b493bac Mon Sep 17 00:00:00 2001 From: Badlop Date: Sat, 21 Feb 2009 09:28:58 +0000 Subject: [PATCH] Merge r1877 from trunk: * src/mod_roster.erl: When account is deleted, cancel presence subscription for all roster items (EJAB-790) * src/mod_roster_odbc.erl: Likewise SVN Revision: 1904 --- ChangeLog | 4 +++ src/mod_roster.erl | 75 ++++++++++++++++++++++++++--------------- src/mod_roster_odbc.erl | 75 ++++++++++++++++++++++++++--------------- 3 files changed, 98 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index c50aa0646..9fa9fad22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-02-21 Badlop + * src/mod_roster.erl: When account is deleted, cancel presence + subscription for all roster items (EJAB-790) + * src/mod_roster_odbc.erl: Likewise + * src/mod_shared_roster.erl: Fix bug: a pending subscription request, and later the requester added to the roster due to a shared roster group, that request could neither be accepted or diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 278602b8e..323f92c97 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -253,34 +253,7 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) -> push_item(User, LServer, To, Item), case Item#roster.subscription of remove -> - IsTo = case OldItem#roster.subscription of - both -> true; - to -> true; - _ -> false - end, - IsFrom = case OldItem#roster.subscription of - both -> true; - from -> true; - _ -> false - end, - if IsTo -> - ejabberd_router:route( - jlib:jid_remove_resource(From), - jlib:make_jid(OldItem#roster.jid), - {xmlelement, "presence", - [{"type", "unsubscribe"}], - []}); - true -> ok - end, - if IsFrom -> - ejabberd_router:route( - jlib:jid_remove_resource(From), - jlib:make_jid(OldItem#roster.jid), - {xmlelement, "presence", - [{"type", "unsubscribed"}], - []}); - true -> ok - end, + send_unsubscribing_presence(From, OldItem), ok; _ -> ok @@ -607,6 +580,7 @@ remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, + send_unsubscription_to_rosteritems(LUser, LServer), F = fun() -> lists:foreach(fun(R) -> mnesia:delete_object(R) @@ -615,6 +589,51 @@ remove_user(User, Server) -> end, mnesia:transaction(F). +%% For each contact with Subscription: +%% Both or From, send a "unsubscribed" presence stanza; +%% Both or To, send a "unsubscribe" presence stanza. +send_unsubscription_to_rosteritems(LUser, LServer) -> + RosterItems = get_user_roster([], {LUser, LServer}), + From = jlib:make_jid({LUser, LServer, ""}), + lists:foreach(fun(RosterItem) -> + send_unsubscribing_presence(From, RosterItem) + end, + RosterItems). + +%% @spec (From::jid(), Item::roster()) -> ok +send_unsubscribing_presence(From, Item) -> + IsTo = case Item#roster.subscription of + both -> true; + to -> true; + _ -> false + end, + IsFrom = case Item#roster.subscription of + both -> true; + from -> true; + _ -> false + end, + if IsTo -> + send_presence_type( + jlib:jid_remove_resource(From), + jlib:make_jid(Item#roster.jid), "unsubscribe"); + true -> ok + end, + if IsFrom -> + send_presence_type( + jlib:jid_remove_resource(From), + jlib:make_jid(Item#roster.jid), "unsubscribed"); + true -> ok + end, + ok. + +send_presence_type(From, To, Type) -> + ejabberd_router:route( + From, To, + {xmlelement, "presence", + [{"type", Type}], + []}). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% set_items(User, Server, SubEl) -> diff --git a/src/mod_roster_odbc.erl b/src/mod_roster_odbc.erl index 90483cf95..91651a97c 100644 --- a/src/mod_roster_odbc.erl +++ b/src/mod_roster_odbc.erl @@ -295,34 +295,7 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) -> push_item(User, LServer, To, Item), case Item#roster.subscription of remove -> - IsTo = case OldItem#roster.subscription of - both -> true; - to -> true; - _ -> false - end, - IsFrom = case OldItem#roster.subscription of - both -> true; - from -> true; - _ -> false - end, - if IsTo -> - ejabberd_router:route( - jlib:jid_remove_resource(From), - jlib:make_jid(OldItem#roster.jid), - {xmlelement, "presence", - [{"type", "unsubscribe"}], - []}); - true -> ok - end, - if IsFrom -> - ejabberd_router:route( - jlib:jid_remove_resource(From), - jlib:make_jid(OldItem#roster.jid), - {xmlelement, "presence", - [{"type", "unsubscribed"}], - []}); - true -> ok - end, + send_unsubscribing_presence(From, OldItem), ok; _ -> ok @@ -669,9 +642,55 @@ remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), + send_unsubscription_to_rosteritems(LUser, LServer), odbc_queries:del_user_roster_t(LServer, Username), ok. +%% For each contact with Subscription: +%% Both or From, send a "unsubscribed" presence stanza; +%% Both or To, send a "unsubscribe" presence stanza. +send_unsubscription_to_rosteritems(LUser, LServer) -> + RosterItems = get_user_roster([], {LUser, LServer}), + From = jlib:make_jid({LUser, LServer, ""}), + lists:foreach(fun(RosterItem) -> + send_unsubscribing_presence(From, RosterItem) + end, + RosterItems). + +%% @spec (From::jid(), Item::roster()) -> ok +send_unsubscribing_presence(From, Item) -> + IsTo = case Item#roster.subscription of + both -> true; + to -> true; + _ -> false + end, + IsFrom = case Item#roster.subscription of + both -> true; + from -> true; + _ -> false + end, + if IsTo -> + send_presence_type( + jlib:jid_remove_resource(From), + jlib:make_jid(Item#roster.jid), "unsubscribe"); + true -> ok + end, + if IsFrom -> + send_presence_type( + jlib:jid_remove_resource(From), + jlib:make_jid(Item#roster.jid), "unsubscribed"); + true -> ok + end, + ok. + +send_presence_type(From, To, Type) -> + ejabberd_router:route( + From, To, + {xmlelement, "presence", + [{"type", Type}], + []}). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% set_items(User, Server, SubEl) ->