comparison mod_rest/mod_rest.lua @ 4244:07c11080027e

mod_rest: Use util.error registry datatype Saves a few characters per line.
author Kim Alvefur <zash@zash.se>
date Sat, 14 Nov 2020 22:38:28 +0100
parents 6a91d217acc9
children 7bf3bf81c9ef
comparison
equal deleted inserted replaced
4243:aed7038ab2ab 4244:07c11080027e
146 return s:get_child_text("body") or ""; 146 return s:get_child_text("body") or "";
147 end 147 end
148 return tostring(s); 148 return tostring(s);
149 end 149 end
150 150
151 local post_errors = { 151 local post_errors = errors.init("mod_rest", {
152 noauthz = { code = 401, type = "auth", condition = "not-authorized", text = "No credentials provided" }, 152 noauthz = { code = 401, type = "auth", condition = "not-authorized", text = "No credentials provided" },
153 unauthz = { code = 403, type = "auth", condition = "not-authorized", text = "Credentials not accepted" }, 153 unauthz = { code = 403, type = "auth", condition = "not-authorized", text = "Credentials not accepted" },
154 parse = { code = 400, condition = "not-well-formed", text = "Failed to parse payload", }, 154 parse = { code = 400, condition = "not-well-formed", text = "Failed to parse payload", },
155 xmlns = { code = 422, condition = "invalid-namespace", text = "'xmlns' attribute must be empty", }, 155 xmlns = { code = 422, condition = "invalid-namespace", text = "'xmlns' attribute must be empty", },
156 name = { code = 422, condition = "unsupported-stanza-type", text = "Invalid stanza, must be 'message', 'presence' or 'iq'.", }, 156 name = { code = 422, condition = "unsupported-stanza-type", text = "Invalid stanza, must be 'message', 'presence' or 'iq'.", },
158 from = { code = 422, condition = "invalid-from", text = "Invalid source JID", }, 158 from = { code = 422, condition = "invalid-from", text = "Invalid source JID", },
159 post_auth = { code = 403, condition = "not-authorized", text = "Not authorized to send stanza with requested 'from'", }, 159 post_auth = { code = 403, condition = "not-authorized", text = "Not authorized to send stanza with requested 'from'", },
160 iq_type = { code = 422, condition = "invalid-xml", text = "'iq' stanza must be of type 'get' or 'set'", }, 160 iq_type = { code = 422, condition = "invalid-xml", text = "'iq' stanza must be of type 'get' or 'set'", },
161 iq_tags = { code = 422, condition = "bad-format", text = "'iq' stanza must have exactly one child tag", }, 161 iq_tags = { code = 422, condition = "bad-format", text = "'iq' stanza must have exactly one child tag", },
162 mediatype = { code = 415, condition = "bad-format", text = "Unsupported media type" }, 162 mediatype = { code = 415, condition = "bad-format", text = "Unsupported media type" },
163 }; 163 });
164 164
165 local function handle_post(event) 165 local function handle_post(event)
166 local request, response = event.request, event.response; 166 local request, response = event.request, event.response;
167 local from; 167 local from;
168 local origin; 168 local origin;
169 169
170 if not request.headers.authorization then 170 if not request.headers.authorization then
171 response.headers.www_authenticate = www_authenticate_header; 171 response.headers.www_authenticate = www_authenticate_header;
172 return errors.new("noauthz", nil, post_errors); 172 return post_errors.new("noauthz");
173 else 173 else
174 origin = check_credentials(request); 174 origin = check_credentials(request);
175 if not origin then 175 if not origin then
176 return errors.new("unauthz", nil, post_errors); 176 return post_errors.new("unauthz");
177 end 177 end
178 from = jid.join(origin.username, origin.host, origin.resource); 178 from = jid.join(origin.username, origin.host, origin.resource);
179 end 179 end
180 local payload, err = parse(request.headers.content_type, request.body); 180 local payload, err = parse(request.headers.content_type, request.body);
181 if not payload then 181 if not payload then
182 -- parse fail 182 -- parse fail
183 local ctx = { error = err, type = request.headers.content_type, data = request.body, }; 183 local ctx = { error = err, type = request.headers.content_type, data = request.body, };
184 if err == "unknown-payload-type" then 184 if err == "unknown-payload-type" then
185 return errors.new("mediatype", ctx, post_errors); 185 return post_errors.new("mediatype", ctx);
186 end 186 end
187 return errors.new("parse", ctx, post_errors); 187 return post_errors.new("parse", ctx);
188 end 188 end
189 189
190 if payload.attr.xmlns then 190 if payload.attr.xmlns then
191 return errors.new("xmlns", nil, post_errors); 191 return post_errors.new("xmlns");
192 elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then 192 elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then
193 return errors.new("name", nil, post_errors); 193 return post_errors.new("name");
194 end 194 end
195 195
196 local to = jid.prep(payload.attr.to); 196 local to = jid.prep(payload.attr.to);
197 if not to then 197 if not to then
198 return errors.new("to", nil, post_errors); 198 return post_errors.new("to");
199 end 199 end
200 200
201 if payload.attr.from then 201 if payload.attr.from then
202 local requested_from = jid.prep(payload.attr.from); 202 local requested_from = jid.prep(payload.attr.from);
203 if not requested_from then 203 if not requested_from then
204 return errors.new("from", nil, post_errors); 204 return post_errors.new("from");
205 end 205 end
206 if jid.compare(requested_from, from) then 206 if jid.compare(requested_from, from) then
207 from = requested_from; 207 from = requested_from;
208 else 208 else
209 return errors.new("from_auth", nil, post_errors); 209 return post_errors.new("from_auth");
210 end 210 end
211 end 211 end
212 212
213 payload.attr = { 213 payload.attr = {
214 from = from, 214 from = from,
224 function origin.send(stanza) 224 function origin.send(stanza)
225 module:send(stanza); 225 module:send(stanza);
226 end 226 end
227 227
228 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then 228 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then
229 return errors.new("iq_type", nil, post_errors); 229 return post_errors.new("iq_type");
230 elseif #payload.tags ~= 1 then 230 elseif #payload.tags ~= 1 then
231 return errors.new("iq_tags", nil, post_errors); 231 return post_errors.new("iq_tags");
232 end 232 end
233 233
234 return module:send_iq(payload, origin):next( 234 return module:send_iq(payload, origin):next(
235 function (result) 235 function (result)
236 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); 236 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag());