Software /
code /
prosody-modules
Annotate
mod_rest/mod_rest.lua @ 3971:ae5ac41c391d
mod_rest: Improve auth error reporting
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 12 Apr 2020 18:07:16 +0200 |
parent | 3933:93147b89ea67 |
child | 4036:04c11b652aeb |
rev | line source |
---|---|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 -- RESTful API |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 -- |
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
3 -- Copyright (c) 2019-2020 Kim Alvefur |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 -- |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 -- This file is MIT/X11 licensed. |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
6 |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
7 local encodings = require "util.encodings"; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
8 local base64 = encodings.base64; |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 local errors = require "util.error"; |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
10 local http = require "net.http"; |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
11 local id = require "util.id"; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
12 local jid = require "util.jid"; |
3813 | 13 local json = require "util.json"; |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
14 local st = require "util.stanza"; |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
15 local um = require "core.usermanager"; |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 local xml = require "util.xml"; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
17 |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
18 local jsonmap = module:require"jsonmap"; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
19 |
3915
80dffbbd056b
mod_rest, mod_http_oauth2: Switch from mod_authtokens to mod_tokenauth per Prosody bf81523e2ff4
Matthew Wild <mwild1@gmail.com>
parents:
3911
diff
changeset
|
20 local tokens = module:depends("tokenauth"); |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
21 |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
22 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" }); |
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
23 |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
24 local www_authenticate_header; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
25 do |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
26 local header, realm = {}, module.host.."/"..module.name; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
27 for mech in auth_mechanisms do |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
28 header[#header+1] = ("%s realm=%q"):format(mech, realm); |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
29 end |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
30 www_authenticate_header = table.concat(header, ", "); |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
31 end |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
32 |
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
33 -- Bearer token |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
34 local function check_credentials(request) |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
35 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$"); |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
36 if not (auth_type and auth_data) or not auth_mechanisms:contains(auth_type) then |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
37 return false; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
38 end |
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
39 |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
40 if auth_type == "Basic" then |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
41 local creds = base64.decode(auth_data); |
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
42 if not creds then return false; end |
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
43 local username, password = string.match(creds, "^([^:]+):(.*)$"); |
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
44 if not username then return false; end |
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
45 username, password = encodings.stringprep.nodeprep(username), encodings.stringprep.saslprep(password); |
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
46 if not username then return false; end |
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
47 if not um.test_password(username, module.host, password) then |
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
48 return false; |
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
49 end |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
50 return { username = username, host = module.host }; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
51 elseif auth_type == "Bearer" then |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
52 local token_info = tokens.get_token_info(auth_data); |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
53 if not token_info or not token_info.session then |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
54 return false; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
55 end |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
56 return token_info.session; |
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
57 end |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
58 return nil; |
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
59 end |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
60 |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
61 local function parse(mimetype, data) |
3825
802087d3155a
mod_rest: Fix traceback on missing content-type header
Kim Alvefur <zash@zash.se>
parents:
3824
diff
changeset
|
62 mimetype = mimetype and mimetype:match("^[^; ]*"); |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
63 if mimetype == "application/xmpp+xml" then |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
64 return xml.parse(data); |
3813 | 65 elseif mimetype == "application/json" then |
66 local parsed, err = json.decode(data); | |
67 if not parsed then | |
68 return parsed, err; | |
69 end | |
70 return jsonmap.json2st(parsed); | |
3911
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
71 elseif mimetype == "application/x-www-form-urlencoded"then |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
72 local parsed = http.formdecode(data); |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
73 if type(parsed) == "string" then |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
74 return parse("text/plain", parsed); |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
75 end |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
76 for i = #parsed, 1, -1 do |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
77 parsed[i] = nil; |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
78 end |
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
79 return jsonmap.json2st(parsed); |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
80 elseif mimetype == "text/plain" then |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
81 return st.message({ type = "chat" }, data); |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
82 end |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
83 return nil, "unknown-payload-type"; |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
84 end |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
85 |
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
86 local function decide_type(accept, supported_types) |
3813 | 87 -- assumes the accept header is sorted |
88 local ret = supported_types[1]; | |
89 for i = 2, #supported_types do | |
90 if (accept:find(supported_types[i], 1, true) or 1000) < (accept:find(ret, 1, true) or 1000) then | |
91 ret = supported_types[i]; | |
92 end | |
93 end | |
94 return ret; | |
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
95 end |
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
96 |
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
97 local supported_inputs = { |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
98 "application/xmpp+xml", |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
99 "application/json", |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
100 "application/x-www-form-urlencoded", |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
101 "text/plain", |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
102 }; |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
103 |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
104 local supported_outputs = { |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
105 "application/xmpp+xml", |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
106 "application/json", |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
107 }; |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
108 |
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
109 local function encode(type, s) |
3813 | 110 if type == "application/json" then |
111 return json.encode(jsonmap.st2json(s)); | |
112 elseif type == "text/plain" then | |
113 return s:get_child_text("body") or ""; | |
114 end | |
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
115 return tostring(s); |
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
116 end |
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
117 |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
118 local post_errors = { |
3971
ae5ac41c391d
mod_rest: Improve auth error reporting
Kim Alvefur <zash@zash.se>
parents:
3933
diff
changeset
|
119 noauthz = { code = 401, type = "auth", condition = "not-authorized", text = "No credentials provided" }, |
ae5ac41c391d
mod_rest: Improve auth error reporting
Kim Alvefur <zash@zash.se>
parents:
3933
diff
changeset
|
120 unauthz = { code = 403, type = "auth", condition = "not-authorized", text = "Credentials not accepted" }, |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
121 parse = { code = 400, condition = "not-well-formed", text = "Failed to parse payload", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
122 xmlns = { code = 422, condition = "invalid-namespace", text = "'xmlns' attribute must be empty", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
123 name = { code = 422, condition = "unsupported-stanza-type", text = "Invalid stanza, must be 'message', 'presence' or 'iq'.", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
124 to = { code = 422, condition = "improper-addressing", text = "Invalid destination JID", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
125 from = { code = 422, condition = "invalid-from", text = "Invalid source JID", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
126 post_auth = { code = 403, condition = "not-authorized", text = "Not authorized to send stanza with requested 'from'", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
127 iq_type = { code = 422, condition = "invalid-xml", text = "'iq' stanza must be of type 'get' or 'set'", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
128 iq_tags = { code = 422, condition = "bad-format", text = "'iq' stanza must have exactly one child tag", }, |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
129 }; |
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
130 |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
131 local function handle_post(event) |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
132 local request, response = event.request, event.response; |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
133 local from; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
134 local origin; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
135 |
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
136 if not request.headers.authorization then |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
137 response.headers.www_authenticate = www_authenticate_header; |
3971
ae5ac41c391d
mod_rest: Improve auth error reporting
Kim Alvefur <zash@zash.se>
parents:
3933
diff
changeset
|
138 return errors.new("noauthz", nil, post_errors); |
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
139 else |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
140 origin = check_credentials(request); |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
141 if not origin then |
3971
ae5ac41c391d
mod_rest: Improve auth error reporting
Kim Alvefur <zash@zash.se>
parents:
3933
diff
changeset
|
142 return errors.new("unauthz", nil, post_errors); |
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
143 end |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
144 from = jid.join(origin.username, origin.host, origin.resource); |
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
145 end |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
146 local payload, err = parse(request.headers.content_type, request.body); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
147 if not payload then |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
148 -- parse fail |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
149 return errors.new("parse", { error = err, type = request.headers.content_type, data = request.body, }, post_errors); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
150 end |
3801
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
151 if payload.attr.xmlns then |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
152 return errors.new("xmlns", nil, post_errors); |
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
153 elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
154 return errors.new("name", nil, post_errors); |
3801
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
155 end |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
156 local to = jid.prep(payload.attr.to); |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
157 if not to then |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
158 return errors.new("to", nil, post_errors); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
159 end |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
160 if payload.attr.from then |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
161 local requested_from = jid.prep(payload.attr.from); |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
162 if not requested_from then |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
163 return errors.new("from", nil, post_errors); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
164 end |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
165 if jid.compare(requested_from, from) then |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
166 from = requested_from; |
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
167 else |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
168 return errors.new("from_auth", nil, post_errors); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
169 end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
170 end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
171 payload.attr = { |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
172 from = from, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
173 to = to, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
174 id = payload.attr.id or id.medium(), |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
175 type = payload.attr.type, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
176 ["xml:lang"] = payload.attr["xml:lang"], |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
177 }; |
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
178 module:log("debug", "Received[rest]: %s", payload:top_tag()); |
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
179 local send_type = decide_type((request.headers.accept or "") ..",".. request.headers.content_type, supported_outputs) |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
180 if payload.name == "iq" then |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
181 function origin.send(stanza) |
3926
f77ae9685eb6
mod_rest: Fix routing to self-jid (thanks jonas’)
Kim Alvefur <zash@zash.se>
parents:
3925
diff
changeset
|
182 module:send(stanza); |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
183 end |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
184 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
185 return errors.new("iq_type", nil, post_errors); |
3832
0d4146cf9fbc
mod_rest: Enforce single child policy for outgoing it stanzas
Kim Alvefur <zash@zash.se>
parents:
3825
diff
changeset
|
186 elseif #payload.tags ~= 1 then |
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
187 return errors.new("iq_tags", nil, post_errors); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
188 end |
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
189 return module:send_iq(payload, origin):next( |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
190 function (result) |
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
191 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); |
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
192 response.headers.content_type = send_type; |
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
193 return encode(send_type, result.stanza); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
194 end, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
195 function (error) |
3909
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
196 if not errors.is_err(error) then |
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
197 module:log("error", "Uncaught native error: %s", error); |
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
198 return select(2, errors.coerce(nil, error)); |
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
199 elseif error.context and error.context.stanza then |
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
200 response.headers.content_type = send_type; |
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
201 module:log("debug", "Sending[rest]: %s", error.context.stanza:top_tag()); |
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
202 return encode(send_type, error.context.stanza); |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
203 else |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
204 return error; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
205 end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
206 end); |
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
207 else |
3796
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3795
diff
changeset
|
208 function origin.send(stanza) |
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
209 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
210 response.headers.content_type = send_type; |
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
211 response:send(encode(send_type, stanza)); |
3796
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3795
diff
changeset
|
212 return true; |
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3795
diff
changeset
|
213 end |
3814
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
214 module:send(payload, origin); |
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
215 return 202; |
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
216 end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
217 end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
218 |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
219 -- Handle stanzas submitted via HTTP |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
220 module:depends("http"); |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
221 module:provides("http", { |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
222 route = { |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
223 POST = handle_post; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
224 }; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
225 }); |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
226 |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
227 -- Forward stanzas from XMPP to HTTP and return any reply |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
228 local rest_url = module:get_option_string("rest_callback_url", nil); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
229 if rest_url then |
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
230 local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); |
3813 | 231 if send_type == "json" then |
232 send_type = "application/json"; | |
233 end | |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
234 |
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
235 module:set_status("info", "Not yet connected"); |
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
236 http.request(rest_url, { |
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
237 method = "OPTIONS", |
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
238 }, function (body, code, response) |
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
239 if code == 0 then |
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
240 return module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, body); |
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
241 else |
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
242 module:set_status("info", "Connected"); |
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
243 end |
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
244 if code == 200 and response.headers.accept then |
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
245 send_type = decide_type(response.headers.accept, supported_outputs); |
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
246 module:log("debug", "Set 'rest_callback_content_type' = %q based on Accept header", send_type); |
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
247 end |
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
248 end); |
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
249 |
3797
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
250 local code2err = { |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
251 [400] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
252 [401] = { condition = "not-authorized"; type = "auth" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
253 [402] = { condition = "not-authorized"; type = "auth" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
254 [403] = { condition = "forbidden"; type = "auth" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
255 [404] = { condition = "item-not-found"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
256 [406] = { condition = "not-acceptable"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
257 [408] = { condition = "remote-server-timeout"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
258 [409] = { condition = "conflict"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
259 [410] = { condition = "gone"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
260 [411] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
261 [412] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
262 [413] = { condition = "resource-constraint"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
263 [414] = { condition = "resource-constraint"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
264 [415] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
265 [429] = { condition = "resource-constraint"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
266 [431] = { condition = "resource-constraint"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
267 |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
268 [500] = { condition = "internal-server-error"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
269 [501] = { condition = "feature-not-implemented"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
270 [502] = { condition = "remote-server-timeout"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
271 [503] = { condition = "service-unavailable"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
272 [504] = { condition = "remote-server-timeout"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
273 [507] = { condition = "resource-constraint"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
274 }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
275 |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
276 local function handle_stanza(event) |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
277 local stanza, origin = event.stanza, event.origin; |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
278 local reply_needed = stanza.name == "iq"; |
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
279 local receipt; |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
280 |
3824
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
281 if stanza.attr.type == "error" then |
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
282 reply_needed = false; |
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
283 end |
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
284 |
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
285 if stanza.name == "message" and stanza.attr.id and stanza:get_child("urn:xmpp:receipts", "request") then |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
286 reply_needed = true; |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
287 receipt = st.stanza("received", { xmlns = "urn:xmpp:receipts", id = stanza.id }); |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
288 end |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
289 |
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
290 local request_body = encode(send_type, stanza); |
3799
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
291 |
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
292 -- Keep only the top level element and let the rest be GC'd |
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
293 stanza = st.clone(stanza, true); |
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
294 |
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
295 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
296 http.request(rest_url, { |
3799
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
297 body = request_body, |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
298 headers = { |
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
299 ["Content-Type"] = send_type, |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
300 ["Content-Language"] = stanza.attr["xml:lang"], |
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
301 Accept = table.concat(supported_inputs, ", "); |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
302 }, |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
303 }, function (body, code, response) |
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
304 if code == 0 then |
3864
d845475c75f3
mod_rest: Process results even on internal errors with HTTP request
Kim Alvefur <zash@zash.se>
parents:
3862
diff
changeset
|
305 module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, body); |
3866
c0df50ce96f0
mod_rest: Handle internal http request errors early and then return
Kim Alvefur <zash@zash.se>
parents:
3865
diff
changeset
|
306 origin.send(st.error_reply(stanza, "wait", "recipient-unavailable", body)); |
c0df50ce96f0
mod_rest: Handle internal http request errors early and then return
Kim Alvefur <zash@zash.se>
parents:
3865
diff
changeset
|
307 return; |
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
308 else |
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
309 module:set_status("info", "Connected"); |
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
310 end |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
311 local reply; |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
312 |
3867
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
313 if code == 202 or code == 204 then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
314 if not reply_needed then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
315 -- Delivered, no reply |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
316 return; |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
317 end |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
318 else |
3867
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
319 local parsed, err = parse(response.headers["content-type"], body); |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
320 if not parsed then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
321 module:log("warn", "Failed parsing data from REST callback: %s, %q", err, body); |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
322 elseif parsed.name ~= stanza.name then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
323 module:log("warn", "REST callback responded with the wrong stanza type, got %s but expected %s", parsed.name, stanza.name); |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
324 else |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
325 parsed.attr = { |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
326 from = stanza.attr.to, |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
327 to = stanza.attr.from, |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
328 id = parsed.attr.id or id.medium(); |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
329 type = parsed.attr.type, |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
330 ["xml:lang"] = parsed.attr["xml:lang"], |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
331 }; |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
332 if parsed.name == "message" and parsed.attr.type == "groupchat" then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
333 parsed.attr.to = jid.bare(stanza.attr.from); |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
334 end |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
335 if not stanza.attr.type and parsed:get_child("error") then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
336 parsed.attr.type = "error"; |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
337 end |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
338 if parsed.attr.type == "error" then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
339 parsed.attr.id = stanza.attr.id; |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
340 elseif parsed.name == "iq" then |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
341 parsed.attr.id = stanza.attr.id; |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
342 parsed.attr.type = "result"; |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
343 end |
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
344 reply = parsed; |
3821
11272a3233ce
mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents:
3816
diff
changeset
|
345 end |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
346 end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
347 |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
348 if not reply then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
349 local code_hundreds = code - (code % 100); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
350 if code_hundreds == 200 then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
351 reply = st.reply(stanza); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
352 if stanza.name ~= "iq" then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
353 reply.attr.id = id.medium(); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
354 end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
355 -- TODO presence/status=body ? |
3797
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
356 elseif code2err[code] then |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
357 reply = st.error_reply(stanza, errors.new(code, nil, code2err)); |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
358 elseif code_hundreds == 400 then |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
359 reply = st.error_reply(stanza, "modify", "bad-request", body); |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
360 elseif code_hundreds == 500 then |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
361 reply = st.error_reply(stanza, "cancel", "internal-server-error", body); |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
362 else |
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
363 reply = st.error_reply(stanza, "cancel", "undefined-condition", body); |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
364 end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
365 end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
366 |
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
367 if receipt then |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
368 reply:add_direct_child(receipt); |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
369 end |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
370 |
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
371 module:log("debug", "Received[rest]: %s", reply:top_tag()); |
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
372 |
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
373 origin.send(reply); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
374 end); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
375 |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
376 return true; |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
377 end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
378 |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
379 if module:get_host_type() == "component" then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
380 module:hook("iq/bare", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
381 module:hook("message/bare", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
382 module:hook("presence/bare", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
383 module:hook("iq/full", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
384 module:hook("message/full", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
385 module:hook("presence/full", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
386 module:hook("iq/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
387 module:hook("message/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
388 module:hook("presence/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
389 else |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
390 -- Don't override everything on normal VirtualHosts |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
391 module:hook("iq/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
392 module:hook("message/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
393 module:hook("presence/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
394 end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
395 end |
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
396 |
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
397 local supported_errors = { |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
398 "text/html", |
3931
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
399 "application/xmpp+xml", |
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
400 "application/json", |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
401 }; |
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
402 |
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
403 local http_server = require "net.http.server"; |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
404 module:hook_object_event(http_server, "http-error", function (event) |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
405 local request, response = event.request, event.response; |
3931
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
406 local response_as = decide_type(request and request.headers.accept or "", supported_errors); |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
407 if response_as == "application/xmpp+xml" then |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
408 if response then |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
409 response.headers.content_type = "application/xmpp+xml"; |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
410 end |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
411 local stream_error = st.stanza("error", { xmlns = "http://etherx.jabber.org/streams" }); |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
412 if event.error then |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
413 stream_error:tag(event.error.condition, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }):up(); |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
414 if event.error.text then |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
415 stream_error:text_tag("text", event.error.text, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }); |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
416 end |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
417 end |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
418 return tostring(stream_error); |
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
419 elseif response_as == "application/json" then |
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
420 if response then |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
421 response.headers.content_type = "application/json"; |
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
422 end |
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
423 return json.encode({ |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
424 type = "error", |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
425 error = event.error, |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
426 code = event.code, |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
427 }); |
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
428 end |
3933
93147b89ea67
mod_rest: Avoid interfering with mod_http_oauth2 errors (fixes #1500)
Kim Alvefur <zash@zash.se>
parents:
3931
diff
changeset
|
429 end, 1); |