From b0e749eca5e4a8c3b99924b0c58d9dfac7c9761f Mon Sep 17 00:00:00 2001 From: Badlop Date: Mon, 16 Feb 2009 14:49:20 +0000 Subject: [PATCH] * 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: 1877 --- ChangeLog | 6 ++++ src/mod_roster.erl | 75 ++++++++++++++++++++++++++--------------- src/mod_roster_odbc.erl | 75 ++++++++++++++++++++++++++--------------- 3 files changed, 100 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 269271f99..14ee02e98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-02-16 Badlop + + * src/mod_roster.erl: When account is deleted, cancel presence + subscription for all roster items (EJAB-790) + * src/mod_roster_odbc.erl: Likewise + 2009-02-14 Badlop * src/web/ejabberd_http_poll.erl: Allow configuration of session diff --git a/src/mod_roster.erl b/src/mod_roster.erl index a1639c55f..9cb23c2a4 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -233,34 +233,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 @@ -570,6 +543,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) @@ -578,6 +552,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 ee4e326a7..0a091a532 100644 --- a/src/mod_roster_odbc.erl +++ b/src/mod_roster_odbc.erl @@ -274,34 +274,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 @@ -631,9 +604,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) ->