mod_post_msg/mod_post_msg.lua
author Ben Smith <bens@effortlessis.com>
Tue, 14 May 2024 07:31:34 -0700
changeset 5912 dcea4b4c415d
parent 2993 926aaaeb0d21
permissions -rw-r--r--
Tweaking documentation to clarify that Oauth2 can be used for VirtualHosts and Component installations.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
661
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
     1
module:depends"http"
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local jid_split = require "util.jid".split;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
local jid_prep = require "util.jid".prep;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local msg = require "util.stanza".message;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
local test_password = require "core.usermanager".test_password;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
local b64_decode = require "util.encodings".base64.decode;
661
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
     8
local formdecode = require "net.http".formdecode;
1302
e556219cb43d mod_post_msg: add support for HTML messages
Christian Weiske <cweiske@cweiske.de>
parents: 661
diff changeset
     9
local xml = require"util.xml";
2993
926aaaeb0d21 mod_post_msg: Add support for a JSON based format similar to what mod_component_http uses
Kim Alvefur <zash@zash.se>
parents: 1418
diff changeset
    10
local json = require "util.json";
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
661
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    12
local function require_valid_user(f)
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    13
	return function(event, path)
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    14
		local request = event.request;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    15
		local response = event.response;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    16
		local headers = request.headers;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    17
		if not headers.authorization then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    18
			response.headers.www_authenticate = ("Basic realm=%q"):format(module.host.."/"..module.name);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    19
			return 401
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    20
		end
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    21
		local from_jid, password = b64_decode(headers.authorization:match"[^ ]*$"):match"([^:]*):(.*)";
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    22
		from_jid = jid_prep(from_jid);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    23
		if from_jid and password then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    24
			local user, host = jid_split(from_jid);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    25
			local ok, err = test_password(user, host, password);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    26
			if ok and user and host then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    27
				module:log("debug", "Authed as %s", from_jid);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    28
				return f(event, path, from_jid);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    29
			elseif err then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    30
				module:log("debug", "User failed authentication: %s", err);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    31
			end
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    32
		end
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    33
		return 401
321
661f64627fed mod_post_msg: Add compatibility with usermanager in 0.7
Kim Alvefur <zash@zash.se>
parents: 320
diff changeset
    34
	end
661f64627fed mod_post_msg: Add compatibility with usermanager in 0.7
Kim Alvefur <zash@zash.se>
parents: 320
diff changeset
    35
end
661f64627fed mod_post_msg: Add compatibility with usermanager in 0.7
Kim Alvefur <zash@zash.se>
parents: 320
diff changeset
    36
661
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    37
local function handle_post(event, path, authed_user)
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    38
	local request = event.request;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    39
	local response = event.response;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    40
	local headers = request.headers;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    41
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    42
	local body_type = headers.content_type;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    43
	local to = jid_prep(path);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    44
	local message;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    45
	if body_type == "text/plain" then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    46
		if to and request.body then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    47
			message = msg({ to = to, from = authed_user, type = "chat"},request.body);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    48
		end
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    49
	elseif body_type == "application/x-www-form-urlencoded" then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    50
		local post_body = formdecode(request.body);
1302
e556219cb43d mod_post_msg: add support for HTML messages
Christian Weiske <cweiske@cweiske.de>
parents: 661
diff changeset
    51
		message = msg({ to = post_body.to or to, from = authed_user,
1417
9b6fbababb8c mod_post_msg: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 1302
diff changeset
    52
		                type = post_body.type or "chat"}, post_body.body);
1302
e556219cb43d mod_post_msg: add support for HTML messages
Christian Weiske <cweiske@cweiske.de>
parents: 661
diff changeset
    53
		if post_body.html then
1418
a0375f84d65a mod_post_msg: Add <body> wrapper tag with namespace in module so the client doesn't have to
Kim Alvefur <zash@zash.se>
parents: 1417
diff changeset
    54
			local html, err = xml.parse([[<body xmlns="http://www.w3.org/1999/xhtml">]]..post_body.html..[[</body>]]);
1417
9b6fbababb8c mod_post_msg: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 1302
diff changeset
    55
			if not html then
9b6fbababb8c mod_post_msg: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 1302
diff changeset
    56
				module:log("warn", "mod_post_msg: invalid XML: %s", err);
9b6fbababb8c mod_post_msg: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 1302
diff changeset
    57
				return 400;
9b6fbababb8c mod_post_msg: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 1302
diff changeset
    58
			end
9b6fbababb8c mod_post_msg: Fix indentation
Kim Alvefur <zash@zash.se>
parents: 1302
diff changeset
    59
			message:tag("html", {xmlns="http://jabber.org/protocol/xhtml-im"}):add_child(html):up();
1302
e556219cb43d mod_post_msg: add support for HTML messages
Christian Weiske <cweiske@cweiske.de>
parents: 661
diff changeset
    60
		end
2993
926aaaeb0d21 mod_post_msg: Add support for a JSON based format similar to what mod_component_http uses
Kim Alvefur <zash@zash.se>
parents: 1418
diff changeset
    61
	elseif body_type == "application/json" then
926aaaeb0d21 mod_post_msg: Add support for a JSON based format similar to what mod_component_http uses
Kim Alvefur <zash@zash.se>
parents: 1418
diff changeset
    62
		local post_body = json.decode(request.body);
926aaaeb0d21 mod_post_msg: Add support for a JSON based format similar to what mod_component_http uses
Kim Alvefur <zash@zash.se>
parents: 1418
diff changeset
    63
		if not post_body then return 400; end
926aaaeb0d21 mod_post_msg: Add support for a JSON based format similar to what mod_component_http uses
Kim Alvefur <zash@zash.se>
parents: 1418
diff changeset
    64
		message = msg({ to = post_body.to or to, from = authed_user,
926aaaeb0d21 mod_post_msg: Add support for a JSON based format similar to what mod_component_http uses
Kim Alvefur <zash@zash.se>
parents: 1418
diff changeset
    65
		                type = post_body.type or "chat"}, post_body.body);
661
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    66
	else
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    67
		return 415;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    68
	end
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    69
	if message and message.attr.to then
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    70
		module:log("debug", "Sending %s", tostring(message));
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    71
		module:send(message);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    72
		return 201;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    73
	end
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    74
	return 422;
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
661
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    77
module:provides("http", {
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    78
	default_path = "/msg";
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    79
	route = {
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    80
		["POST /*"] = require_valid_user(handle_post);
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    81
		OPTIONS = function(e)
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    82
			local headers = e.response.headers;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    83
			headers.allow = "POST";
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    84
			headers.accept = "application/x-www-form-urlencoded, text/plain";
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    85
			return 200;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    86
		end;
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    87
	}
a6c8f252e5fa mod_post_msg: Update to the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 321
diff changeset
    88
});