mod_pubsub_post/mod_pubsub_post.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 23 Sep 2022 22:41:15 +0100
changeset 5058 62480053c87b
parent 4556 c87181a98f29
permissions -rw-r--r--
mod_cloud_notify_encrypted: Additional debug logging when enabling/skipping
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:depends("http");
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local st = require "util.stanza";
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local json = require "util.json";
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
     5
local xml = require "util.xml";
4556
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
     6
local http = require "net.http";
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
local uuid_generate = require "util.uuid".generate;
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local timestamp_generate = require "util.datetime".datetime;
3505
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
     9
local hashes = require "util.hashes";
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
    10
local from_hex = require "util.hex".from;
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
    11
local hmacs = {
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
    12
	sha1 = hashes.hmac_sha1;
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
    13
	sha256 = hashes.hmac_sha256;
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
    14
	sha384 = hashes.hmac_sha384;
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
    15
	sha512 = hashes.hmac_sha512;
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
    16
};
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
local pubsub_service = module:depends("pubsub").service;
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
4525
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    20
local mappings = module:get_option("pubsub_post_mappings", nil);
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    21
local datamapper;
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    22
if type(mappings) == "table" then
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    23
	datamapper = require "util.datamapper";
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    24
	for node, f in pairs(mappings) do
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    25
		if type(f) == "string" then
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    26
			local fh = assert(module:load_resource(f));
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    27
			mappings[node] = assert(json.parse(fh:read("*a")));
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    28
			fh:close()
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    29
		end
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    30
	end
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    31
end
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    32
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    33
local function wrap(node, parsed, raw)
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    34
	if mappings and mappings[node] then
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    35
		return datamapper.unparse(mappings[node], parsed)
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    36
	end
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    37
	return st.stanza("json", { xmlns="urn:xmpp:json:0" }):text(raw);
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    38
end
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    39
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    40
local error_mapping = {
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    41
	["forbidden"] = 403;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    42
	["item-not-found"] = 404;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    43
	["internal-server-error"] = 500;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    44
	["conflict"] = 409;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    45
};
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    46
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
    47
local function publish_payload(node, actor, item_id, payload)
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    48
	local post_item = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = item_id, })
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    49
		:add_child(payload);
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
    50
	local ok, err = pubsub_service:publish(node, actor, item_id, post_item);
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    51
	module:log("debug", ":publish(%q, true, %q, %s) -> %q", node, item_id, payload:top_tag(), err or "");
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    52
	if not ok then
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    53
		return error_mapping[err] or 500;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    54
	end
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    55
	return 202;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    56
end
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
    58
local function handle_json(node, actor, data)
3020
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    59
	local parsed, err = json.decode(data);
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    60
	if not parsed then
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    61
		return { status_code = 400; body = tostring(err); }
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    62
	end
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    63
	if type(parsed) ~= "table" then
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    64
		return { status_code = 400; body = "object or array expected"; };
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    65
	end
4525
f7381268a597 mod_pubsub_post: Add support for mapping incoming JSON to XML
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
    66
	local payload = wrap(node, parsed, data)
4526
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    67
	local item_id = "current";
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    68
	if payload.attr["http://jabber.org/protocol/pubsub\1id"] then
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    69
		item_id = payload.attr["http://jabber.org/protocol/pubsub\1id"];
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    70
		payload.attr["http://jabber.org/protocol/pubsub\1id"] = nil;
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    71
	elseif type(parsed.id) == "string" then
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    72
		item_id = parsed.id;
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    73
	end
08b71d02c6dc mod_pubsub_post: Allow specifying item id by a special mapping
Kim Alvefur <zash@zash.se>
parents: 4525
diff changeset
    74
	return publish_payload(node, actor, item_id, payload);
3020
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    75
end
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
    76
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
    77
local function publish_atom(node, actor, feed)
3019
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    78
	for entry in feed:childtags("entry") do
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    79
		local item_id = entry:get_child_text("id");
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    80
		if not item_id then
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    81
			item_id = uuid_generate();
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    82
			entry:tag("id"):text(item_id):up();
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    83
		end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    84
		if not entry:get_child_text("published") then
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    85
			entry:tag("published"):text(timestamp_generate()):up();
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    86
		end
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
    87
		local resp = publish_payload(node, actor, item_id, entry);
3019
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    88
		if resp ~= 202 then return resp; end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    89
	end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    90
	return 202;
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    91
end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    92
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
    93
local function handle_xml(node, actor, payload)
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    94
	local xmlpayload, err = xml.parse(payload);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    95
	if not xmlpayload then
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    96
		module:log("debug", "XML parse error: %s\n%q", err, payload);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    97
		return { status_code = 400, body = tostring(err) };
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    98
	end
3019
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    99
	if xmlpayload.attr.xmlns == "http://www.w3.org/2005/Atom" and xmlpayload.name == "feed" then
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
   100
		return publish_atom(node, actor, xmlpayload);
3019
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
   101
	else
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
   102
		return publish_payload(node, actor, "current", xmlpayload);
