mod_pubsub,mod_pep: Implement 'send_last_published_item' option #1436
authorKim Alvefur <zash@zash.se>
Tue, 19 Oct 2021 18:11:50 +0200
changeset 11858 b605cbd5f13b
parent 11857 ae5ac9830add
child 11859 8890eaa69446
mod_pubsub,mod_pep: Implement 'send_last_published_item' option #1436 Default left as 'never' in mod_pubsub to preserve the previous behavior. Unclear if this is desirable, but can always be changed later. In mod_pep this allows turning off the automatic resending of most recent item.
plugins/mod_pep.lua
plugins/mod_pubsub/pubsub.lib.lua
spec/scansion/pubsub_config.scs
spec/scansion/pubsub_max_items.scs
spec/scansion/pubsub_multi_items.scs
spec/scansion/pubsub_preconditions.scs
spec/scansion/pubsub_resend_on_sub.scs
util/pubsub.lua
--- a/plugins/mod_pep.lua	Tue Oct 19 16:37:32 2021 +0200
+++ b/plugins/mod_pep.lua	Tue Oct 19 18:11:50 2021 +0200
@@ -187,6 +187,7 @@
 			["max_items"] = 1;
 			["persist_items"] = true;
 			["access_model"] = "presence";
+			["send_last_published_item"] = "on_sub_and_presence";
 		};
 
 		autocreate_on_publish = true;
@@ -260,6 +261,8 @@
 end
 
 local function resend_last_item(jid, node, service)
+	local ok, config = service:get_node_config(node, true);
+	if ok and config.send_last_published_item ~= "on_sub_and_presence" then return end
 	local ok, id, item = service:get_last_item(node, jid);
 	if not (ok and id) then return; end
 	service.config.broadcaster("items", node, { [jid] = true }, item);
