Mercurial > prosody-modules
comparison mod_rest/mod_rest.lua @ 3930:d5dafd617cd6
mod_rest: Break out POST errors into a registry
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 07 Mar 2020 17:34:17 +0100 |
| parents | bd687d586a8a |
| children | 2e8b284ac8b3 |
comparison
equal
deleted
inserted
replaced
| 3929:bd687d586a8a | 3930:d5dafd617cd6 |
|---|---|
| 113 return s:get_child_text("body") or ""; | 113 return s:get_child_text("body") or ""; |
| 114 end | 114 end |
| 115 return tostring(s); | 115 return tostring(s); |
| 116 end | 116 end |
| 117 | 117 |
| 118 local post_errors = { | |
| 119 parse = { code = 400, condition = "not-well-formed", text = "Failed to parse payload", }, | |
| 120 xmlns = { code = 422, condition = "invalid-namespace", text = "'xmlns' attribute must be empty", }, | |
| 121 name = { code = 422, condition = "unsupported-stanza-type", text = "Invalid stanza, must be 'message', 'presence' or 'iq'.", }, | |
| 122 to = { code = 422, condition = "improper-addressing", text = "Invalid destination JID", }, | |
| 123 from = { code = 422, condition = "invalid-from", text = "Invalid source JID", }, | |
| 124 post_auth = { code = 403, condition = "not-authorized", text = "Not authorized to send stanza with requested 'from'", }, | |
| 125 iq_type = { code = 422, condition = "invalid-xml", text = "'iq' stanza must be of type 'get' or 'set'", }, | |
| 126 iq_tags = { code = 422, condition = "bad-format", text = "'iq' stanza must have exactly one child tag", }, | |
| 127 }; | |
| 128 | |
| 118 local function handle_post(event) | 129 local function handle_post(event) |
| 119 local request, response = event.request, event.response; | 130 local request, response = event.request, event.response; |
| 120 local from; | 131 local from; |
| 121 local origin; | 132 local origin; |
| 122 | 133 |
| 131 from = jid.join(origin.username, origin.host, origin.resource); | 142 from = jid.join(origin.username, origin.host, origin.resource); |
| 132 end | 143 end |
| 133 local payload, err = parse(request.headers.content_type, request.body); | 144 local payload, err = parse(request.headers.content_type, request.body); |
| 134 if not payload then | 145 if not payload then |
| 135 -- parse fail | 146 -- parse fail |
| 136 return errors.new({ code = 400, text = "Failed to parse payload" }, { error = err, type = request.headers.content_type, data = request.body }); | 147 return errors.new("parse", { error = err, type = request.headers.content_type, data = request.body, }, post_errors); |
| 137 end | 148 end |
| 138 if payload.attr.xmlns then | 149 if payload.attr.xmlns then |
| 139 return errors.new({ code = 422, text = "'xmlns' attribute must be empty" }); | 150 return errors.new("xmlns", nil, post_errors); |
| 140 elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then | 151 elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then |
| 141 return errors.new({ code = 422, text = "Invalid stanza, must be 'message', 'presence' or 'iq'." }); | 152 return errors.new("name", nil, post_errors); |
| 142 end | 153 end |
| 143 local to = jid.prep(payload.attr.to); | 154 local to = jid.prep(payload.attr.to); |
| 144 if not to then | 155 if not to then |
| 145 return errors.new({ code = 422, text = "Invalid destination JID" }); | 156 return errors.new("to", nil, post_errors); |
| 146 end | 157 end |
| 147 if payload.attr.from then | 158 if payload.attr.from then |
| 148 local requested_from = jid.prep(payload.attr.from); | 159 local requested_from = jid.prep(payload.attr.from); |
| 149 if not requested_from then | 160 if not requested_from then |
| 150 return errors.new({ code = 422, text = "Invalid source JID" }); | 161 return errors.new("from", nil, post_errors); |
| 151 end | 162 end |
| 152 if jid.compare(requested_from, from) then | 163 if jid.compare(requested_from, from) then |
| 153 from = requested_from; | 164 from = requested_from; |
| 154 else | 165 else |
| 155 return errors.new({ code = 403, text = "Not authorized to send from "..requested_from }); | 166 return errors.new("from_auth", nil, post_errors); |
| 156 end | 167 end |
| 157 end | 168 end |
| 158 payload.attr = { | 169 payload.attr = { |
| 159 from = from, | 170 from = from, |
| 160 to = to, | 171 to = to, |
| 167 if payload.name == "iq" then | 178 if payload.name == "iq" then |
| 168 function origin.send(stanza) | 179 function origin.send(stanza) |
| 169 module:send(stanza); | 180 module:send(stanza); |
| 170 end | 181 end |
| 171 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then | 182 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then |
| 172 return errors.new({ code = 422, text = "'iq' stanza must be of type 'get' or 'set'" }); | 183 return errors.new("iq_type", nil, post_errors); |
| 173 elseif #payload.tags ~= 1 then | 184 elseif #payload.tags ~= 1 then |
| 174 return errors.new({ code = 422, text = "'iq' stanza must have exactly one child tag" }); | 185 return errors.new("iq_tags", nil, post_errors); |
| 175 end | 186 end |
| 176 return module:send_iq(payload, origin):next( | 187 return module:send_iq(payload, origin):next( |
| 177 function (result) | 188 function (result) |
| 178 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); | 189 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); |
| 179 response.headers.content_type = send_type; | 190 response.headers.content_type = send_type; |
