Software /
code /
prosody-modules
Comparison
mod_muc_http_auth/mod_muc_http_auth.lua @ 4296:08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
author | Seve Ferrer <seve@delape.net> |
---|---|
date | Sat, 12 Dec 2020 18:19:14 +0100 |
child | 4299:8006da2cf44c |
comparison
equal
deleted
inserted
replaced
4295:d44a8d3dd571 | 4296:08138de4cb88 |
---|---|
1 local wait_for = require "util.async".wait_for; | |
2 local http = require "net.http"; | |
3 local json = require "util.json"; | |
4 local st = require "util.stanza"; | |
5 local jid_node = require "util.jid".node; | |
6 local jid_bare = require "util.jid".bare; | |
7 | |
8 local authorization_url = module:get_option("muc_http_auth_url", "") | |
9 local enabled_for = module:get_option_set("muc_http_auth_enabled_for", nil) | |
10 local disabled_for = module:get_option_set("muc_http_auth_disabled_for", nil) | |
11 local insecure = module:get_option("muc_http_auth_insecure", false) --For development purposes | |
12 | |
13 local function must_be_authorized(room_node) | |
14 -- If none of these is set, all rooms need authorization | |
15 if not enabled_for and not disabled_for then return true; end | |
16 | |
17 if enabled_for and not disabled_for then | |
18 for _, _room_node in ipairs(enabled_for) do | |
19 if _room_node == room_node then | |
20 return true; | |
21 end | |
22 end | |
23 end | |
24 | |
25 if disabled_for and not enabled_for then | |
26 for _, _room_node in ipairs(disabled_for) do | |
27 if _room_node == room_node then | |
28 return false; | |
29 end | |
30 end | |
31 end | |
32 | |
33 return true; | |
34 end | |
35 | |
36 local function handle_success(response) | |
37 local body = json.decode(response.body or "") or {} | |
38 response = { | |
39 err = body.error, | |
40 allowed = body.allowed, | |
41 code = response.code | |
42 } | |
43 return {response=response, err=response.err}; | |
44 end | |
45 | |
46 local function handle_error(err) | |
47 return {err=err}; | |
48 end | |
49 | |
50 local function handle_presence(event) | |
51 local stanza = event.stanza; | |
52 if stanza.name ~= "presence" or stanza.attr.type == "unavailable" then | |
53 return; | |
54 end | |
55 | |
56 local room, origin = event.room, event.origin; | |
57 if (not room) or (not origin) then return; end | |
58 | |
59 if not must_be_authorized(jid_node(room.jid)) then return; end | |
60 | |
61 local user_bare_jid = jid_bare(stanza.attr.from); | |
62 local url = authorization_url .. "?userJID=" .. user_bare_jid .."&mucJID=" .. room.jid; | |
63 | |
64 local result = wait_for(http.request(url, {method="GET", insecure=insecure}):next(handle_success, handle_error)); | |
65 local response, err = result.response, result.err; | |
66 | |
67 if not (response and response.allowed) then | |
68 -- User is not authorized to join this room | |
69 err = (response or {}).err or err | |
70 module:log("debug", user_bare_jid .. " is not authorized to join " .. room.jid .. " Error: " .. tostring(err)); | |
71 origin.send(st.error_reply(stanza, "error", "not-authorized", nil, module.host)); | |
72 return true; | |
73 end | |
74 | |
75 module:log("debug", user_bare_jid .. " is authorized to join " .. room.jid); | |
76 return; | |
77 end | |
78 | |
79 | |
80 module:hook("muc-occupant-pre-join", handle_presence); |