# HG changeset patch # User Matthew Wild # Date 1364998456 -3600 # Node ID 2c5430ff1c11ee2691ebbdb71be6417a1043696c # Parent dbcbcec37d24d2e27e8679b98908e5b5f14b4eb6 mod_pubsub_googlecode: Module to receive post-commit webhook requests from Google Code Hosting diff -r dbcbcec37d24 -r 2c5430ff1c11 mod_pubsub_googlecode/mod_pubsub_googlecode.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_pubsub_googlecode/mod_pubsub_googlecode.lua Wed Apr 03 15:14:16 2013 +0100 @@ -0,0 +1,84 @@ +module:depends("http"); + +local st = require "util.stanza"; +local json = require "util.json"; +local formdecode = require "net.http".formdecode; +local hmac = require "util.hmac"; +local st = require "util.stanza"; +local json = require "util.json"; +local datetime = require "util.datetime".datetime; + + +local pubsub_service = module:depends("pubsub").service; + +local node = module:get_option_string("googlecode_node", "googlecode"); +local auth_key = module:get_option_string("googlecode_auth_key"); + +if not auth_key then + module:log("warn", "Specify googlecode_auth_key to prevent commit spoofing!"); +end + +function handle_POST(event) + local request = event.request; + local body = request.body; + + if auth_key then + local digest_header = request.headers["google-code-project-hosting-hook-hmac"]; + local digest = hmac.md5(auth_key, body, true); + if digest ~= digest_header then + module:log("warn", "Commit POST failed authentication check, sender gave %s, we got %s, body was:\n%s", tostring(digest_header), tostring(digest), tostring(body)); + return "No thanks."; + end + end + + local data = json.decode(body); + + local project = data.project_name or "somewhere"; + for _, rev in ipairs(data.revisions) do + if rev.url:match("^http://wiki.") then + local what; + for _, page in ipairs(rev.added) do + what = page:match("^/(.-)%.wiki"); + if what then break; end + end + if not what then + for _, page in ipairs(rev.modified) do + what = page:match("^/(.-)%.wiki"); + if what then break; end + end + end + rev.message = "wiki ("..(what or "unknown page").."): "..rev.message; + end + + local ok, err = pubsub_service:publish(node, true, project, + st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = "project" }) + :tag("entry", { xmlns = "http://www.w3.org/2005/Atom" }) + :tag("id"):text(tostring(rev.revision)):up() + :tag("title"):text(rev.message):up() + :tag("link", { rel = "alternate", href = rev.url }):up() + :tag("published"):text(datetime(rev.timestamp)):up() + :tag("author") + :tag("name"):text(rev.author):up() + :up() + ); + end + module:log("debug", "Handled POST: \n%s\n", tostring(body)); + return "Thank you Google!"; +end + +module:provides("http", { + route = { + POST = handle_POST; + }; +}); + +function module.load() + if not pubsub_service.nodes[node] then + local ok, err = pubsub_service:create(node, true); + if not ok then + module:log("error", "Error creating node: %s", err); + else + module:log("debug", "Node %q created", node); + end + end +end