changeset 5920:254a21a104aa

mod_server_contact_info: Backport from prosody trunk
author Matthew Wild <mwild1@gmail.com>
date Fri, 07 Jun 2024 16:14:58 +0100
parents 99ecfe44910b
children e67fc7b66c13
files mod_firewall/mod_firewall.lua mod_server_contact_info/README.md mod_server_contact_info/mod_server_contact_info.lua
diffstat 3 files changed, 120 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mod_firewall/mod_firewall.lua	Fri Jun 07 15:53:30 2024 +0100
+++ b/mod_firewall/mod_firewall.lua	Fri Jun 07 16:14:58 2024 +0100
@@ -315,6 +315,10 @@
 	new_long_id = {
 		global_code = [[local new_long_id = require "util.id".long;]];
 	};
+
+	trace = {
+		global_code = [[local trace_init = module:require("trace").init;]];
+	};
 };
 
 local function include_dep(dependency, code)
@@ -371,9 +375,9 @@
 	module:require"marks";
 end
 
-local function new_rule(ruleset, chain)
+local function new_rule(ruleset, chain, line_no)
 	assert(chain, "no chain specified");
-	local rule = { conditions = {}, actions = {}, deps = {} };
+	local rule = { conditions = {}, actions = {}, deps = {}, line_no = line_no };
 	table.insert(ruleset[chain], rule);
 	return rule;
 end
@@ -385,6 +389,7 @@
 		return "Error compiling "..filename.." on line "..line_no..": "..err;
 	end
 
+	local metadata = { debug = {} };
 	local ruleset = {
 		deliver = {};
 	};
@@ -429,6 +434,12 @@
 				return nil, errmsg("Only event chains supported at the moment");
 			end
 			ruleset[chain] = ruleset[chain] or {};
+		elseif not(state) and line:sub(1, 2) == "@@" then
+			local k, v = line:match("^@@%s*([^%s=]+)%s*=%s*(.+)$");
+			if not k then
+				return nil, errmsg("Unable to parse metadata assignment (expected '@@ key = value')");
+			end
+			metadata[k] = v;
 		elseif not(state) and line:sub(1,1) == "%" then -- Definition (zone, limit, etc.)
 			local what, name = line:match("^%%%s*([%w_]+) +([^ :]+)");
 			if not definition_handlers[what] then
@@ -483,12 +494,13 @@
 			end
 		elseif state == "actions" then -- state is actions but action pattern did not match
 			state = nil; -- Awaiting next rule, etc.
-			table.insert(ruleset[chain], rule);
+			table.insert(ruleset[chain], rule); -- FIXME: Is this a bug? Rule should have already been inserted by new_rule()?
 			rule = nil;
 		else
-			if not state then
+			-- Condition
+			if not state then -- Starting a new rule block?
 				state = "rules";
-				rule = new_rule(ruleset, chain);
+				rule = new_rule(ruleset, chain, line_no);
 			end
 			-- Check standard modifiers for the condition (e.g. NOT)
 			local negated;
@@ -514,10 +526,10 @@
 			end
 		end
 	end
-	return ruleset;
+	return ruleset, metadata;
 end
 
-local function process_firewall_rules(ruleset)
+local function process_firewall_rules(ruleset, metadata)
 	-- Compile ruleset and return complete code
 
 	local chain_handlers = {};
@@ -537,8 +549,13 @@
 			end
 		end
 
+		if metadata.trace then
+			include_dep("trace", code);
+			table.insert(code, ("local trace = trace_init(%q, %q);"):format(metadata.filename, chain_name))
+		end
+
 		local condition_cache, n_conditions = {}, 0;
-		for _, rule in ipairs(rules) do
+		for rule_n, rule in ipairs(rules) do
 			for _, dep in ipairs(rule.deps) do
 				include_dep(dep, code);
 			end
@@ -562,6 +579,17 @@
 					else
 						rule.conditions[i] = (negated and "not(" or "(")..condition..")";
 					end
