mod_storage_xep0227: Allow overriding the input/output layer for XEP-0227 data
authorMatthew Wild <mwild1@gmail.com>
Mon, 10 Jan 2022 15:47:59 +0000
changeset 12177 270047afa6af
parent 12176 2515033c2a74
child 12178 a38b7cb5fd6a
mod_storage_xep0227: Allow overriding the input/output layer for XEP-0227 data This can (and will) be used to support in-memory import/export functions.
plugins/mod_storage_xep0227.lua
--- a/plugins/mod_storage_xep0227.lua	Mon Jan 10 00:13:17 2022 +0100
+++ b/plugins/mod_storage_xep0227.lua	Mon Jan 10 15:47:59 2022 +0000
@@ -20,7 +20,7 @@
 
 local lfs = require "lfs";
 
-local function getXml(user, host)
+local function default_get_user_xml(self, user, host)
 	local jid = user.."@"..host;
 	local path = paths.join(prosody.paths.data, jid..".xml");
 	local f, err = io_open(path);
@@ -33,7 +33,7 @@
 	f:close();
 	return parse_xml_real(s);
 end
-local function setXml(user, host, xml)
+local function default_set_user_xml(user, host, xml)
 	local jid = user.."@"..host;
 	local path = paths.join(prosody.paths.data, jid..".xml");
 	local f, err = io_open(path, "w");
