mod_pep: Implement 'roster' (group) access_model
authorKim Alvefur <zash@zash.se>
Sun, 03 Dec 2023 23:19:27 +0100
changeset 13490 fdd1438d9ef7
parent 13489 3bdbaba15c00
child 13493 ae65f199f408
mod_pep: Implement 'roster' (group) access_model Allows e.g. restricting your vcard4 to only family or similar. Notes: This does not include roster groups in the configuration form, so the client will have to get them from the actual roster.
CHANGES
plugins/mod_pep.lua
plugins/mod_pubsub/pubsub.lib.lua
util/pubsub.lua
--- a/CHANGES	Fri Apr 26 10:37:20 2024 +0100
+++ b/CHANGES	Sun Dec 03 23:19:27 2023 +0100
@@ -67,6 +67,7 @@
 - When mod_smacks is enabled, s2s connections not responding to ack requests are closed.
 - Arguments to `prosodyctl shell` that start with ':' are now turned into method calls
 - Support for Type=notify and notify-reload systemd service type added
+- Support for the roster *group* access_model in mod_pep
 
 ## Removed
 
--- a/plugins/mod_pep.lua	Fri Apr 26 10:37:20 2024 +0100
+++ b/plugins/mod_pep.lua	Sun Dec 03 23:19:27 2023 +0100
@@ -5,7 +5,7 @@
 local set_new = require "prosody.util.set".new;
 local st = require "prosody.util.stanza";
 local calculate_hash = require "prosody.util.caps".calculate_hash;
-local is_contact_subscribed = require "prosody.core.rostermanager".is_contact_subscribed;
+local rostermanager = require "prosody.core.rostermanager";
 local cache = require "prosody.util.cache";
 local set = require "prosody.util.set";
 local new_id = require "prosody.util.id".medium;
@@ -16,6 +16,8 @@
 local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event";
 local xmlns_pubsub_owner = "http://jabber.org/protocol/pubsub#owner";
 
+local is_contact_subscribed = rostermanager.is_contact_subscribed;
+
 local lib_pubsub = module:require "pubsub";
 
 local empty_set = set_new();
@@ -84,6 +86,7 @@
 		return false;
 	end
 	if new_config["access_model"] ~= "presence"
+	and new_config["access_model"] ~= "roster"
 	and new_config["access_model"] ~= "whitelist"
 	and new_config["access_model"] ~= "open" then
 		return false;
@@ -256,6 +259,20 @@
 				end
 				return "outcast";
 			end;
+			roster = function (jid, node)
+				jid = jid_bare(jid);
+				local allowed_groups = set_new(node.config.roster_groups_allowed);
+				local roster = rostermanager.load_roster(username, host);
+				if not roster[jid] then
+					return "outcast";
+				end
+				for group in pairs(roster[jid].groups) do
+					if allowed_groups:contains(group) then
+						return "member";
+					end
+				end
+				return "outcast";
+			end;
 		};
 
 		jid = user_bare;
--- a/plugins/mod_pubsub/pubsub.lib.lua	Fri Apr 26 10:37:20 2024 +0100
+++ b/plugins/mod_pubsub/pubsub.lib.lua	Sun Dec 03 23:19:27 2023 +0100
@@ -110,6 +110,12 @@
 		};
 	};
 	{
+		type = "list-multi"; -- TODO some way to inject options
+		name = "roster_groups_allowed";
+		var = "pubsub#roster_groups_allowed";
+		label = "Roster groups allowed to subscribe";
+	};
+	{
 		type = "list-single";
 		name = "publish_model";
 		var = "pubsub#publish_model";
--- a/util/pubsub.lua	Fri Apr 26 10:37:20 2024 +0100
+++ b/util/pubsub.lua	Sun Dec 03 23:19:27 2023 +0100
@@ -263,7 +263,7 @@
 	if self.config.access_models then
 		local check = self.config.access_models[access_model];
 		if check then
-			local aff = check(actor);
+			local aff = check(actor, node_obj);
 			if aff then
 				return aff;
 			end