# HG changeset patch
# User Kim Alvefur <zash@zash.se>
# Date 1731028260 -3600
# Node ID 3b357ab6b6eb24725405ab5ce725427df38f43d7
# Parent  84ee435f284eca4cc68a016b9cb6bd53a797d3b8
util.pubsub: Add method returning subset of config as metadata

Allows granting read only access to other sets of users using a separate
access control capability, which makes sense as some properties may be
intended to be public but read-only.

diff -r 84ee435f284e -r 3b357ab6b6eb spec/util_pubsub_spec.lua
--- a/spec/util_pubsub_spec.lua	Fri Nov 08 10:31:25 2024 +0000
+++ b/spec/util_pubsub_spec.lua	Fri Nov 08 02:11:00 2024 +0100
@@ -605,4 +605,14 @@
 		end);
 
 	end)
+
+	describe("metadata", function()
+		it("works", function()
+			local service = pubsub.new { metadata_subset = { "title" } };
+			assert.truthy(service:create("node", true, { title = "Hello", secret = "hidden" }))
+			local ok, meta = service:get_node_metadata("node", "nobody");
+			assert.truthy(ok, meta);
+			assert.same({ title = "Hello" }, meta);
+		end)
+	end);
 end);
diff -r 84ee435f284e -r 3b357ab6b6eb util/pubsub.lua
--- a/util/pubsub.lua	Fri Nov 08 10:31:25 2024 +0000
+++ b/util/pubsub.lua	Fri Nov 08 02:11:00 2024 +0100
@@ -11,6 +11,7 @@
 	itemcheck = function () return true; end;
 	get_affiliation = function () end;
 	normalize_jid = function (jid) return jid; end;
+	metadata_subset = {};
 	capabilities = {
 		outcast = {
 			create = false;
@@ -45,6 +46,7 @@
 			get_subscription = true;
 			get_subscriptions = true;
 			get_items = false;
+			get_metadata = true;
 
 			subscribe_other = false;
 			unsubscribe_other = false;
@@ -67,6 +69,7 @@
 			get_subscription = true;
 			get_subscriptions = true;
 			get_items = true;
+			get_metadata = true;
 
 			subscribe_other = false;
 			unsubscribe_other = false;
@@ -90,6 +93,7 @@
 			get_subscription = true;
 			get_subscriptions = true;
 			get_items = true;
+			get_metadata = true;
 
 			subscribe_other = false;
 			unsubscribe_other = false;
@@ -115,6 +119,7 @@
 			get_subscription = true;
 			get_subscriptions = true;
 			get_items = true;
+			get_metadata = true;
 
 
 			subscribe_other = true;
@@ -872,6 +877,20 @@
 	return true, config_table;
 end
 
+function service:get_node_metadata(node, actor)
+	if not self:may(node, actor, "get_metadata") then
+		return false, "forbidden";
+	end
+
+	local ok, config = self:get_node_config(node, true);
+	if not ok then return ok, config; end
+	local meta = {};
+	for _, k in ipairs(self.config.metadata_subset) do
+		meta[k] = config[k];
+	end
+	return true, meta;
+end
+
 return {
 	new = new;
 };