Mercurial > prosody-modules
comparison mod_auth_http_async/mod_auth_http_async.lua @ 2629:a11568bfaf4c
mod_auth_http_async: For sync calls, use LuaSockets' HTTP lib
author | JC Brand <jc@opkode.com> |
---|---|
date | Tue, 21 Mar 2017 09:14:03 +0000 |
parents | b2a198665946 |
children | 96eb1c4f9ff7 |
comparison
equal
deleted
inserted
replaced
2628:fbb26a56a667 | 2629:a11568bfaf4c |
---|---|
6 -- This project is MIT/X11 licensed. Please see the | 6 -- This project is MIT/X11 licensed. Please see the |
7 -- COPYING file in the source package for more information. | 7 -- COPYING file in the source package for more information. |
8 -- | 8 -- |
9 | 9 |
10 local new_sasl = require "util.sasl".new; | 10 local new_sasl = require "util.sasl".new; |
11 local http = require "socket.http"; | |
12 local https = require "ssl.https"; | |
11 local base64 = require "util.encodings".base64.encode; | 13 local base64 = require "util.encodings".base64.encode; |
12 local have_async, async = pcall(require, "util.async"); | 14 local have_async, async = pcall(require, "util.async"); |
13 local http = require "net.http"; | |
14 | 15 |
15 local log = module._log; | 16 local log = module._log; |
16 local host = module.host; | 17 local host = module.host; |
17 | 18 |
18 local api_base = module:get_option_string("http_auth_url", ""):gsub("$host", host); | 19 local api_base = module:get_option_string("http_auth_url", ""):gsub("$host", host); |
19 if api_base == "" then error("http_auth_url required") end | 20 if api_base == "" then error("http_auth_url required") end |
20 | 21 |
21 local function async_http_request(url, ex) | 22 local provider = {}; |
23 | |
24 -- globals required by socket.http | |
25 if rawget(_G, "PROXY") == nil then | |
26 rawset(_G, "PROXY", false) | |
27 end | |
28 if rawget(_G, "base_parsed") == nil then | |
29 rawset(_G, "base_parsed", false) | |
30 end | |
31 | |
32 local function async_http_auth(url, username, password) | |
22 local wait, done = async.waiter(); | 33 local wait, done = async.waiter(); |
23 local content, code, request, response; | 34 local content, code, request, response; |
35 local ex = { | |
36 headers = { Authorization = "Basic "..base64(username..":"..password); }; | |
37 } | |
24 local function cb(content_, code_, request_, response_) | 38 local function cb(content_, code_, request_, response_) |
25 content, code, request, response = content_, code_, request_, response_; | 39 content, code, request, response = content_, code_, request_, response_; |
26 done(); | 40 done(); |
27 end | 41 end |
28 http.request(url, ex, cb); | 42 http.request(url, ex, cb); |
29 wait(); | 43 wait(); |
30 return content, code, request, response; | 44 if code >= 200 and code <= 299 then |
45 module:log("debug", "HTTP auth provider confirmed valid password"); | |
46 return true; | |
47 else | |
48 module:log("debug", "HTTP auth provider returned status code %d", code); | |
49 end | |
50 return nil, "Auth failed. Invalid username or password."; | |
31 end | 51 end |
32 | 52 |
33 local provider = {}; | 53 local function sync_http_auth(url) |
54 local request; | |
55 if string.sub(url, 1, string.len('https')) == 'https' then | |
56 request = https.request; | |
57 else | |
58 request = http.request; | |
59 end | |
60 local _, code, headers, status = request{ | |
61 url = url, | |
62 headers = { ACCEPT = "application/json, text/plain, */*"; } | |
63 }; | |
64 if type(code) == "number" and code >= 200 and code <= 299 then | |
65 module:log("debug", "HTTP auth provider confirmed valid password"); | |
66 return true; | |
67 else | |
68 module:log("debug", "HTTP auth provider returned status code: "..code); | |
69 end | |
70 return nil, "Auth failed. Invalid username or password."; | |
71 end | |
34 | 72 |
35 function provider.test_password(username, password) | 73 function provider.test_password(username, password) |
36 local url = api_base:gsub("$user", username); | 74 local url = api_base:gsub("$user", username):gsub("$password", password); |
37 log("debug", "Testing password for user %s at host %s with URL %s", username, host, url); | 75 log("debug", "Testing password for user %s at host %s with URL %s", username, host, url); |
38 local ex = { | |
39 headers = { Authorization = "Basic "..base64(username..":"..password); }; | |
40 } | |
41 if (have_async) then | 76 if (have_async) then |
42 local _, code = async_http_request(url, ex); | 77 return async_http_auth(url, username, password); |
43 if code >= 200 and code <= 299 then | |
44 module:log("debug", "HTTP auth provider confirmed valid password"); | |
45 return true; | |
46 else | |
47 module:log("debug", "HTTP auth provider returned status code %d", code); | |
48 end | |
49 else | 78 else |
50 local ok, err = http.request(url, ex, function(body, code) | 79 return sync_http_auth(url); |
51 if code >= 200 and code <= 299 then | |
52 module:log("debug", "HTTP auth provider confirmed valid password"); | |
53 else | |
54 module:log("debug", "HTTP auth provider returned status code %d", code); | |
55 end | |
56 end); | |
57 if ok then | |
58 return true; | |
59 end | |
60 end | 80 end |
61 return nil, "Auth failed. Invalid username or password."; | 81 end |
82 | |
83 function provider.users() | |
84 return function() | |
85 return nil; | |
86 end | |
62 end | 87 end |
63 | 88 |
64 function provider.set_password(username, password) | 89 function provider.set_password(username, password) |
65 return nil, "Changing passwords not supported"; | 90 return nil, "Changing passwords not supported"; |
66 end | 91 end |
82 plain_test = function(sasl, username, password, realm) | 107 plain_test = function(sasl, username, password, realm) |
83 return provider.test_password(username, password), true; | 108 return provider.test_password(username, password), true; |
84 end | 109 end |
85 }); | 110 }); |
86 end | 111 end |
87 | 112 |
88 module:provides("auth", provider); | 113 module:provides("auth", provider); |