mod_pubsub_github/mod_pubsub_github.lua
author Kim Alvefur <zash@zash.se>
Sun, 31 Mar 2019 17:47:45 +0200
changeset 3517 9556e92b2ec4
parent 3514 f09423c29f31
child 3518 8811b7dbe6e2
permissions -rw-r--r--
mod_pubsub_github: Abort on unknown github events
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;
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
     8
local node = module:get_option("github_node", "github");
3268
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
     9
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
    10
3513
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    11
local error_mapping = {
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    12
	["forbidden"] = 403;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    13
	["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
    14
	["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
    15
	["conflict"] = 409;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    16
};
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    17
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
    18
function handle_POST(event)
3512
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3269
diff changeset
    19
	local request, response = event.request, event.response;
3268
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
    20
	if secret and ("sha1=" .. hmac_sha1(secret, request.body, true)) ~= request.headers.x_hub_signature then
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
    21
		return 401;
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3267
diff changeset
    22
	end
3267
a65f4297264b mod_pubsub_github: Unpack request from event
Kim Alvefur <zash@zash.se>
parents: 1624
diff changeset
    23
	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
    24
	if not data then
3512
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3269
diff changeset
    25
		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
    26
		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
    27
	end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 860
diff changeset
    28
3517
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    29
	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
    30
	if github_event == "push" then
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    31
		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
    32
	elseif github_event then
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    33
		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
    34
		return 501;
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
    35
	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
    36
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
    37
	for _, commit in ipairs(data.commits) do
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
    38
		local ok, err = pubsub_service:publish(node, true, data.repository.name,
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
    39
			st.stanza("item", { id = data.repository.name, xmlns = "http://jabber.org/protocol/pubsub" })
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
    40
			: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
    41
				:tag("id"):text(commit.id):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
    42
				:tag("title"):text(commit.message):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
    43
				:tag("link", { rel = "alternate", href = commit.url }):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
    44
				:tag("published"):text(commit.timestamp):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
    45
				: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
    46
					: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
    47
					: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
    48
					: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
    49
		);
3513
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3512
diff changeset
    50
		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
    51
			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
    52
		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
    53
	end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 860
diff changeset
    54
3512
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3269
diff changeset
    55
	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
    56
	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
    57
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
    58
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
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
    60
	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
    61
		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
    62
	};
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
    63
});
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
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
    65
function module.load()
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
    66
	if not pubsub_service.nodes[node] then
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
		local ok, err = pubsub_service:create(node, true);
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
		if not ok then
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
			module:log("error", "Error creating node: %s", err);
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
		else
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
			module:log("debug", "Node %q created", node);
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
		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
    73
	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
    74
end