+
+					if metadata.trace then
+						-- Wrap each condition in a tracer
+						rule.conditions[i] = ("trace(%d, %d, %s)"):format(rule_n, i, rule.conditions[i]);
+					end
+				end
+
+				if metadata.trace then
+					-- Trace overall action
+					table.insert(rule.actions, 1, ("trace(%d, nil, true)"):format(rule_n));
+					table.insert(rule.actions, ("else trace(%d, nil, false)"):format(rule_n));
 				end
 
 				rule_code = "if "..table.concat(rule.conditions, " and ").." then\n\t\t\t"
@@ -592,9 +620,9 @@
 end
 
 local function compile_firewall_rules(filename)
-	local ruleset, err = parse_firewall_rules(filename);
-	if not ruleset then return nil, err; end
-	local chain_handlers = process_firewall_rules(ruleset);
+	local ruleset, metadata = parse_firewall_rules(filename);
+	if not ruleset then return nil, metadata; end
+	local chain_handlers = process_firewall_rules(ruleset, metadata);
 	return chain_handlers;
 end
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_server_contact_info/README.md	Fri Jun 07 16:14:58 2024 +0100
@@ -0,0 +1,27 @@
+---
+labels:
+- 'Stage-Alpha'
+summary: Backported mod_server_contact_info for Prosody 0.12
+...
+
+## Overview
+
+In February 2024 we improved the internal API to allow multiple modules to
+publish information about the server, this includes mod_pubsub_serverinfo.
+
+Although Prosody 0.12 comes with its own mod_server_contact_info, this version
+uses the new API so that 0.12 users can hopefully use mod_pubsub_serverinfo
+and other modules which use the new API.
+
+To use it, you must ensure that your Prosody 0.12 deployment is loading *both*
+mod_server_contact_info **and** mod_server_info community modules.
+
+Configuration of contact addresses is the same, whatever version of the module
+you use. See the official documentation on [Prosody's mod_server_contact_info](https://prosody.im/doc/modules/mod_server_contact_info)
+page.
+
+## Compatibility
+
+This module should be compatible with Prosody 0.12, and will fail to load in
+later versions (which already provide the same functionality without community
+modules).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_server_contact_info/mod_server_contact_info.lua	Fri Jun 07 16:14:58 2024 +0100
@@ -0,0 +1,54 @@
+-- XEP-0157: Contact Addresses for XMPP Services for Prosody
+--
+-- Copyright (C) 2011-2018 Kim Alvefur
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+-- This module is backported from Prosody trunk for the benefit of
+-- Prosody 0.12 deployments. The following line will ensure that it won't be
+-- loaded in Prosody versions with built-in support for mod_server_info -
+-- thus preferring the mod_server_contact_info shipped with Prosody instead.
+--% conflicts: mod_server_info
+
+
+local array = require "util.array";
+local it = require "util.iterators";
+local jid = require "util.jid";
+local url = require "socket.url";
+
+module:depends("server_info");
+
+-- Source: http://xmpp.org/registrar/formtypes.html#http:--jabber.org-network-serverinfo
+local address_types = {
+	abuse = "abuse-addresses";
+	admin = "admin-addresses";
+	feedback = "feedback-addresses";
+	sales = "sales-addresses";
+	security = "security-addresses";
+	status = "status-addresses";
+	support = "support-addresses";
+};
+
+-- JIDs of configured service admins are used as fallback
+local admins = module:get_option_inherited_set("admins", {});
+
+local contact_config = module:get_option("contact_info", {
+	admin = array.collect(admins / jid.prep / function(admin) return url.build({scheme = "xmpp"; path = admin}); end);
+});
+
+local fields = {};
+
+for key, field_var in it.sorted_pairs(address_types) do
+	if contact_config[key] then
+		table.insert(fields, {
+			type = "list-multi";
+			name = key;
+			var = field_var;
+			value = contact_config[key];
+		});
+	end
+end
+
+module:add_item("server-info-fields", fields);