Mercurial > 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 |
| parents | |
| children | 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); |