--- a/plugins/mod_pubsub/pubsub.lib.lua	Tue Oct 19 16:37:32 2021 +0200
+++ b/plugins/mod_pubsub/pubsub.lib.lua	Tue Oct 19 18:11:50 2021 +0200
@@ -120,6 +120,12 @@
 		};
 	};
 	{
+		type = "list-single";
+		var = "pubsub#send_last_published_item";
+		name = "send_last_published_item";
+		options = { "never"; "on_sub"; "on_sub_and_presence" };
+	};
+	{
 		type = "boolean";
 		value = true;
 		label = "Whether to deliver event notifications";
@@ -253,6 +259,10 @@
 		supported_features:add("access-"..service.node_defaults.access_model);
 	end
 
+	if service.node_defaults.send_last_published_item ~= "never" then
+		supported_features:add("last-published");
+	end
+
 	if rawget(service.config, "itemstore") and rawget(service.config, "nodestore") then
 		supported_features:add("persistent-items");
 	end
@@ -530,6 +540,12 @@
 		reply = pubsub_error_reply(stanza, ret);
 	end
 	origin.send(reply);
+	local ok, config = service:get_node_config(node, true);
+	if ok and config.send_last_published_item ~= "never" then
+		local ok, id, item = service:get_last_item(node, jid);
+		if not (ok and id) then return; end
+		service.config.broadcaster("items", node, { [jid] = true }, item);
+	end
 end
 
 function handlers.set_unsubscribe(origin, stanza, unsubscribe, service)
--- a/spec/scansion/pubsub_config.scs	Tue Oct 19 16:37:32 2021 +0200
+++ b/spec/scansion/pubsub_config.scs	Tue Oct 19 18:11:50 2021 +0200
@@ -84,6 +84,18 @@
 						</option>
 						<value>publishers</value>
 					</field>
+					<field type='list-single' var='pubsub#send_last_published_item'>
+						<option label='never'>
+							<value>never</value>
+						</option>
+						<option label='on_sub'>
+							<value>on_sub</value>
+						</option>
+						<option label='on_sub_and_presence'>
+							<value>on_sub_and_presence</value>
+						</option>
+						<value>on_sub_and_presence</value>
+					</field>
 					<field var="pubsub#deliver_notifications" label="Whether to deliver event notifications" type="boolean">
 						<value>1</value>
 					</field>
@@ -160,6 +172,9 @@
 						</option>
 						<value>publishers</value>
 					</field>
+					<field type='list-single' var='pubsub#send_last_published_item'>
+						<value>never</value>
+					</field>
 					<field var="pubsub#deliver_notifications" type="boolean" label="Whether to deliver event notifications">
 						<value>1</value>
 					</field>
--- a/spec/scansion/pubsub_max_items.scs	Tue Oct 19 16:37:32 2021 +0200
+++ b/spec/scansion/pubsub_max_items.scs	Tue Oct 19 18:11:50 2021 +0200
@@ -79,6 +79,18 @@
 		  </option>
 		  <value>publishers</value>
 		</field>
+		<field type='list-single' var='pubsub#send_last_published_item'>
+			<option label='never'>
+				<value>never</value>
+			</option>
+			<option label='on_sub'>
+				<value>on_sub</value>
+			</option>
+			<option label='on_sub_and_presence'>
+				<value>on_sub_and_presence</value>
+			</option>
+			<value>never</value>
+		</field>
 		<field var="pubsub#deliver_notifications" label="Whether to deliver event notifications" type="boolean">
 		  <value>1</value>
 		</field>
--- a/spec/scansion/pubsub_multi_items.scs	Tue Oct 19 16:37:32 2021 +0200
+++ b/spec/scansion/pubsub_multi_items.scs	Tue Oct 19 18:11:50 2021 +0200
@@ -79,6 +79,18 @@
 		  </option>
 		  <value>publishers</value>
 		</field>
+		<field type='list-single' var='pubsub#send_last_published_item'>
+			<option label='never'>
+				<value>never</value>
+			</option>
+			<option label='on_sub'>
+				<value>on_sub</value>
+			</option>
+			<option label='on_sub_and_presence'>
+				<value>on_sub_and_presence</value>
+			</option>
+			<value>never</value>
+		</field>
 		<field var="pubsub#deliver_notifications" label="Whether to deliver event notifications" type="boolean">
 		  <value>1</value>
 		</field>
--- a/spec/scansion/pubsub_preconditions.scs	Tue Oct 19 16:37:32 2021 +0200
+++ b/spec/scansion/pubsub_preconditions.scs	Tue Oct 19 18:11:50 2021 +0200
@@ -83,6 +83,18 @@
 						</option>
 						<value>publishers</value>
 					</field>
+					<field type='list-single' var='pubsub#send_last_published_item'>
+						<option label='never'>
+							<value>never</value>
+						</option>
+						<option label='on_sub'>
+							<value>on_sub</value>
+						</option>
+						<option label='on_sub_and_presence'>
+							<value>on_sub_and_presence</value>
+						</option>
+						<value>on_sub_and_presence</value>
+					</field>
 					<field var="pubsub#deliver_notifications" label="Whether to deliver event notifications" type="boolean">
 						<value>1</value>
 					</field>
@@ -159,6 +171,9 @@
 						</option>
 						<value>publishers</value>
 					</field>
+					<field type='list-single' var='pubsub#send_last_published_item'>
+						<value>never</value>
+					</field>
 					<field var="pubsub#deliver_notifications" type="boolean" label="Whether to deliver event notifications">
 						<value>1</value>
 					</field>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/scansion/pubsub_resend_on_sub.scs	Tue Oct 19 18:11:50 2021 +0200
@@ -0,0 +1,152 @@
+# Pubsub: Send last item on subscribe #1436
+
+[Client] Romeo
+	jid: admin@localhost
+	password: password
+
+// admin@localhost is assumed to have node creation privileges
+
+[Client] Juliet
+	jid: juliet@localhost
+	password: password
+
+---------
+
+Romeo connects
+
+Romeo sends:
+	<iq type="set" to="pubsub.localhost" id='create1'>
+		<pubsub xmlns="http://jabber.org/protocol/pubsub">
+			<create node="princely_musings"/>
+		</pubsub>
+	</iq>
+
+Romeo receives:
+	<iq type="result" id='create1'/>
+
+Romeo sends:
+	<iq to="pubsub.localhost" id="config-never" type="set">
+		<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
+			<configure node="princely_musings">
+				<x xmlns="jabber:x:data" type="submit">
+					<field var="FORM_TYPE" type="hidden">
+						<value>http://jabber.org/protocol/pubsub#node_config</value>
+					</field>
+					<field type='list-single' var='pubsub#send_last_published_item'>
+						<value>never</value>
+					</field>
+				</x>
+			</configure>
+		</pubsub>
+	</iq>
+
+Romeo receives:
+	<iq from="pubsub.localhost" id="config-never" type="result"/>
+
+Romeo sends:
+	<iq type="set" to="pubsub.localhost" id='pub1'>
+		<pubsub xmlns="http://jabber.org/protocol/pubsub">
+			<publish node="princely_musings">
+				<item id="current">
+					<entry xmlns="http://www.w3.org/2005/Atom">
+						<title>Soliloquy</title>
+						<summary>Lorem ipsum dolor sit amet</summary>
+					</entry>
+				</item>
+			</publish>
+		</pubsub>
+	</iq>
+
+Romeo receives:
+	<iq type="result" id='pub1'/>
+
+Juliet connects
+
+Juliet sends:
+	<iq type="set" to="pubsub.localhost" id='sub1'>
+		<pubsub xmlns="http://jabber.org/protocol/pubsub">
+			<subscribe node="princely_musings" jid="${Juliet's full JID}"/>
+		</pubsub>
+	</iq>
+
+Juliet receives:
+	<iq type="result" id='sub1'/>
+
+Juliet sends:
+	<iq type="set" to="pubsub.localhost" id='unsub1'>
+		<pubsub xmlns="http://jabber.org/protocol/pubsub">
+			<unsubscribe node="princely_musings" jid="${Juliet's full JID}"/>
+		</pubsub>
+	</iq>
+
+Juliet receives:
+	<iq type="result" id='unsub1'/>
+
+Romeo sends:
+	<iq to="pubsub.localhost" id="config-on_sub" type="set">
+		<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
+			<configure node="princely_musings">
+				<x xmlns="jabber:x:data" type="submit">
+					<field var="FORM_TYPE" type="hidden">
+						<value>http://jabber.org/protocol/pubsub#node_config</value>
+					</field>
+					<field type='list-single' var='pubsub#send_last_published_item'>
+						<value>on_sub</value>
+					</field>
+				</x>
+			</configure>
+		</pubsub>
+	</iq>
+
+Romeo receives:
+	<iq from="pubsub.localhost" id="config-on_sub" type="result"/>
+
+Juliet sends:
+	<iq type="set" to="pubsub.localhost" id='sub2'>
+		<pubsub xmlns="http://jabber.org/protocol/pubsub">
+			<subscribe node="princely_musings" jid="${Juliet's full JID}"/>
+		</pubsub>
+	</iq>
+
+Juliet receives:
+	<iq type="result" id='sub2'/>
+
+Juliet receives:
+	<message type="headline" from="pubsub.localhost">
+		<event xmlns="http://jabber.org/protocol/pubsub#event">
+			<items node="princely_musings">
+				<item id="current" publisher="${Romeo's JID}">
+					<entry xmlns="http://www.w3.org/2005/Atom">
+						<title>Soliloquy</title>
+						<summary>Lorem ipsum dolor sit amet</summary>
+					</entry>
+				</item>
+			</items>
+		</event>
+	</message>
+
+Juliet sends:
+	<iq type="set" to="pubsub.localhost" id='unsub2'>
+		<pubsub xmlns="http://jabber.org/protocol/pubsub">
+			<unsubscribe node="princely_musings" jid="${Juliet's full JID}"/>
+		</pubsub>
+	</iq>
+
+Juliet receives:
+	<iq type="result" id='unsub2'/>
+
+Juliet disconnects
+
+Romeo sends:
+	<iq type="set" to="pubsub.localhost" id='del1'>
+		<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
+			<delete node="princely_musings"/>
+		</pubsub>
+	</iq>
+
+Romeo receives:
+	<iq type="result" id='del1'/>
+
+Romeo disconnects
+
+// vim: syntax=xml:
--- a/util/pubsub.lua	Tue Oct 19 16:37:32 2021 +0200
+++ b/util/pubsub.lua	Tue Oct 19 18:11:50 2021 +0200
@@ -136,6 +136,7 @@
 	["max_items"] = 20;
 	["access_model"] = "open";
 	["publish_model"] = "publishers";
+	["send_last_published_item"] = "never";
 };
 local default_node_config_mt = { __index = default_node_config };