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
parent 2442:b2a198665946
child 2630: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);