Mercurial > prosody-modules
comparison mod_pubsub_post/mod_pubsub_post.lua @ 3501:1df139b157fb
mod_pubsub_post: Add support for WebSub authentication
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 24 Aug 2018 14:52:09 +0200 |
parents | 64d1dfbd1740 |
children | 882180b459a0 |
comparison
equal
deleted
inserted
replaced
3500:e86315c9b5c4 | 3501:1df139b157fb |
---|---|
3 local st = require "util.stanza"; | 3 local st = require "util.stanza"; |
4 local json = require "util.json"; | 4 local json = require "util.json"; |
5 local xml = require "util.xml"; | 5 local xml = require "util.xml"; |
6 local uuid_generate = require "util.uuid".generate; | 6 local uuid_generate = require "util.uuid".generate; |
7 local timestamp_generate = require "util.datetime".datetime; | 7 local timestamp_generate = require "util.datetime".datetime; |
8 local hashes = require "util.hashes"; | |
9 local from_hex = require "util.hex".from; | |
10 local hmacs = { | |
11 sha1 = hashes.hmac_sha1; | |
12 sha256 = hashes.hmac_sha256; | |
13 sha384 = hashes.hmac_sha384; | |
14 sha512 = hashes.hmac_sha512; | |
15 }; | |
8 | 16 |
9 local pubsub_service = module:depends("pubsub").service; | 17 local pubsub_service = module:depends("pubsub").service; |
10 | 18 |
11 local error_mapping = { | 19 local error_mapping = { |
12 ["forbidden"] = 403; | 20 ["forbidden"] = 403; |
66 return publish_payload(node, actor, "current", xmlpayload); | 74 return publish_payload(node, actor, "current", xmlpayload); |
67 end | 75 end |
68 end | 76 end |
69 | 77 |
70 local actor_source = module:get_option_string("pubsub_post_actor", "superuser"); | 78 local actor_source = module:get_option_string("pubsub_post_actor", "superuser"); |
79 local actor_secret = module:get_option_string("pubsub_post_secret"); | |
80 local actor_secrets = module:get_option("pubsub_post_secrets"); | |
81 | |
82 local function verify_signature(secret, body, signature) | |
83 if not signature then return false; end | |
84 local algo, digest = signature:match("^([^=]+)=(%x+)"); | |
85 if not algo then return false; end | |
86 local hmac = hmacs[algo]; | |
87 if not algo then return false; end | |
88 return hmac(secret, body) == from_hex(digest); | |
89 end | |
71 | 90 |
72 function handle_POST(event, path) | 91 function handle_POST(event, path) |
73 local request = event.request; | 92 local request = event.request; |
74 module:log("debug", "Handling POST: \n%s\n", tostring(request.body)); | 93 module:log("debug", "Handling POST: \n%s\n", tostring(request.body)); |
75 | 94 |
76 local content_type = request.headers.content_type or "application/octet-stream"; | 95 local content_type = request.headers.content_type or "application/octet-stream"; |
77 local actor; | 96 local actor; |
97 | |
98 local secret = actor_secrets and actor_secrets[path] or actor_secret; | |
99 if secret and not verify_signature(secret, request.body, request.headers.x_hub_signature) then | |
100 return 401; | |
101 end | |
78 | 102 |
79 if actor_source == "request.ip" then | 103 if actor_source == "request.ip" then |
80 actor = request.ip or request.conn:ip(); | 104 actor = request.ip or request.conn:ip(); |
81 elseif actor_source == "superuser" then | 105 elseif actor_source == "superuser" then |
82 actor = true; | 106 actor = true; |