Changeset

8351:cc05b6366576

mod_storage_xep0227: Add roster storage (fixes #1023)
author Kim Alvefur <zash@zash.se>
date Thu, 19 Oct 2017 12:08:40 +0200
parents 8350:3ca11d408382
children 8352:6ff50541d2a6
files plugins/mod_storage_xep0227.lua
diffstat 1 files changed, 73 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_storage_xep0227.lua	Thu Oct 19 12:21:49 2017 +0200
+++ b/plugins/mod_storage_xep0227.lua	Thu Oct 19 12:08:40 2017 +0200
@@ -164,6 +164,79 @@
 	end;
 };
 
+handlers.roster = {
+	get = function(self, user)
+		user = getUserElement(getXml(user, self.host));
+		if user then
+			local roster = user:get_child("query", "jabber:iq:roster");
+			if roster then
+				local r = {
+					[false] = {
+						version = roster.attr.version;
+						pending = {};
+					}
+				};
+				for item in roster:childtags("item") do
+					r[item.attr.jid] = {
+						jid = item.attr.jid,
+						subscription = item.attr.subscription,
+						ask = item.attr.ask,
+						name = item.attr.name,
+						groups = {};
+					};
+					for group in item:childtags("group") do
+						r[item.attr.jid].groups[group:get_text()] = true;
+					end
+					for pending in user:childtags("presence", "jabber:client") do
+						r[false].pending[pending.attr.from] = true;
+					end
+				end
+				return r;
+			end
+		end
+	end;
+	set = function(self, user, data)
+		local xml = getXml(user, self.host);
+		local usere = xml and getUserElement(xml);
+		if usere then
+			local roster = usere:get_child("query", 'jabber:iq:roster');
+			if roster then removeStanzaChild(usere, roster); end
+			usere:maptags(function (tag)
+				if tag.attr.xmlns == "jabber:client" and tag.name == "presence" and tag.attr.type == "subscribe" then
+					return nil;
+				end
+				return tag;
+			end);
+			if data and next(data) ~= nil then
+				roster = st.stanza("query", {xmlns='jabber:iq:roster'});
+				usere:add_child(roster);
+				for jid, item in pairs(data) do
+					if jid then
+						roster:tag("item", {
+							jid = jid,
+							subscription = item.subscription,
+							ask = item.ask,
+							name = item.name,
+						});
+						for group in pairs(item.groups) do
+							roster:tag("group"):text(group):up();
+						end
+						roster:up(); -- move out from item
+					else
+						roster.attr.version = item.version;
+						for pending_jid in pairs(item.pending) do
+							usere:add_child(st.presence({ from = pending_jid, type = "subscribe" }));
+						end
+					end
+				end
+			end
+			return setXml(user, self.host, xml);
+		end
+		return true;
+	end;
+};
+
+
 -----------------------------
 local driver = {};