Mercurial > prosody-modules
annotate mod_post_msg/mod_post_msg.lua @ 5193:2bb29ece216b
mod_http_oauth2: Implement stateless dynamic client registration
Replaces previous explicit registration that required either the
additional module mod_adhoc_oauth2_client or manually editing the
database. That method was enough to have something to test with, but
would not probably not scale easily.
Dynamic client registration allows creating clients on the fly, which
may be even easier in theory.
In order to not allow basically unauthenticated writes to the database,
we implement a stateless model here.
per_host_key := HMAC(config -> oauth2_registration_key, hostname)
client_id := JWT { client metadata } signed with per_host_key
client_secret := HMAC(per_host_key, client_id)
This should ensure everything we need to know is part of the client_id,
allowing redirects etc to be validated, and the client_secret can be
validated with only the client_id and the per_host_key.
A nonce injected into the client_id JWT should ensure nobody can submit
the same client metadata and retrieve the same client_secret
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 03 Mar 2023 21:14:19 +0100 |
parents | 926aaaeb0d21 |
children |
rev | line source |
---|---|
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"; |
2989
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 | 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 | 55 if not html then |
56 module:log("warn", "mod_post_msg: invalid XML: %s", err); | |
57 return 400; | |
58 end | |
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 |
2989
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 }); |