3019
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
   103
	end
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   104
end
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   105
4556
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   106
local function handle_urlencoded(node, actor, data)
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   107
	local parsed = http.formdecode(data);
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   108
	if type(parsed) ~= "table" then return {status_code = 400; body = "invalid payload"}; end
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   109
	for i = 1, #parsed do parsed[i] = nil; end
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   110
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   111
	local payload = wrap(node, parsed, json.encode(parsed));
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   112
	local item_id = "current";
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   113
	if payload.attr["http://jabber.org/protocol/pubsub\1id"] then
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   114
		item_id = payload.attr["http://jabber.org/protocol/pubsub\1id"];
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   115
		payload.attr["http://jabber.org/protocol/pubsub\1id"] = nil;
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   116
	elseif type(parsed.id) == "string" then
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   117
		item_id = parsed.id;
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   118
	end
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   119
	return publish_payload(node, actor, item_id, payload);
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   120
end
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   121
3507
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   122
local actor_source = module:get_option_string("pubsub_post_actor"); -- COMPAT
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   123
local default_secret = module:get_option_string("pubsub_post_default_secret");
3505
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   124
local actor_secrets = module:get_option("pubsub_post_secrets");
3507
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   125
local actors = module:get_option("pubsub_post_actors");
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   126
local default_actor = module:get_option_string("pubsub_post_default_actor");
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   127
if not default_actor and actor_source == "superuser" then
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   128
	default_actor = true;
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   129
end
3505
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   130
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   131
local function verify_signature(secret, body, signature)
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   132
	if not signature then return false; end
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   133
	local algo, digest = signature:match("^([^=]+)=(%x+)");
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   134
	if not algo then return false; end
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   135
	local hmac = hmacs[algo];
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   136
	if not algo then return false; end
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   137
	return hmac(secret, body) == from_hex(digest);
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   138
end
3022
727a8beeb5c3 mod_pubsub_post: Add an option for what to use as pubsub 'actor'
Kim Alvefur <zash@zash.se>
parents: 3021
diff changeset
   139
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   140
function handle_POST(event, path)
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   141
	local request = event.request;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   142
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   143
	local content_type = request.headers.content_type or "application/octet-stream";
3507
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   144
	local actor = actors and actors[path] or default_actor or request.ip;
882180b459a0 mod_pubsub_post: Restructure authentication and authorization (BC)
Kim Alvefur <zash@zash.se>
parents: 3505
diff changeset
   145
	local secret = actor_secrets and actor_secrets[path] or default_secret;
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   146
3508
9ef5b229f73e mod_pubsub_post: Make debug messages more informative
Kim Alvefur <zash@zash.se>
parents: 3507
diff changeset
   147
	module:log("debug", "Handling POST to node %q by %q with %q: \n%s\n", path, actor, content_type, request.body);
9ef5b229f73e mod_pubsub_post: Make debug messages more informative
Kim Alvefur <zash@zash.se>
parents: 3507
diff changeset
   148
3505
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   149
	if secret and not verify_signature(secret, request.body, request.headers.x_hub_signature) then
3508
9ef5b229f73e mod_pubsub_post: Make debug messages more informative
Kim Alvefur <zash@zash.se>
parents: 3507
diff changeset
   150
		module:log("debug", "Signature validation failed");
3505
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   151
		return 401;
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   152
	end
1df139b157fb mod_pubsub_post: Add support for WebSub authentication
Kim Alvefur <zash@zash.se>
parents: 3259
diff changeset
   153
3259
64d1dfbd1740 mod_pubsub_post: Ensure actor is non-nil (catch inability to determine IP or simliar)
Kim Alvefur <zash@zash.se>
parents: 3258
diff changeset
   154
	if not actor then
64d1dfbd1740 mod_pubsub_post: Ensure actor is non-nil (catch inability to determine IP or simliar)
Kim Alvefur <zash@zash.se>
parents: 3258
diff changeset
   155
		return 401;
64d1dfbd1740 mod_pubsub_post: Ensure actor is non-nil (catch inability to determine IP or simliar)
Kim Alvefur <zash@zash.se>
parents: 3258
diff changeset
   156
	end
64d1dfbd1740 mod_pubsub_post: Ensure actor is non-nil (catch inability to determine IP or simliar)
Kim Alvefur <zash@zash.se>
parents: 3258
diff changeset
   157
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   158
	if content_type == "application/xml" or content_type:sub(-4) == "+xml" then
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
   159
		return handle_xml(path, actor, request.body);
3020
3f4e2340bfdc mod_pubsub_post: Add support for publishing arbitrary JSON
Kim Alvefur <zash@zash.se>
parents: 3019
diff changeset
   160
	elseif content_type == "application/json" or content_type:sub(-5) == "+json" then
3021
8e48c0b233e0 mod_pubsub_post: Factor out the 'actor' into an argument
Kim Alvefur <zash@zash.se>
parents: 3020
diff changeset
   161
		return handle_json(path, actor, request.body);
4556
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   162
	elseif content_type == "application/x-www-form-urlencoded" then
c87181a98f29 mod_pubsub_post: Add support for urlencoded form-data
Kim Alvefur <zash@zash.se>
parents: 4526
diff changeset
   163
		return handle_urlencoded(path, actor, request.body);
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   164
	end
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   165
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   166
	module:log("debug", "Unsupported content-type: %q", content_type);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
   167
	return 415;
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   168
end
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   170
module:provides("http", {
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   171
	route = {
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   172
		["POST /*"] = handle_POST;
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   173
	};
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   174
});
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   175
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   176
function module.load()
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   177
	module:log("debug", "Loaded at %s", module:http_url());
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   178
end