Mercurial > prosody-modules
comparison mod_auth_http/mod_auth_http.lua @ 4157:93b12bfd7aa8
mod_auth_http: Yet another module to authenticate against a HTTP service
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 30 Sep 2020 13:20:11 +0100 |
parents | |
children | 8862a80cbd00 |
comparison
equal
deleted
inserted
replaced
4156:b79904446d9e | 4157:93b12bfd7aa8 |
---|---|
1 -- Prosody IM | |
2 -- Copyright (C) 2008-2013 Matthew Wild | |
3 -- Copyright (C) 2008-2013 Waqas Hussain | |
4 -- Copyright (C) 2014 Kim Alvefur | |
5 -- | |
6 -- This project is MIT/X11 licensed. Please see the | |
7 -- COPYING file in the source package for more information. | |
8 -- | |
9 | |
10 local new_sasl = require "util.sasl".new; | |
11 local base64 = require "util.encodings".base64.encode; | |
12 local have_async, async = pcall(require, "util.async"); | |
13 local http = require "net.http"; | |
14 | |
15 if not have_async then | |
16 error("Your version of Prosody does not support async and is incompatible"); | |
17 end | |
18 | |
19 local host = module.host; | |
20 | |
21 local api_base = module:get_option_string("http_auth_url", ""):gsub("$host", host); | |
22 if api_base == "" then error("http_auth_url required") end | |
23 api_base = api_base:gsub("/$", ""); | |
24 | |
25 local auth_creds = module:get_option_string("http_auth_credentials"); | |
26 | |
27 local method_types = { | |
28 -- Unlisted methods default to GET | |
29 register = "POST"; | |
30 set_password = "POST"; | |
31 remove_user = "POST"; | |
32 }; | |
33 | |
34 local provider = {}; | |
35 | |
36 local function make_request(method_name, params) | |
37 local wait, done = async.waiter(); | |
38 | |
39 local method_type = method_types[method_name] or "GET"; | |
40 | |
41 params.server = params.server or host; | |
42 local encoded_params = http.formencode(params); | |
43 | |
44 local url; | |
45 local ex = { | |
46 method = method_type; | |
47 headers = { Authorization = auth_creds and ("Basic "..base64(auth_creds)) or nil; }; | |
48 } | |
49 if method_type == "POST" then | |
50 url = api_base.."/"..method_name; | |
51 ex.headers["Content-Type"] = "application/x/www-form-urlencoded"; | |
52 ex.body = encoded_params; | |
53 else | |
54 url = api_base.."/"..method_name.."?"..encoded_params; | |
55 end | |
56 | |
57 local content, code; | |
58 local function cb(content_, code_) | |
59 content, code = content_, code_; | |
60 done(); | |
61 end | |
62 http.request(url, ex, cb); | |
63 wait(); | |
64 return code, content; | |
65 end | |
66 | |
67 function provider.test_password(username, password) | |
68 local code, body = make_request("check_password", { user = username, pass = password }); | |
69 if code == 200 and body == "true" then | |
70 return true; | |
71 end | |
72 return false; | |
73 end | |
74 | |
75 function provider.users() | |
76 return function() | |
77 return nil; | |
78 end | |
79 end | |
80 | |
81 function provider.set_password(username, password) | |
82 local code = make_request("set_password", { user = username, pass = password }); | |
83 if code == 200 or code == 201 or code == 204 then | |
84 return true; | |
85 end | |
86 return false; | |
87 end | |
88 | |
89 function provider.user_exists(username) | |
90 local code, body = make_request("user_exists", { user = username }); | |
91 if code == 200 and body == "true" then | |
92 return true; | |
93 end | |
94 return false; | |
95 end | |
96 | |
97 function provider.create_user(username, password) | |
98 local code = make_request("register", { user = username, pass = password }); | |
99 if code == 201 then | |
100 return true; | |
101 end | |
102 return false; | |
103 end | |
104 | |
105 function provider.delete_user(username) | |
106 local code = make_request("remove_user", { user = username }); | |
107 if code == 200 or code == 201 or code == 204 then | |
108 return true; | |
109 end | |
110 return false; | |
111 end | |
112 | |
113 function provider.get_sasl_handler() | |
114 return new_sasl(host, { | |
115 --luacheck: ignore 212/sasl 212/realm | |
116 plain_test = function(sasl, username, password, realm) | |
117 return provider.test_password(username, password), true; | |
118 end; | |
119 }); | |
120 end | |
121 | |
122 module:provides("auth", provider); |