Merge 0.11->trunk
authorKim Alvefur <zash@zash.se>
Sat, 26 Jan 2019 15:07:11 +0100
changeset 9819 fed614598f88
parent 9811 dcc85d72d5b3 (current diff)
parent 9818 5eb4ef537e98 (diff)
child 9822 eb4724f20b1e
Merge 0.11->trunk
--- a/plugins/mod_vcard_legacy.lua	Thu Jan 24 05:48:55 2019 +0100
+++ b/plugins/mod_vcard_legacy.lua	Sat Jan 26 15:07:11 2019 +0100
@@ -1,4 +1,4 @@
-local st = require "util.stanza"
+local st = require "util.stanza";
 local jid_split = require "util.jid".split;
 
 local mod_pep = module:depends("pep");
@@ -130,10 +130,6 @@
 		end
 	end
 
-	if not vcard_temp.tags[1] then
-		vcard_temp = st.deserialize(vcards:get(jid_split(stanza.attr.to) or origin.username)) or vcard_temp;
-	end
-
 	origin.send(st.reply(stanza):add_child(vcard_temp));
 	return true;
 end);
@@ -143,19 +139,12 @@
 	_defaults_only = true;
 };
 
-module:hook("iq-set/self/vcard-temp:vCard", function (event)
-	local origin, stanza = event.origin, event.stanza;
-	local pep_service = mod_pep.get_pep_service(origin.username);
-
-	local vcard_temp = stanza.tags[1];
+function vcard_to_pep(vcard_temp)
+	local avatars = {};
 
 	local vcard4 = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = "current" })
 		:tag("vcard", { xmlns = 'urn:ietf:params:xml:ns:vcard-4.0' });
 
-	if pep_service:purge("urn:xmpp:avatar:metadata", origin.full_jid) then
-		pep_service:purge("urn:xmpp:avatar:data", origin.full_jid);
-	end
-
 	vcard4:tag("fn"):text_tag("text", vcard_temp:get_child_text("FN")):up();
 
 	local N = vcard_temp:get_child("N");
@@ -248,19 +237,53 @@
 					:tag("data", { xmlns="urn:xmpp:avatar:data" })
 						:text(avatar_payload);
 
-				local ok, err = pep_service:publish("urn:xmpp:avatar:data", origin.full_jid, avatar_hash, avatar_data, node_defaults)
-				if ok then
-					ok, err = pep_service:publish("urn:xmpp:avatar:metadata", origin.full_jid, avatar_hash, avatar_meta, node_defaults);
-				end
-				if not ok then
-					handle_error(origin, stanza, err);
-					return true;
-				end
+				table.insert(avatars, { hash = avatar_hash, meta = avatar_meta, data = avatar_data });
+			end
+		end
+	end
+	return vcard4, avatars;
+end
+
+function save_to_pep(pep_service, actor, vcard4, avatars)
+	if avatars then
+
+		if pep_service:purge("urn:xmpp:avatar:metadata", actor) then
+			pep_service:purge("urn:xmpp:avatar:data", actor);
+		end
+
+		local avatar_defaults = node_defaults;
+		if #avatars > 1 then
+			avatar_defaults = {};
+			for k,v in pairs(node_defaults) do
+				avatar_defaults[k] = v;
+			end
+			avatar_defaults.max_items = #avatars;
+		end
+		for _, avatar in ipairs(avatars) do
+			local ok, err = pep_service:publish("urn:xmpp:avatar:data", actor, avatar.hash, avatar.data, avatar_defaults);
+			if ok then
+				ok, err = pep_service:publish("urn:xmpp:avatar:metadata", actor, avatar.hash, avatar.meta, avatar_defaults);
+			end
+			if not ok then
+				return ok, err;
 			end
 		end
 	end
 
-	local ok, err = pep_service:publish("urn:xmpp:vcard4", origin.full_jid, "current", vcard4, node_defaults);
+	if vcard4 then
+		return pep_service:publish("urn:xmpp:vcard4", actor, "current", vcard4, node_defaults);
+	end
+
+	return true;
+end
+
+module:hook("iq-set/self/vcard-temp:vCard", function (event)
+	local origin, stanza = event.origin, event.stanza;
+	local pep_service = mod_pep.get_pep_service(origin.username);
+
+	local vcard_temp = stanza.tags[1];
+
+	local ok, err = save_to_pep(pep_service, origin.full_jid, vcard_to_pep(vcard_temp));
 	if ok then
 		origin.send(st.reply(stanza));
 	else
@@ -289,3 +312,36 @@
 module:hook("pre-presence/full", inject_xep153, 1);
 module:hook("pre-presence/bare", inject_xep153, 1);
 module:hook("pre-presence/host", inject_xep153, 1);
+
+if module:get_option_boolean("upgrade_legacy_vcards", true) then
+module:hook("resource-bind", function (event)
+	local session = event.session;
+	local username = session.username;
+	local vcard_temp = vcards:get(username);
+	if not vcard_temp then
+		session.log("debug", "No legacy vCard to migrate or already migrated");
+		return;
+	end
+	local pep_service = mod_pep.get_pep_service(username);
+	vcard_temp = st.deserialize(vcard_temp);
+	local vcard4, avatars = vcard_to_pep(vcard_temp);
+	if pep_service:get_last_item("urn:xmpp:vcard4", true) then
+		vcard4 = nil;
+	end
+	if pep_service:get_last_item("urn:xmpp:avatar:metadata", true)
+	or pep_service:get_last_item("urn:xmpp:avatar:data", true) then
+		avatars = nil;
+	end
+	if not (vcard4 or avatars) then
+		session.log("debug", "Already PEP data, not overwriting with migrated data");
+		vcards:set(username, nil);
+		return;
+	end
+	local ok, err = save_to_pep(pep_service, true, vcard4, avatars);
+	if ok and vcards:set(username, nil) then
+		session.log("info", "Migrated vCard-temp to PEP");
+	else
+		session.log("info", "Failed to migrate vCard-temp to PEP: %s", err or "problem emptying 'vcard' store");
+	end
+end);
+end