annotate mod_auth_http/mod_auth_http.lua @ 5448:9d542e86e19a

mod_http_oauth2: Allow requesting a subset of scopes on token refresh This enables clients to request access tokens with fewer permissions than the grant they were given, reducing impact of token leak. Clients could e.g. request access tokens with some privileges and immediately revoke them after use, or other strategies.
author Kim Alvefur <zash@zash.se>
date Thu, 11 May 2023 21:40:09 +0200
parents 8862a80cbd00
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4157
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 -- Prosody IM
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 -- Copyright (C) 2008-2013 Matthew Wild
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 -- Copyright (C) 2008-2013 Waqas Hussain
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 -- Copyright (C) 2014 Kim Alvefur
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 --
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 -- This project is MIT/X11 licensed. Please see the
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 -- COPYING file in the source package for more information.
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 --
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 local new_sasl = require "util.sasl".new;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 local base64 = require "util.encodings".base64.encode;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 local have_async, async = pcall(require, "util.async");
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 local http = require "net.http";
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 if not have_async then
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 error("Your version of Prosody does not support async and is incompatible");
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 local host = module.host;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 local api_base = module:get_option_string("http_auth_url", ""):gsub("$host", host);
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 if api_base == "" then error("http_auth_url required") end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 api_base = api_base:gsub("/$", "");
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 local auth_creds = module:get_option_string("http_auth_credentials");
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 local method_types = {
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 -- Unlisted methods default to GET
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 register = "POST";
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 set_password = "POST";
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 remove_user = "POST";
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 };
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 local provider = {};
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 local function make_request(method_name, params)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 local wait, done = async.waiter();
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 local method_type = method_types[method_name] or "GET";
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 params.server = params.server or host;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 local encoded_params = http.formencode(params);
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 local url;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 local ex = {
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 method = method_type;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 headers = { Authorization = auth_creds and ("Basic "..base64(auth_creds)) or nil; };
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 }
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 if method_type == "POST" then
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 url = api_base.."/"..method_name;
4454
8862a80cbd00 mod_auth_http: type fix #1621
Ben
parents: 4157
diff changeset
51 ex.headers["Content-Type"] = "application/x-www-form-urlencoded";
4157
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 ex.body = encoded_params;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 else
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 url = api_base.."/"..method_name.."?"..encoded_params;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 local content, code;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 local function cb(content_, code_)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 content, code = content_, code_;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 done();
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 http.request(url, ex, cb);
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 wait();
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 return code, content;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 function provider.test_password(username, password)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 local code, body = make_request("check_password", { user = username, pass = password });
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 if code == 200 and body == "true" then
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 return true;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 return false;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 function provider.users()
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 return function()
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 return nil;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 function provider.set_password(username, password)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 local code = make_request("set_password", { user = username, pass = password });
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 if code == 200 or code == 201 or code == 204 then
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 return true;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 return false;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 function provider.user_exists(username)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 local code, body = make_request("user_exists", { user = username });
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 if code == 200 and body == "true" then
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 return true;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 return false;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 function provider.create_user(username, password)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 local code = make_request("register", { user = username, pass = password });
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 if code == 201 then
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 return true;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 return false;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 function provider.delete_user(username)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 local code = make_request("remove_user", { user = username });
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 if code == 200 or code == 201 or code == 204 then
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 return true;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 return false;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 function provider.get_sasl_handler()
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 return new_sasl(host, {
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 --luacheck: ignore 212/sasl 212/realm
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 plain_test = function(sasl, username, password, realm)
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 return provider.test_password(username, password), true;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 end;
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 });
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 end
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121
93b12bfd7aa8 mod_auth_http: Yet another module to authenticate against a HTTP service
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 module:provides("auth", provider);