@@ -84,7 +84,7 @@
 
 handlers.accounts = {
 	get = function(self, user)
-		user = getUserElement(getXml(user, self.host));
+		user = getUserElement(self:_get_user_xml(user, self.host));
 		local scram_credentials = user and user:get_child_with_attr(
 			"scram-credentials", "urn:xmpp:pie:0#scram",
 			"mechanism", "SCRAM-"..scram_hash_name
@@ -110,10 +110,10 @@
 	end;
 	set = function(self, user, data)
 		if not data then
-			return setXml(user, self.host, nil);
+			return self:_set_user_xml(user, self.host, nil);
 		end
 
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		if not xml then xml = createOuterXml(user, self.host); end
 		local usere = getUserElement(xml);
 
@@ -141,12 +141,12 @@
 			usere.attr[extended..property] = data[property];
 		end
 
-		return setXml(user, self.host, xml);
+		return self:_set_user_xml(user, self.host, xml);
 	end;
 };
 handlers.vcard = {
 	get = function(self, user)
-		user = getUserElement(getXml(user, self.host));
+		user = getUserElement(self:_get_user_xml(user, self.host));
 		if user then
 			local vcard = user:get_child("vCard", 'vcard-temp');
 			if vcard then
@@ -155,7 +155,7 @@
 		end
 	end;
 	set = function(self, user, data)
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local usere = xml and getUserElement(xml);
 		if usere then
 			usere:remove_children("vCard", "vcard-temp");
@@ -165,14 +165,14 @@
 			end
 			local vcard = st.deserialize(data);
 			usere:add_child(vcard);
-			return setXml(user, self.host, xml);
+			return self:_set_user_xml(user, self.host, xml);
 		end
 		return true;
 	end;
 };
 handlers.private = {
 	get = function(self, user)
-		user = getUserElement(getXml(user, self.host));
+		user = getUserElement(self:_get_user_xml(user, self.host));
 		if user then
 			local private = user:get_child("query", "jabber:iq:private");
 			if private then
@@ -185,7 +185,7 @@
 		end
 	end;
 	set = function(self, user, data)
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local usere = xml and getUserElement(xml);
 		if usere then
 			usere:remove_children("query", "jabber:iq:private");
@@ -196,7 +196,7 @@
 				end
 				usere:add_child(private);
 			end
-			return setXml(user, self.host, xml);
+			return self:_set_user_xml(user, self.host, xml);
 		end
 		return true;
 	end;
@@ -204,7 +204,7 @@
 
 handlers.roster = {
 	get = function(self, user)
-		user = getUserElement(getXml(user, self.host));
+		user = getUserElement(self:_get_user_xml(user, self.host));
 		if user then
 			local roster = user:get_child("query", "jabber:iq:roster");
 			if roster then
@@ -234,7 +234,7 @@
 		end
 	end;
 	set = function(self, user, data)
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local usere = xml and getUserElement(xml);
 		if usere then
 			usere:remove_children("query", "jabber:iq:roster");
@@ -267,7 +267,7 @@
 					end
 				end
 			end
-			return setXml(user, self.host, xml);
+			return self:_set_user_xml(user, self.host, xml);
 		end
 		return true;
 	end;
@@ -278,7 +278,7 @@
 local lib_pubsub = module:require "pubsub";
 handlers.pep = {
 	get = function (self, user)
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local user_el = xml and getUserElement(xml);
 		if not user_el then
 			return nil;
@@ -342,7 +342,7 @@
 		return nodes;
 	end;
 	set = function(self, user, data)
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local user_el = xml and getUserElement(xml);
 		if not user_el then
 			return true;
@@ -380,7 +380,7 @@
 
 		user_el:add_child(owner_el);
 
-		return setXml(user, self.host, xml);
+		return self:_set_user_xml(user, self.host, xml);
 	end;
 };
 
@@ -410,7 +410,7 @@
 	find = function (self, user, query)
 		-- query keys: limit, reverse, key (id)
 
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local user_el = xml and getUserElement(xml);
 		if not user_el then
 			return nil, "no 227 user element found";
@@ -465,7 +465,7 @@
 		end;
 	end;
 	append = function (self, user, key, payload, when, with) --luacheck: ignore 212/when 212/with 212/key
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local user_el = xml and getUserElement(xml);
 		if not user_el then
 			return true;
@@ -500,12 +500,12 @@
 			:add_child(payload);
 		node_items_el:add_child(item_el);
 
-		return setXml(user, self.host, xml);
+		return self:_set_user_xml(user, self.host, xml);
 	end;
 	delete = function (self, user, query)
 		-- query keys: limit, reverse, key (id)
 
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local user_el = xml and getUserElement(xml);
 		if not user_el then
 			return nil, "no 227 user element found";
@@ -558,7 +558,7 @@
 			end
 			return item_el;
 		end);
-		return setXml(user, self.host, xml);
+		return self:_set_user_xml(user, self.host, xml);
 	end;
 };
 
@@ -568,7 +568,7 @@
 	find = function (self, user, query)
 		assert(query == nil, "XEP-0313 queries are not supported on XEP-0227 files");
 
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local user_el = xml and getUserElement(xml);
 		if not user_el then
 			return nil, "no 227 user element found";
@@ -599,7 +599,7 @@
 		end;
 	end;
 	append = function (self, user, key, payload, when, with) --luacheck: ignore 212/when 212/with 212/key
-		local xml = getXml(user, self.host);
+		local xml = self:_get_user_xml(user, self.host);
 		local user_el = xml and getUserElement(xml);
 		if not user_el then
 			return true;
@@ -624,7 +624,7 @@
 		-- Append item to archive_el
 		archive_el:add_child(result_el);
 
-		return setXml(user, self.host, xml);
+		return self:_set_user_xml(user, self.host, xml);
 	end;
 };
 
@@ -653,11 +653,33 @@
 		handler = handlers.pep_;
 	end
 	if not handler then return nil, "unsupported-datastore"; end
-	local instance = setmetatable({ host = module.host; datastore = datastore; users = users; }, { __index = handler });
+	local instance = setmetatable({
+			host = module.host;
+			datastore = datastore;
+			users = users;
+			_get_user_xml = assert(default_get_user_xml);
+			_set_user_xml = default_set_user_xml;
+		}, {
+			__index = handler;
+		}
+	);
 	if instance.init then instance:init(); end
 	return instance;
 end
 
+-- Custom API that allows some configuration
+function driver:open_xep0227(datastore, typ, options)
+	local instance, err = self:open(datastore, typ);
+	if not instance then
+		return instance, err;
+	end
+	if options then
+		instance._set_user_xml = assert(options.set_user_xml);
+		instance._get_user_xml = assert(options.get_user_xml);
+	end
+	return instance;
+end
+
 local function get_store_names(self, path)
 	local stores = set.new();
 	local f, err = io_open(paths.join(prosody.paths.data, path));