annotate mod_pubsub_github/mod_pubsub_github.lua @ 3866:c0df50ce96f0

mod_rest: Handle internal http request errors early and then return Skips over attempted parsing of the payload which usually failed since the body is an error string like "connection refused", so this produced useless errors.
author Kim Alvefur <zash@zash.se>
date Sat, 25 Jan 2020 20:22:12 +0100
parents 3bece2db869c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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";
3520
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
5 local hashes = require "util.hashes";
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
6 local from_hex = require "util.hex".from;
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
7 local hmacs = {
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
8 sha1 = hashes.hmac_sha1;
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
9 sha256 = hashes.hmac_sha256;
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
10 sha384 = hashes.hmac_sha384;
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
11 sha512 = hashes.hmac_sha512;
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
12 };
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
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
14 local pubsub_service = module:depends("pubsub").service;
3521
a200fbce0ecb mod_pubsub_github: Add some spacing to improve readability
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
15
a200fbce0ecb mod_pubsub_github: Add some spacing to improve readability
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
16 -- configuration
3517
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3516
diff changeset
17 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: 3516
diff changeset
18 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: 3516
diff changeset
19 local node_mapping = module:get_option_string("github_node_mapping");
3514
8811b7dbe6e2 mod_pubsub_github: Add support for specifying an actor with less privileges
Kim Alvefur <zash@zash.se>
parents: 3513
diff changeset
20 local github_actor = module:get_option_string("github_actor") or true;
3525
8c1a3b989990 mod_pubsub_github: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3522
diff changeset
21 local github_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
22
3521
a200fbce0ecb mod_pubsub_github: Add some spacing to improve readability
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
23 -- validation
3525
8c1a3b989990 mod_pubsub_github: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3522
diff changeset
24 assert(github_secret, "Please set 'github_secret'");
3515
f756e051fa02 mod_pubsub_github: Require a secret to be set (BC)
Kim Alvefur <zash@zash.se>
parents: 3514
diff changeset
25
3509
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3508
diff changeset
26 local error_mapping = {
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3508
diff changeset
27 ["forbidden"] = 403;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3508
diff changeset
28 ["item-not-found"] = 404;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3508
diff changeset
29 ["internal-server-error"] = 500;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3508
diff changeset
30 ["conflict"] = 409;
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3508
diff changeset
31 };
94414cadfcaa mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents: 3508
diff changeset
32
3520
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
33 local function verify_signature(secret, body, signature)
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
34 if not signature then return false; end
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
35 local algo, digest = signature:match("^([^=]+)=(%x+)");
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
36 if not algo then return false; end
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
37 local hmac = hmacs[algo];
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
38 if not algo then return false; end
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
39 return hmac(secret, body) == from_hex(digest);
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
40 end
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
41
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
42 function handle_POST(event)
3508
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3265
diff changeset
43 local request, response = event.request, event.response;
3520
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
44
3525
8c1a3b989990 mod_pubsub_github: Rename variable to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3522
diff changeset
45 if not verify_signature(github_secret, request.body, request.headers.x_hub_signature) then
3520
37e89a76c7d7 mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents: 3519
diff changeset
46 module:log("debug", "Signature validation failed");
3264
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3263
diff changeset
47 return 401;
f48bedd1d433 mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents: 3263
diff changeset
48 end
3521
a200fbce0ecb mod_pubsub_github: Add some spacing to improve readability
Kim Alvefur <zash@zash.se>
parents: 3520
diff changeset
49
3263
a65f4297264b mod_pubsub_github: Unpack request from event
Kim Alvefur <zash@zash.se>
parents: 1620
diff changeset
50 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
51 if not data then
3508
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3265
diff changeset
52 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
53 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
54 end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 860
diff changeset
55
3526
bcfd6e5bb0f5 mod_pubsub_github: Reorder code to prepare for more code reordering
Kim Alvefur <zash@zash.se>
parents: 3525
diff changeset
56 local node = default_node;
bcfd6e5bb0f5 mod_pubsub_github: Reorder code to prepare for more code reordering
Kim Alvefur <zash@zash.se>
parents: 3525
diff changeset
57 if node_mapping then
bcfd6e5bb0f5 mod_pubsub_github: Reorder code to prepare for more code reordering
Kim Alvefur <zash@zash.se>
parents: 3525
diff changeset
58 node = node_prefix .. data.repository[node_mapping];
bcfd6e5bb0f5 mod_pubsub_github: Reorder code to prepare for more code reordering
Kim Alvefur <zash@zash.se>
parents: 3525
diff changeset
59 end
bcfd6e5bb0f5 mod_pubsub_github: Reorder code to prepare for more code reordering
Kim Alvefur <zash@zash.se>
parents: 3525
diff changeset
60
3529
6ac98c4dbbd3 mod_pubsub_github: Get event type from payload (should work with gitlab)
Kim Alvefur <zash@zash.se>
parents: 3526
diff changeset
61 local github_event = request.headers.x_github_event or data.object_kind;
3531
3bece2db869c mod_pubsub_github: Assume unspecified event is 'push' if there are commits in payload
Kim Alvefur <zash@zash.se>
parents: 3530
diff changeset
62 if not github_event and data.commits then
3bece2db869c mod_pubsub_github: Assume unspecified event is 'push' if there are commits in payload
Kim Alvefur <zash@zash.se>
parents: 3530
diff changeset
63 github_event = "push"; -- curl?
3bece2db869c mod_pubsub_github: Assume unspecified event is 'push' if there are commits in payload
Kim Alvefur <zash@zash.se>
parents: 3530
diff changeset
64 end
3530
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
65 module:log("debug", "Handling '%s' event: \n%s\n", github_event, tostring(request.body));
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
66
3513
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3510
diff changeset
67 if github_event == "push" then
3530
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
68
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
69 for _, commit in ipairs(data.commits) do
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
70 local ok, err = pubsub_service:publish(node, github_actor, commit.id,
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
71 st.stanza("item", { id = commit.id, xmlns = "http://jabber.org/protocol/pubsub" })
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
72 :tag("entry", { xmlns = "http://www.w3.org/2005/Atom" })
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
73 :tag("id"):text(commit.id):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
74 :tag("title"):text(commit.message:match("^[^\r\n]*")):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
75 :tag("summary"):text(("Commit to %s by %s: %s"):format(data.repository.name, commit.author.name, commit.message:match("^[^\r\n]*"))):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
76 :tag("content"):text(commit.message):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
77 :tag("link", { rel = "alternate", href = commit.url }):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
78 :tag("published"):text(commit.author.date):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
79 :tag("author")
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
80 :tag("name"):text(commit.author.name):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
81 :tag("email"):text(commit.author.email):up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
82 :up()
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
83 );
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
84 if not ok then
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
85 return error_mapping[err] or 500;
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
86 end
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
87 end
552d4944d1ca mod_pubsub_github: Rearrange code to make it easier to handle other event types
Kim Alvefur <zash@zash.se>
parents: 3529
diff changeset
88
3513
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3510
diff changeset
89 elseif github_event then
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3510
diff changeset
90 module:log("debug", "Unsupported Github event %q", github_event);
9556e92b2ec4 mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents: 3510
diff changeset
91 return 501;
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
92 end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 860
diff changeset
93
3508
a98a3922bc01 mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents: 3265
diff changeset
94 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
95 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
96 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
97
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
98 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
99 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
100 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
101 };
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
102 });
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
103
3517
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3516
diff changeset
104 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: 3516
diff changeset
105 function module.load()
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3516
diff changeset
106 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: 3516
diff changeset
107 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: 3516
diff changeset
108 if not ok then
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3516
diff changeset
109 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: 3516
diff changeset
110 else
ea1edd7cfb01 mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents: 3516
diff changeset
111 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: 3516
diff changeset
112 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
113 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
114 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
115 end