File

mod_pubsub_github/mod_pubsub_github.lua @ 6296:1661f6a74141

Multible community modules: Update Readme diff --git a/mod_admin_blocklist/README.md b/mod_admin_blocklist/README.md --- a/mod_admin_blocklist/README.md +++ b/mod_admin_blocklist/README.md @@ -24,8 +24,9 @@ admin_blocklist_roles = { "prosody:opera # Compatibility Prosody-Version Status - --------------- ------ - trunk* Works - 0.12 Works + -------------- ------ + trunk* Works + 13 Works + 0.12 Works -*as of 2024-12-21 + *as of 2025-06-13 diff --git a/mod_audit/README.md b/mod_audit/README.md --- a/mod_audit/README.md +++ b/mod_audit/README.md @@ -52,6 +52,7 @@ prosodyctl mod_audit user@example.com # Compatibilty -Requires Prosody **trunk** as of 2025-02-11. - -Does not work with Prosody 0.12 or earlier. + Prosody-Version Status + ----- ------ + 13 Works + 0.12 Does not work diff --git a/mod_csi_grace_period/README.md b/mod_csi_grace_period/README.md --- a/mod_csi_grace_period/README.md +++ b/mod_csi_grace_period/README.md @@ -16,9 +16,9 @@ pocket is not the best use of radio time Works with [mod_csi_simple][doc:modules:mod_csi_simple] which is included with Prosody. - ------- -------------- - trunk* Works - 0.12 Works - ------- -------------- + ------- ------- + trunk* Works + 13 Works + 0.12 Works -*as of 2024-10-22 + *as of 2025-06-13 diff --git a/mod_http_upload_external/README.md b/mod_http_upload_external/README.md --- a/mod_http_upload_external/README.md +++ b/mod_http_upload_external/README.md @@ -19,7 +19,6 @@ Implementations * [PHP implementation](https://hg.prosody.im/prosody-modules/raw-file/tip/mod_http_upload_external/share.php) * [Python3+Flask implementation](https://github.com/horazont/xmpp-http-upload) * [Go implementation, Prosody Filer](https://github.com/ThomasLeister/prosody-filer) -* [Go implementation, HMAC File Server](https://github.com/PlusOne/hmac-file-server) * [Perl implementation for nginx](https://github.com/weiss/ngx_http_upload) * [Rust implementation](https://gitlab.com/nyovaya/xmpp-http-upload) @@ -88,9 +87,10 @@ Compatibility ============= Prosody-Version Status - ---------------- -------------------- - trunk Works as of 24-12-12 - 0.12 Works + ---------------- -------------------- + trunk Works as of 25-06-13 + 13 Works + 0.12 Works Implementation ============== diff --git a/mod_muc_moderation/README.md b/mod_muc_moderation/README.md --- a/mod_muc_moderation/README.md +++ b/mod_muc_moderation/README.md @@ -27,10 +27,11 @@ modules_enabled = { # Compatibility - ------- --------------- - trunk Works^[as of 2024-10-22] - 0.12 Works - ------- --------------- + ------- --------------- + trunk Works^[as of 2025-06-13] + 13 Works + 0.12 Works + ------- --------------- ## XEP version diff --git a/mod_s2s_idle_timeout/README.md b/mod_s2s_idle_timeout/README.md --- a/mod_s2s_idle_timeout/README.md +++ b/mod_s2s_idle_timeout/README.md @@ -25,9 +25,10 @@ Compatibility ============= Prosody Version Status - ----------------- ----------- - trunk[^1] Works - 0.12 Works - ----------------- ----------- + ----------------- ----------- + trunk[^1] Works + 13 Works + 0.12 Works + ----------------- ----------- -[^1]: as of 2024-10-22 +[^1]: as of 2025-06-13 diff --git a/mod_s2s_keepalive/README.md b/mod_s2s_keepalive/README.md --- a/mod_s2s_keepalive/README.md +++ b/mod_s2s_keepalive/README.md @@ -34,9 +34,10 @@ Compatibility ============= Prosody Version Status - ----------------- ----------- - trunk[^1] Works - 0.12 Works - ----------------- ----------- + ----------------- ----------- + trunk[^1] Works + 13 Works + 0.12 Works + ----------------- ----------- -[^1]: as of 2024-11-11 +[^1]: as of 2025-06-13
author Menel <menel@snikket.de>
date Fri, 13 Jun 2025 09:53:41 +0200
parent 3531:3bece2db869c
line wrap: on
line source

module:depends("http");

local st = require "util.stanza";
local json = require "util.json";
local hashes = require "util.hashes";
local from_hex = require "util.hex".from;
local hmacs = {
	sha1 = hashes.hmac_sha1;
	sha256 = hashes.hmac_sha256;
	sha384 = hashes.hmac_sha384;
	sha512 = hashes.hmac_sha512;
};

local pubsub_service = module:depends("pubsub").service;

-- configuration
local default_node = module:get_option("github_node", "github");
local node_prefix = module:get_option_string("github_node_prefix", "github/");
local node_mapping = module:get_option_string("github_node_mapping");
local github_actor = module:get_option_string("github_actor") or true;
local github_secret = module:get_option("github_secret");

-- validation
assert(github_secret, "Please set 'github_secret'");

local error_mapping = {
	["forbidden"] = 403;
	["item-not-found"] = 404;
	["internal-server-error"] = 500;
	["conflict"] = 409;
};

local function verify_signature(secret, body, signature)
	if not signature then return false; end
	local algo, digest = signature:match("^([^=]+)=(%x+)");
	if not algo then return false; end
	local hmac = hmacs[algo];
	if not algo then return false; end
	return hmac(secret, body) == from_hex(digest);
end

function handle_POST(event)
	local request, response = event.request, event.response;

	if not verify_signature(github_secret, request.body, request.headers.x_hub_signature) then
		module:log("debug", "Signature validation failed");
		return 401;
	end

	local data = json.decode(request.body);
	if not data then
		response.status_code = 400;
		return "Invalid JSON. From you of all people...";
	end

	local node = default_node;
	if node_mapping then
		node = node_prefix .. data.repository[node_mapping];
	end

	local github_event = request.headers.x_github_event or data.object_kind;
	if not github_event and data.commits then
		github_event = "push"; -- curl?
	end
	module:log("debug", "Handling '%s' event: \n%s\n", github_event, tostring(request.body));

	if github_event == "push" then

		for _, commit in ipairs(data.commits) do
			local ok, err = pubsub_service:publish(node, github_actor, commit.id,
				st.stanza("item", { id = commit.id, xmlns = "http://jabber.org/protocol/pubsub" })
				:tag("entry", { xmlns = "http://www.w3.org/2005/Atom" })
					:tag("id"):text(commit.id):up()
					:tag("title"):text(commit.message:match("^[^\r\n]*")):up()
					:tag("summary"):text(("Commit to %s by %s: %s"):format(data.repository.name, commit.author.name, commit.message:match("^[^\r\n]*"))):up()
					:tag("content"):text(commit.message):up()
					:tag("link", { rel = "alternate", href = commit.url }):up()
					:tag("published"):text(commit.author.date):up()
					:tag("author")
						:tag("name"):text(commit.author.name):up()
						:tag("email"):text(commit.author.email):up()
						:up()
			);
			if not ok then
				return error_mapping[err] or 500;
			end
		end

	elseif github_event then
		module:log("debug", "Unsupported Github event %q", github_event);
		return 501;
	end

	response.status_code = 202;
	return "Thank you Github!";
end

module:provides("http", {
	route = {
		POST = handle_POST;
	};
});

if not node_mapping then
	function module.load()
		if not pubsub_service.nodes[default_node] then
			local ok, err = pubsub_service:create(default_node, true);
			if not ok then
				module:log("error", "Error creating node: %s", err);
			else
				module:log("debug", "Node %q created", default_node);
			end
		end
	end
end