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); |
