Mercurial > prosody-modules
annotate mod_muc_http_auth/mod_muc_http_auth.lua @ 5186:fa3059e653fa
mod_http_oauth2: Implement the Implicit flow
Everyone says this is insecure and bad, but it's also the only thing
that makes sense for e.g. pure JavaScript clients, but hey implement
this even more complicated thing instead!
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 02 Mar 2023 22:06:50 +0100 |
parents | b125db92bac6 |
children |
rev | line source |
---|---|
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
1 local http = require "net.http"; |
4723
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
2 local jid_bare = require "util.jid".bare; |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
3 local jid_host = require "util.jid".host; |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
4 local jid_node = require "util.jid".node; |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
5 local jid_resource = require "util.jid".resource; |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
6 local json = require "util.json"; |
4724
b125db92bac6
mod_muc_http_auth: Add missing import
JC Brand <jc@opkode.com>
parents:
4723
diff
changeset
|
7 local set = require "util.set"; |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
8 local st = require "util.stanza"; |
4696
6a05c9eb964e
mod_muc_http_auth: Make sure query parameters are URL encoded
Seve Ferrer <seve@delape.net>
parents:
4695
diff
changeset
|
9 local urlencode = require "util.http".urlencode; |
4723
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
10 local wait_for = require "util.async".wait_for; |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
11 |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
12 local authorization_url = module:get_option("muc_http_auth_url", "") |
4723
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
13 local enabled_for = module:get_option("muc_http_auth_enabled_for", nil) |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
14 local disabled_for = module:get_option("muc_http_auth_disabled_for", nil) |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
15 local insecure = module:get_option("muc_http_auth_insecure", false) --For development purposes |
4299
8006da2cf44c
For deployments that have https://hg.prosody.im/trunk/file/tip/plugins/muc/register.lib.lua#l7 and use https://modules.prosody.im/mod_muc_http_auth.html users can still register to a MUC even if they are not allowed to join. That means they would receive RAI or RMN, for instance.
Seve Ferrer <seve@delape.net>
parents:
4296
diff
changeset
|
16 local authorize_registration = module:get_option("muc_http_auth_authorize_registration", false) |
4322
9606e7a63a69
mod_mucc_http_auth: Provide Authorization header setting for deployments behind a login
Seve Ferrer <seve@delape.net>
parents:
4319
diff
changeset
|
17 local authorization_header = module:get_option("muc_http_auth_authorization_header", nil) |
9606e7a63a69
mod_mucc_http_auth: Provide Authorization header setting for deployments behind a login
Seve Ferrer <seve@delape.net>
parents:
4319
diff
changeset
|
18 |
9606e7a63a69
mod_mucc_http_auth: Provide Authorization header setting for deployments behind a login
Seve Ferrer <seve@delape.net>
parents:
4319
diff
changeset
|
19 local options = {method="GET", insecure=insecure} |
9606e7a63a69
mod_mucc_http_auth: Provide Authorization header setting for deployments behind a login
Seve Ferrer <seve@delape.net>
parents:
4319
diff
changeset
|
20 if authorization_header then |
9606e7a63a69
mod_mucc_http_auth: Provide Authorization header setting for deployments behind a login
Seve Ferrer <seve@delape.net>
parents:
4319
diff
changeset
|
21 options.headers = {["Authorization"] = authorization_header}; |
9606e7a63a69
mod_mucc_http_auth: Provide Authorization header setting for deployments behind a login
Seve Ferrer <seve@delape.net>
parents:
4319
diff
changeset
|
22 end |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
23 |
4304
aec8148df26a
mod_muc_http_auth: Bugfix: Not properly listening on register IQs
Seve Ferrer <seve@delape.net>
parents:
4303
diff
changeset
|
24 local verbs = {presence='join', iq='register'}; |
aec8148df26a
mod_muc_http_auth: Bugfix: Not properly listening on register IQs
Seve Ferrer <seve@delape.net>
parents:
4303
diff
changeset
|
25 |
4723
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
26 local function must_be_authorized(room_node, user_host) |
4303
d261233f7ced
Improve UX by providing defaults users expect
Seve Ferrer <seve@delape.net>
parents:
4301
diff
changeset
|
27 -- If none of these is set, all rooms need authorization |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
28 if not enabled_for and not disabled_for then return true; end |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
29 |
4723
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
30 if enabled_for then |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
31 local enabled_for_host = set.new(enabled_for[user_host] or {}); |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
32 local enabled_for_all = set.new(enabled_for['all'] or {}); |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
33 return enabled_for_host:contains(room_node) or enabled_for_all:contains(room_node); |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
34 |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
35 end |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
36 if disabled_for then |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
37 local disabled_for_host = set.new(disabled_for[user_host] or {}); |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
38 local disabled_for_all = set.new(disabled_for['all'] or {}); |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
39 return not disabled_for_host:contains(room_node) and not disabled_for_all:contains(room_node); |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
40 end |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
41 end |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
42 |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
43 local function handle_success(response) |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
44 local body = json.decode(response.body or "") or {} |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
45 response = { |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
46 err = body.error, |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
47 allowed = body.allowed, |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
48 code = response.code |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
49 } |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
50 return {response=response, err=response.err}; |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
51 end |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
52 |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
53 local function handle_error(err) |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
54 return {err=err}; |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
55 end |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
56 |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
57 local function handle_presence(event) |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
58 local stanza = event.stanza; |
4304
aec8148df26a
mod_muc_http_auth: Bugfix: Not properly listening on register IQs
Seve Ferrer <seve@delape.net>
parents:
4303
diff
changeset
|
59 if stanza.name ~= "iq" and stanza.name ~= "presence" or stanza.attr.type == "unavailable" then return; end |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
60 |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
61 local room, origin = event.room, event.origin; |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
62 if (not room) or (not origin) then return; end |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
63 |
4723
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
64 local user_bare_jid = jid_bare(stanza.attr.from) |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
65 if not must_be_authorized(jid_node(room.jid), jid_host(user_bare_jid)) then |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
66 module:log("debug", "Authorization not required for "..jid_node(room.jid).." and "..jid_host(user_bare_jid)) |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
67 return; |
0a0334a3a784
mod_muc_http_auth: Allow for enabling/disabling per user host
JC Brand <jc@opkode.com>
parents:
4697
diff
changeset
|
68 end |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
69 |
4695
4b3f054666e6
mod_muc_http_auth: External auth services might need to check on the nickname as well
Seve Ferrer <seve@delape.net>
parents:
4322
diff
changeset
|
70 local user_nickname = jid_resource(stanza.attr.to); |
4b3f054666e6
mod_muc_http_auth: External auth services might need to check on the nickname as well
Seve Ferrer <seve@delape.net>
parents:
4322
diff
changeset
|
71 |
4b3f054666e6
mod_muc_http_auth: External auth services might need to check on the nickname as well
Seve Ferrer <seve@delape.net>
parents:
4322
diff
changeset
|
72 -- Nickname is mandatory to enter a MUC |
4b3f054666e6
mod_muc_http_auth: External auth services might need to check on the nickname as well
Seve Ferrer <seve@delape.net>
parents:
4322
diff
changeset
|
73 if not user_nickname then return; end |
4b3f054666e6
mod_muc_http_auth: External auth services might need to check on the nickname as well
Seve Ferrer <seve@delape.net>
parents:
4322
diff
changeset
|
74 |
4697
15c335dc196e
mod_muc_http_auth: Make sure query parameters are URL encoded
Seve Ferrer <seve@delape.net>
parents:
4696
diff
changeset
|
75 local url = authorization_url .. "?userJID=" .. urlencode(user_bare_jid) .."&mucJID=" .. urlencode(room.jid) .. "&nickname=" .. urlencode(user_nickname); |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
76 |
4322
9606e7a63a69
mod_mucc_http_auth: Provide Authorization header setting for deployments behind a login
Seve Ferrer <seve@delape.net>
parents:
4319
diff
changeset
|
77 local result = wait_for(http.request(url, options):next(handle_success, handle_error)); |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
78 local response, err = result.response, result.err; |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
79 |
4304
aec8148df26a
mod_muc_http_auth: Bugfix: Not properly listening on register IQs
Seve Ferrer <seve@delape.net>
parents:
4303
diff
changeset
|
80 local verb = verbs[stanza.name]; |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
81 if not (response and response.allowed) then |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
82 -- User is not authorized to join this room |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
83 err = (response or {}).err or err |
4304
aec8148df26a
mod_muc_http_auth: Bugfix: Not properly listening on register IQs
Seve Ferrer <seve@delape.net>
parents:
4303
diff
changeset
|
84 module:log("debug", user_bare_jid .. " is not authorized to " ..verb.. ": " .. room.jid .. " Error: " .. tostring(err)); |
4319
caaa40f072da
mod_muc_http_auth: `no-authorized` error must be of type `auth`
JC Brand <jc@opkode.com>
parents:
4304
diff
changeset
|
85 origin.send(st.error_reply(stanza, "auth", "not-authorized", nil, module.host)); |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
86 return true; |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
87 end |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
88 |
4304
aec8148df26a
mod_muc_http_auth: Bugfix: Not properly listening on register IQs
Seve Ferrer <seve@delape.net>
parents:
4303
diff
changeset
|
89 module:log("debug", user_bare_jid .. " is authorized to " .. verb .. ": " .. room.jid); |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
90 return; |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
91 end |
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
92 |
4299
8006da2cf44c
For deployments that have https://hg.prosody.im/trunk/file/tip/plugins/muc/register.lib.lua#l7 and use https://modules.prosody.im/mod_muc_http_auth.html users can still register to a MUC even if they are not allowed to join. That means they would receive RAI or RMN, for instance.
Seve Ferrer <seve@delape.net>
parents:
4296
diff
changeset
|
93 if authorize_registration then |
8006da2cf44c
For deployments that have https://hg.prosody.im/trunk/file/tip/plugins/muc/register.lib.lua#l7 and use https://modules.prosody.im/mod_muc_http_auth.html users can still register to a MUC even if they are not allowed to join. That means they would receive RAI or RMN, for instance.
Seve Ferrer <seve@delape.net>
parents:
4296
diff
changeset
|
94 module:hook("muc-register-iq", handle_presence); |
8006da2cf44c
For deployments that have https://hg.prosody.im/trunk/file/tip/plugins/muc/register.lib.lua#l7 and use https://modules.prosody.im/mod_muc_http_auth.html users can still register to a MUC even if they are not allowed to join. That means they would receive RAI or RMN, for instance.
Seve Ferrer <seve@delape.net>
parents:
4296
diff
changeset
|
95 end |
4296
08138de4cb88
Prosodoy module to externalize MUC authorization via HTTP
Seve Ferrer <seve@delape.net>
parents:
diff
changeset
|
96 |
4319
caaa40f072da
mod_muc_http_auth: `no-authorized` error must be of type `auth`
JC Brand <jc@opkode.com>
parents:
4304
diff
changeset
|
97 module:hook("muc-occupant-pre-join", handle_presence); |