changeset 4668:ede9682c2022

mod_external_services: Factor out public function for converting to XML Along with the previous commit, allows building the XML thing yourself, should you wish to send it yourself or use it in a different context than an iq reply. API change: The 'reply' is removed from the event.
author Kim Alvefur <zash@zash.se>
date Mon, 30 Aug 2021 20:19:15 +0200
parents 1990611691cf
children d3434fd151b5
files mod_external_services/mod_external_services.lua
diffstat 1 files changed, 35 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/mod_external_services/mod_external_services.lua	Mon Aug 30 00:11:58 2021 +0200
+++ b/mod_external_services/mod_external_services.lua	Mon Aug 30 20:19:15 2021 +0200
@@ -124,34 +124,8 @@
 	return services;
 end
 
-local function handle_services(event)
-	local origin, stanza = event.origin, event.stanza;
-	local action = stanza.tags[1];
-
-	local user_bare = jid.bare(stanza.attr.from);
-	local user_host = jid.host(user_bare);
-	if not ((access:empty() and origin.type == "c2s") or access:contains(user_bare) or access:contains(user_host)) then
-		origin.send(st.error_reply(stanza, "auth", "forbidden"));
-		return true;
-	end
-
-	local reply = st.reply(stanza):tag("services", { xmlns = action.attr.xmlns });
-	local services = get_services();
-
-	local requested_type = action.attr.type;
-	if requested_type then
-		services:filter(function(item)
-			return item.type == requested_type;
-		end);
-	end
-
-	module:fire_event("external_service/services", {
-			origin = origin;
-			stanza = stanza;
-			reply = reply;
-			requested_type = requested_type;
-			services = services;
-		});
+function services_xml(services, name, namespace)
+	local reply = st.stanza(name or "services", { xmlns = namespace or "urn:xmpp:extdisco:2" });
 
 	for _, srv in ipairs(services) do
 		reply:tag("service", {
@@ -166,6 +140,38 @@
 			}):up();
 	end
 
+	return reply;
+end
+
+local function handle_services(event)
+	local origin, stanza = event.origin, event.stanza;
+	local action = stanza.tags[1];
+
+	local user_bare = jid.bare(stanza.attr.from);
+	local user_host = jid.host(user_bare);
+	if not ((access:empty() and origin.type == "c2s") or access:contains(user_bare) or access:contains(user_host)) then
+		origin.send(st.error_reply(stanza, "auth", "forbidden"));
+		return true;
+	end
+
+	local services = get_services();
+
+	local requested_type = action.attr.type;
+	if requested_type then
+		services:filter(function(item)
+			return item.type == requested_type;
+		end);
+	end
+
+	module:fire_event("external_service/services", {
+			origin = origin;
+			stanza = stanza;
+			requested_type = requested_type;
+			services = services;
+		});
+
+	local reply = st.reply(stanza):add_child(services_xml(services, action.name, action.attr.xmlns));
+
 	origin.send(reply);
 	return true;
 end
@@ -179,7 +185,6 @@
 		return true;
 	end
 
-	local reply = st.reply(stanza):tag("credentials", { xmlns = action.attr.xmlns });
 	local services = get_services();
 	services:filter(function (item)
 		return item.restricted;
@@ -199,7 +204,6 @@
 	module:fire_event("external_service/credentials", {
 			origin = origin;
 			stanza = stanza;
-			reply = reply;
 			requested_credentials = requested_credentials;
 			services = services;
 		});
@@ -210,18 +214,7 @@
 		return requested_credentials:contains(port_key) or requested_credentials:contains(portless_key);
 	end);
 
-	for _, srv in ipairs(services) do
-		reply:tag("service", {
-				type = srv.type;
-				transport = srv.transport;
-				host = srv.host;
-				port = srv.port and string.format("%d", srv.port) or nil;
-				username = srv.username;
-				password = srv.password;
-				expires = srv.expires and dt.datetime(srv.expires) or nil;
-				restricted = srv.restricted and "1" or nil;
-			}):up();
-	end
+	local reply = st.reply(stanza):add_child(services_xml(services, action.name, action.attr.xmlns));
 
 	origin.send(reply);
 	return true;