mod_pubsub_github/mod_pubsub_github.lua
author Kim Alvefur <zash@zash.se>
Sun, 31 Mar 2019 18:16:49 +0200
changeset 3523 ac623080324a
parent 3522 95c1c3e057cf
child 3524 37e89a76c7d7
permissions -rw-r--r--
mod_pubsub_github: Only put first line of commit message in title, rest in content
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:depends("http");
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local st = require "util.stanza";
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local json = require "util.json";
3268
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
     5
local hmac_sha1 = require "util.hashes".hmac_sha1;
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
local pubsub_service = module:depends("pubsub").service;
3521
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
     8
local default_node = module:get_option("github_node", "github");
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
     9
local node_prefix = module:get_option_string("github_node_prefix", "github/");
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    10
local node_mapping = module:get_option_string("github_node_mapping");
3518
8811b7dbe6e2 mod_pubsub_github: Add support for specifying an actor with less privileges
Kim Alvefur <zash@zash.se>
parents: 3517
diff changeset
    11
local github_actor = module:get_option_string("github_actor") or true;
3268
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
    12
local secret = module:get_option("github_secret");
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
3519
f756e051fa02 mod_pubsub_github: Require a secret to be set (BC)
Kim Alvefur <zash@zash.se>
parents: 3518
diff changeset
    14
assert(secret, "Please set 'github_secret'");
f756e051fa02 mod_pubsub_github: Require a secret to be set (BC)
Kim Alvefur <zash@zash.se>
parents: 3518
diff changeset
    15
3513
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    16
local error_mapping = {
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    17
	["forbidden"] = 403;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    18
	["item-not-found"] = 404;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    19
	["internal-server-error"] = 500;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    20
	["conflict"] = 409;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    21
};
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    22
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
function handle_POST(event)
3512
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3269
diff changeset
    24
	local request, response = event.request, event.response;
3519
f756e051fa02 mod_pubsub_github: Require a secret to be set (BC)
Kim Alvefur <zash@zash.se>
parents: 3518
diff changeset
    25
	if ("sha1=" .. hmac_sha1(secret, request.body, true)) ~= request.headers.x_hub_signature then
3268
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
    26
		return 401;
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
    27
	end
3267
a65f4297264b mod_pubsub_github: Unpack request from event
Kim Alvefur <zash@zash.se>
parents: 1624
diff changeset
    28
	local data = json.decode(request.body);
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
	if not data then
3512
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3269
diff changeset
    30
		response.status_code = 400;
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
		return "Invalid JSON. From you of all people...";
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
	end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 860
diff changeset
    33
3517
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    34
	local github_event = request.headers.x_github_event
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    35
	if github_event == "push" then
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    36
		module:log("debug", "Handling 'push' event: \n%s\n", tostring(request.body));
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    37
	elseif github_event then
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    38
		module:log("debug", "Unsupported Github event %q", github_event);
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    39
		return 501;
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    40
	end -- else .. is this even github?
3514
f09423c29f31 mod_pubsub_github: Log debug message before attempting to publish
Kim Alvefur <zash@zash.se>
parents: 3513
diff changeset
    41
3521
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    42
	local node = default_node;
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    43
	if node_mapping then
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    44
		node = node_prefix .. data.repository[node_mapping];
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    45
	end
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    46
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
	for _, commit in ipairs(data.commits) do
3520
d94875c3ddda mod_pubsub_github: Publish with item id set to commit hash (BC)
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
    48
		local ok, err = pubsub_service:publish(node, github_actor, commit.id,
d94875c3ddda mod_pubsub_github: Publish with item id set to commit hash (BC)
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
    49
			st.stanza("item", { id = commit.id, xmlns = "http://jabber.org/protocol/pubsub" })
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
			:tag("entry", { xmlns = "http://www.w3.org/2005/Atom" })
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
				:tag("id"):text(commit.id):up()
3523
ac623080324a mod_pubsub_github: Only put first line of commit message in title, rest in content
Kim Alvefur <zash@zash.se>
parents: 3522
diff changeset
    52
				:tag("title"):text(commit.message:match("^[^\r\n]*")):up()
ac623080324a mod_pubsub_github: Only put first line of commit message in title, rest in content
Kim Alvefur <zash@zash.se>
parents: 3522
diff changeset
    53
				:tag("content"):text(commit.message):up()
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
				:tag("link", { rel = "alternate", href = commit.url }):up()
3522
95c1c3e057cf mod_pubsub_github: Fix publish date
Kim Alvefur <zash@zash.se>
parents: 3521
diff changeset
    55
				:tag("published"):text(commit.author.date):up()
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
				:tag("author")
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
					:tag("name"):text(commit.author.name):up()
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
					:tag("email"):text(commit.author.email):up()
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
					:up()
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
		);
3513
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    61
		if not ok then
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    62
			return error_mapping[err] or 500;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    63
		end
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
	end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 860
diff changeset
    65
3512
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3269
diff changeset
    66
	response.status_code = 202;
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
	return "Thank you Github!";
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
end
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
module:provides("http", {
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
	route = {
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
		POST = handle_POST;
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
	};
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
});
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
3521
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    76
if not node_mapping then
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    77
	function module.load()
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    78
		if not pubsub_service.nodes[default_node] then
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    79
			local ok, err = pubsub_service:create(default_node, true);
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    80
			if not ok then
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    81
				module:log("error", "Error creating node: %s", err);
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    82
			else
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    83
				module:log("debug", "Node %q created", default_node);
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
    84
			end
860
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
		end
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
	end
1c886affb375 mod_pubsub_github: Receive Github web hooks (generated on pushes to a repository) and forward to a local pubsub node
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
end