Mercurial > prosody-modules
annotate mod_pubsub_github/mod_pubsub_github.lua @ 3520:37e89a76c7d7
mod_pubsub_github: Lift signature validation from mod_pubsub_post
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 31 Mar 2019 18:21:22 +0200 |
parents | ac623080324a |
children | a200fbce0ecb |
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; |
3517
ea1edd7cfb01
mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents:
3516
diff
changeset
|
15 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
|
16 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
|
17 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
|
18 local github_actor = module:get_option_string("github_actor") or true; |
3264
f48bedd1d433
mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents:
3263
diff
changeset
|
19 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
|
20 |
3515
f756e051fa02
mod_pubsub_github: Require a secret to be set (BC)
Kim Alvefur <zash@zash.se>
parents:
3514
diff
changeset
|
21 assert(secret, "Please set 'github_secret'"); |
f756e051fa02
mod_pubsub_github: Require a secret to be set (BC)
Kim Alvefur <zash@zash.se>
parents:
3514
diff
changeset
|
22 |
3509
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
23 local error_mapping = { |
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
24 ["forbidden"] = 403; |
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
25 ["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
|
26 ["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
|
27 ["conflict"] = 409; |
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
28 }; |
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
29 |
3520
37e89a76c7d7
mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents:
3519
diff
changeset
|
30 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
|
31 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
|
32 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
|
33 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
|
34 local hmac = hmacs[algo]; |
37e89a76c7d7
mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents:
3519
diff
changeset
|
35 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
|
36 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
|
37 end |
37e89a76c7d7
mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents:
3519
diff
changeset
|
38 |
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
|
39 function handle_POST(event) |
3508
a98a3922bc01
mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents:
3265
diff
changeset
|
40 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
|
41 |
37e89a76c7d7
mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents:
3519
diff
changeset
|
42 if not verify_signature(secret, request.body, request.headers.x_hub_signature) then |
37e89a76c7d7
mod_pubsub_github: Lift signature validation from mod_pubsub_post
Kim Alvefur <zash@zash.se>
parents:
3519
diff
changeset
|
43 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
|
44 return 401; |
f48bedd1d433
mod_pubsub_github: Add support for signed requests
Kim Alvefur <zash@zash.se>
parents:
3263
diff
changeset
|
45 end |
3263
a65f4297264b
mod_pubsub_github: Unpack request from event
Kim Alvefur <zash@zash.se>
parents:
1620
diff
changeset
|
46 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
|
47 if not data then |
3508
a98a3922bc01
mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents:
3265
diff
changeset
|
48 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
|
49 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
|
50 end |
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
860
diff
changeset
|
51 |
3513
9556e92b2ec4
mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents:
3510
diff
changeset
|
52 local github_event = request.headers.x_github_event |
9556e92b2ec4
mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents:
3510
diff
changeset
|
53 if github_event == "push" then |
9556e92b2ec4
mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents:
3510
diff
changeset
|
54 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:
3510
diff
changeset
|
55 elseif github_event then |
9556e92b2ec4
mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents:
3510
diff
changeset
|
56 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
|
57 return 501; |
9556e92b2ec4
mod_pubsub_github: Abort on unknown github events
Kim Alvefur <zash@zash.se>
parents:
3510
diff
changeset
|
58 end -- else .. is this even github? |
3510
f09423c29f31
mod_pubsub_github: Log debug message before attempting to publish
Kim Alvefur <zash@zash.se>
parents:
3509
diff
changeset
|
59 |
3517
ea1edd7cfb01
mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents:
3516
diff
changeset
|
60 local node = 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
|
61 if 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
|
62 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:
3516
diff
changeset
|
63 end |
ea1edd7cfb01
mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents:
3516
diff
changeset
|
64 |
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
|
65 for _, commit in ipairs(data.commits) do |
3516
d94875c3ddda
mod_pubsub_github: Publish with item id set to commit hash (BC)
Kim Alvefur <zash@zash.se>
parents:
3515
diff
changeset
|
66 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:
3515
diff
changeset
|
67 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
|
68 :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
|
69 :tag("id"):text(commit.id):up() |
3519
ac623080324a
mod_pubsub_github: Only put first line of commit message in title, rest in content
Kim Alvefur <zash@zash.se>
parents:
3518
diff
changeset
|
70 :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:
3518
diff
changeset
|
71 :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
|
72 :tag("link", { rel = "alternate", href = commit.url }):up() |
3518
95c1c3e057cf
mod_pubsub_github: Fix publish date
Kim Alvefur <zash@zash.se>
parents:
3517
diff
changeset
|
73 :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
|
74 :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
|
75 :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
|
76 :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
|
77 :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
|
78 ); |
3509
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
79 if not ok then |
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
80 return error_mapping[err] or 500; |
94414cadfcaa
mod_pubsub_github: Return appropriate status code on failure to publish
Kim Alvefur <zash@zash.se>
parents:
3508
diff
changeset
|
81 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
|
82 end |
1343
7dbde05b48a9
all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
860
diff
changeset
|
83 |
3508
a98a3922bc01
mod_pubsub_github: Send sensible status codes
Kim Alvefur <zash@zash.se>
parents:
3265
diff
changeset
|
84 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
|
85 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
|
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 |
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
|
88 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
|
89 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
|
90 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
|
91 }; |
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 }); |
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
|
93 |
3517
ea1edd7cfb01
mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents:
3516
diff
changeset
|
94 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
|
95 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
|
96 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
|
97 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
|
98 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
|
99 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
|
100 else |
ea1edd7cfb01
mod_pubsub_github: Add support for publishing to multiple node based on repository
Kim Alvefur <zash@zash.se>
parents:
3516
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 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
|
105 end |