aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mod_pubsub/mod_pubsub.erl76
-rw-r--r--src/mod_pubsub/node.template1
-rw-r--r--src/mod_pubsub/node_buddy.erl1
-rw-r--r--src/mod_pubsub/node_club.erl1
-rw-r--r--src/mod_pubsub/node_dispatch.erl1
-rw-r--r--src/mod_pubsub/node_flat.erl1
-rw-r--r--src/mod_pubsub/node_flat_odbc.erl1
-rw-r--r--src/mod_pubsub/node_hometree.erl1
-rw-r--r--src/mod_pubsub/node_hometree_odbc.erl1
-rw-r--r--src/mod_pubsub/node_mb.erl1
-rw-r--r--src/mod_pubsub/node_pep.erl1
-rw-r--r--src/mod_pubsub/node_pep_odbc.erl1
-rw-r--r--src/mod_pubsub/node_private.erl1
-rw-r--r--src/mod_pubsub/node_public.erl1
14 files changed, 89 insertions, 0 deletions
diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl
index 592d11d35..f29f6a040 100644
--- a/src/mod_pubsub/mod_pubsub.erl
+++ b/src/mod_pubsub/mod_pubsub.erl
@@ -62,6 +62,7 @@
-export([presence_probe/3,
in_subscription/6,
out_subscription/4,
+ on_user_offline/3,
remove_user/2,
feature_check_packet/6,
disco_local_identity/5,
@@ -197,6 +198,7 @@ init([ServerHost, Opts]) ->
ets:insert(gen_mod:get_module_proc(ServerHost, config), {pep_mapping, PepMapping}),
ets:insert(gen_mod:get_module_proc(ServerHost, config), {ignore_pep_from_offline, PepOffline}),
ets:insert(gen_mod:get_module_proc(ServerHost, config), {host, Host}),
+ ejabberd_hooks:add(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75),
ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
@@ -864,6 +866,7 @@ terminate(_Reason, #state{host = Host,
false ->
ok
end,
+ ejabberd_hooks:delete(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75),
ejabberd_hooks:delete(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
ejabberd_hooks:delete(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
@@ -3313,6 +3316,7 @@ get_configure_xfields(_Type, Options, Lang, Groups) ->
?LISTM_CONFIG_FIELD("Roster groups allowed to subscribe", roster_groups_allowed, Groups),
?ALIST_CONFIG_FIELD("Specify the publisher model", publish_model,
[publishers, subscribers, open]),
+ ?BOOL_CONFIG_FIELD("Purge all items when the relevant publisher goes offline", purge_offline),
?ALIST_CONFIG_FIELD("Specify the event message type", notification_type,
[headline, normal]),
?INTEGER_CONFIG_FIELD("Max payload size in bytes", max_payload_size),
@@ -3456,6 +3460,8 @@ set_xoption(Host, [{"pubsub#send_last_published_item", [Val]} | Opts], NewOpts)
?SET_ALIST_XOPT(send_last_published_item, Val, [never, on_sub, on_sub_and_presence]);
set_xoption(Host, [{"pubsub#presence_based_delivery", [Val]} | Opts], NewOpts) ->
?SET_BOOL_XOPT(presence_based_delivery, Val);
+set_xoption(Host, [{"pubsub#purge_offline", [Val]} | Opts], NewOpts) ->
+ ?SET_BOOL_XOPT(purge_offline, Val);
set_xoption(Host, [{"pubsub#title", Value} | Opts], NewOpts) ->
?SET_STRING_XOPT(title, Value);
set_xoption(Host, [{"pubsub#type", Value} | Opts], NewOpts) ->
@@ -3789,3 +3795,73 @@ is_feature_supported({xmlelement, "presence", _, Els}, Feature) ->
nothing -> false;
Caps -> lists:member(Feature ++ "+notify", mod_caps:get_features(Caps))
end.
+
+on_user_offline(_, JID, _) ->
+ {User, Server, Resource} = jlib:jid_tolower(JID),
+ case ejabberd_sm:get_user_resources(User, Server) of
+ [] -> purge_offline({User, Server, Resource});
+ _ -> true
+ end.
+
+purge_offline({User, Server, _} = LJID) ->
+ Host = host(element(2, LJID)),
+ Plugins = plugins(Host),
+ Result =
+ lists:foldl(
+ fun(Type, {Status, Acc}) ->
+ case lists:member("retrieve-affiliations", features(Type)) of
+ false ->
+ {{error, extended_error('feature-not-implemented', unsupported, "retrieve-affiliations")}, Acc};
+ true ->
+ {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, LJID]),
+ {Status, [Affiliations|Acc]}
+ end
+ end,
+ {ok, []}, Plugins),
+ case Result of
+ {ok, Affiliations} ->
+ lists:foreach(
+ fun({#pubsub_node{nodeid = {_, NodeId}, options = Options, type = Type, id = NodeIdx}, Affiliation})
+ when Affiliation == 'owner' orelse Affiliation == 'publisher' ->
+ Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
+ node_call(Type, get_items, [NodeId, service_jid(Host)])
+ end,
+ case transaction(Host, NodeId, Action, sync_dirty) of
+ {result, {_, []}} -> true;
+ {result, {_, Items}} ->
+ Features = features(Type),
+ case
+ {lists:member("retract-items", Features),
+ lists:member("persistent-items", Features),
+ get_option(Options, persist_items),
+ get_option(Options, purge_offline)}
+ of
+ {true, true, true, true} ->
+ ForceNotify = get_option(Options, notify_retract),
+ lists:foreach(
+ fun(#pubsub_item{itemid = {ItemId, _}, modification = {_, Modification}}) ->
+ case Modification of
+ {User, Server, _} ->
+ delete_item(Host, NodeId, LJID, ItemId, ForceNotify);
+ _ ->
+ true
+ end;
+ (_) ->
+ true
+ end,
+ Items);
+ _ ->
+ true
+ end;
+ Error ->
+ Error
+ end
+ end;
+ (_) ->
+ true
+ end, lists:usort(lists:flatten(Affiliations)));
+ {Error, _} ->
+ ?DEBUG("on_user_offline ~p", [Error])
+ end,
+ ok.
+
diff --git a/src/mod_pubsub/node.template b/src/mod_pubsub/node.template
index 03bb03a0c..0c5555131 100644
--- a/src/mod_pubsub/node.template
+++ b/src/mod_pubsub/node.template
@@ -82,6 +82,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_buddy.erl b/src/mod_pubsub/node_buddy.erl
index f7608a92b..315dd01e2 100644
--- a/src/mod_pubsub/node_buddy.erl
+++ b/src/mod_pubsub/node_buddy.erl
@@ -85,6 +85,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_club.erl b/src/mod_pubsub/node_club.erl
index d76d73f64..6e71c5b15 100644
--- a/src/mod_pubsub/node_club.erl
+++ b/src/mod_pubsub/node_club.erl
@@ -85,6 +85,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_dispatch.erl b/src/mod_pubsub/node_dispatch.erl
index 87b2caec8..ed6bf85ae 100644
--- a/src/mod_pubsub/node_dispatch.erl
+++ b/src/mod_pubsub/node_dispatch.erl
@@ -83,6 +83,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_flat.erl b/src/mod_pubsub/node_flat.erl
index f3d7d4bce..5b0bcde06 100644
--- a/src/mod_pubsub/node_flat.erl
+++ b/src/mod_pubsub/node_flat.erl
@@ -76,6 +76,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_flat_odbc.erl b/src/mod_pubsub/node_flat_odbc.erl
index b3e331349..a255e9b0d 100644
--- a/src/mod_pubsub/node_flat_odbc.erl
+++ b/src/mod_pubsub/node_flat_odbc.erl
@@ -81,6 +81,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_hometree.erl b/src/mod_pubsub/node_hometree.erl
index 740b2f5ff..69deef211 100644
--- a/src/mod_pubsub/node_hometree.erl
+++ b/src/mod_pubsub/node_hometree.erl
@@ -139,6 +139,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_hometree_odbc.erl b/src/mod_pubsub/node_hometree_odbc.erl
index 8f024f6b7..a3618b78c 100644
--- a/src/mod_pubsub/node_hometree_odbc.erl
+++ b/src/mod_pubsub/node_hometree_odbc.erl
@@ -143,6 +143,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_mb.erl b/src/mod_pubsub/node_mb.erl
index ef64418aa..4a8be3f0b 100644
--- a/src/mod_pubsub/node_mb.erl
+++ b/src/mod_pubsub/node_mb.erl
@@ -88,6 +88,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, false},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_pep.erl b/src/mod_pubsub/node_pep.erl
index 103fffc49..0f406296d 100644
--- a/src/mod_pubsub/node_pep.erl
+++ b/src/mod_pubsub/node_pep.erl
@@ -83,6 +83,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, false},
+ {purge_offline, false},
{persist_items, false},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_pep_odbc.erl b/src/mod_pubsub/node_pep_odbc.erl
index f39b4e11f..9f0071bbc 100644
--- a/src/mod_pubsub/node_pep_odbc.erl
+++ b/src/mod_pubsub/node_pep_odbc.erl
@@ -91,6 +91,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, false},
+ {purge_offline, false},
{persist_items, false},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_private.erl b/src/mod_pubsub/node_private.erl
index 4e3cb0bad..1ba0bc3d5 100644
--- a/src/mod_pubsub/node_private.erl
+++ b/src/mod_pubsub/node_private.erl
@@ -85,6 +85,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
diff --git a/src/mod_pubsub/node_public.erl b/src/mod_pubsub/node_public.erl
index 6013c0ba4..c8895dd15 100644
--- a/src/mod_pubsub/node_public.erl
+++ b/src/mod_pubsub/node_public.erl
@@ -85,6 +85,7 @@ options() ->
{notify_config, false},
{notify_delete, false},
{notify_retract, true},
+ {purge_offline, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},