Comparison

mod_muc_http_defaults/mod_muc_http_defaults.lua @ 4448:5879ca1f7853

mod_muc_http_defaults: Remove fancy to be 0.11-compatible
author Kim Alvefur <zash@zash.se>
date Fri, 19 Feb 2021 19:50:21 +0100
parent 4447:07aa101a1ae7
child 4449:c25eef56e9c9
comparison
equal deleted inserted replaced
4447:07aa101a1ae7 4448:5879ca1f7853
3 -- This file is MIT licensed. Please see the 3 -- This file is MIT licensed. Please see the
4 -- COPYING file in the source package for more information. 4 -- COPYING file in the source package for more information.
5 -- 5 --
6 6
7 local http = require "net.http"; 7 local http = require "net.http";
8 local httperr = require "net.http.errors";
9 local async = require "util.async"; 8 local async = require "util.async";
10 local errors = require "util.error";
11 local uh = require "util.http"; 9 local uh = require "util.http";
12 local jid = require "util.jid"; 10 local jid = require "util.jid";
13 local json = require "util.json"; 11 local json = require "util.json";
14 local st = require "util.stanza"; 12 local st = require "util.stanza";
15 13
25 accept = "application/json"; 23 accept = "application/json";
26 authorization = apiauth; 24 authorization = apiauth;
27 } 25 }
28 }; 26 };
29 27
30 local function check_status(response) 28 local problems = {
31 if math.floor(response.code/100) > 2 then 29 format = "API server returned invalid data, see logs",
32 error(httperr.new(response.code, response.body)); 30 config = "A problem occured while creating the room, see logs",
33 end 31 };
34 return response;
35 end
36
37 local problems = errors.init(module.name, {
38 format = { type = "cancel", condition = "internal-server-error", text = "API server returned invalid data, see logs" },
39 config = { type = "cancel", condition = "internal-server-error", text = "A problem occured while creating the room, see logs" },
40 });
41
42 local function get_json(response)
43 return assert(json.decode(response.body), problems.new("format"));
44 end
45 32
46 local function apply_config(room, settings) 33 local function apply_config(room, settings)
47 local affiliations = settings.affiliations; 34 local affiliations = settings.affiliations;
48 if type(affiliations) == "table" then 35 if type(affiliations) == "table" then
49 36
59 local prepped_jid = jid.prep(aff.jid); 46 local prepped_jid = jid.prep(aff.jid);
60 if prepped_jid then 47 if prepped_jid then
61 local ok, err = room:set_affiliation(true, prepped_jid, aff.affiliation, aff.nick and { nick = aff.nick }); 48 local ok, err = room:set_affiliation(true, prepped_jid, aff.affiliation, aff.nick and { nick = aff.nick });
62 if not ok then 49 if not ok then
63 module:log("error", "Could not set affiliation in %s: %s", room.jid, err); 50 module:log("error", "Could not set affiliation in %s: %s", room.jid, err);
64 return nil, problems.new("config"); 51 return nil, "config";
65 end 52 end
66 else 53 else
67 module:log("error", "Invalid JID returned from API for %s: %q", room.jid, aff.jid); 54 module:log("error", "Invalid JID returned from API for %s: %q", room.jid, aff.jid);
68 return nil, problems.new("format"); 55 return nil, "format";
69 end 56 end
70 else 57 else
71 module:log("error", "Invalid affiliation item returned from API for %s: %q", room.jid, aff); 58 module:log("error", "Invalid affiliation item returned from API for %s: %q", room.jid, aff);
72 return nil, problems.new("format"); 59 return nil, "format";
73 end 60 end
74 end 61 end
75 else -- map of jid : affiliation 62 else -- map of jid : affiliation
76 for user_jid, aff in pairs(affiliations) do 63 for user_jid, aff in pairs(affiliations) do
77 if type(user_jid) == "string" and type(aff) == "string" then 64 if type(user_jid) == "string" and type(aff) == "string" then
78 local prepped_jid = jid.prep(user_jid); 65 local prepped_jid = jid.prep(user_jid);
79 if prepped_jid then 66 if prepped_jid then
80 local ok, err = room:set_affiliation(true, prepped_jid, aff); 67 local ok, err = room:set_affiliation(true, prepped_jid, aff);
81 if not ok then 68 if not ok then
82 module:log("error", "Could not set affiliation in %s: %s", room.jid, err); 69 module:log("error", "Could not set affiliation in %s: %s", room.jid, err);
83 return nil, problems.new("config"); 70 return nil, "config";
84 end 71 end
85 else 72 else
86 module:log("error", "Invalid JID returned from API: %q", aff.jid); 73 module:log("error", "Invalid JID returned from API: %q", aff.jid);
87 return nil, problems.new("format"); 74 return nil, "format";
88 end 75 end
89 end 76 end
90 end 77 end
91 end 78 end
92 elseif affiliations ~= nil then 79 elseif affiliations ~= nil then
93 module:log("error", "Invalid affiliations returned from API for %s: %q", room.jid, affiliations); 80 module:log("error", "Invalid affiliations returned from API for %s: %q", room.jid, affiliations);
94 return nil, problems.new("format", { field = "affiliations" }); 81 return nil, "format", { field = "affiliations" };
95 end 82 end
96 83
97 local config = settings.config; 84 local config = settings.config;
98 if type(config) == "table" then 85 if type(config) == "table" then
99 -- TODO reject invalid fields instead of ignoring them 86 -- TODO reject invalid fields instead of ignoring them
116 103
117 -- mod_muc_mam 104 -- mod_muc_mam
118 if type(config.archiving) == "boolean" then room._config.archiving = config.archiving; end 105 if type(config.archiving) == "boolean" then room._config.archiving = config.archiving; end
119 elseif config ~= nil then 106 elseif config ~= nil then
120 module:log("error", "Invalid config returned from API for %s: %q", room.jid, config); 107 module:log("error", "Invalid config returned from API for %s: %q", room.jid, config);
121 return nil, problems.new("format", { field = "config" }); 108 return nil, "format", { field = "config" };
122 end 109 end
123 return true; 110 return true;
124 end 111 end
125 112
126 module:hook("muc-room-pre-create", function(event) 113 module:hook("muc-room-pre-create", function(event)
127 local url = render(url_template, event); 114 local url = render(url_template, event);
128 module:log("debug", "Calling API at %q for room %s", url, event.room.jid); 115 module:log("debug", "Calling API at %q for room %s", url, event.room.jid);
129 local ret, err = errors.coerce(async.wait_for(http.request(url, ex):next(check_status):next(get_json))); 116 local wait, done = async.waiter();
117
118 local ret, err;
119 http.request(url, ex, function (code, body)
120 if math.floor(code / 100) == 2 then
121 local parsed, parse_err = json.decode(body);
122 if not parsed then
123 module:log("debug", "Got invalid JSON from %s: %s", url, parse_err);
124 err = problems.format;
125 else
126 ret = parsed;
127 end
128 else
129 module:log("debug", "Rejected by API: ", body);
130 err = "Rejected by API";
131 end
132
133 done()
134 end);
135
136 wait();
130 if not ret then 137 if not ret then
131 event.room:destroy(); 138 event.room:destroy();
132 event.origin.send(st.error_reply(event.stanza, err)); 139 event.origin.send(st.error_reply(event.stanza, "cancel", "internal-server-error", err, module.host));
133 return true; 140 return true;
134 end 141 end
135 142
136 local configured, err = apply_config(event.room, ret); 143 local configured, err = apply_config(event.room, ret);
137 if not configured then 144 if not configured then
138 event.room:destroy(); 145 event.room:destroy();
139 event.origin.send(st.error_reply(event.stanza, err)); 146 event.origin.send(st.error_reply(event.stanza, "cancel", "internal-server-error", err, event.room.jid or module.host));
140 return true; 147 return true;
141 end 148 end
142 end, -2); 149 end, -2);