Mercurial > prosody-modules
comparison mod_auth_oauthbearer/mod_auth_oauthbearer.lua @ 3114:73ada978dabc
mod_sasl_oauthbearer and mod_auth_oauthbearer
Two new modules for logging in with OAuth tokens.
| author | JC Brand <jc@opkode.com> |
|---|---|
| date | Wed, 13 Jun 2018 17:09:49 +0000 |
| parents | |
| children | d2bf9c8be3a3 |
comparison
equal
deleted
inserted
replaced
| 3113:8298b06e6603 | 3114:73ada978dabc |
|---|---|
| 1 local host = module.host; | |
| 2 local log = module._log; | |
| 3 local new_sasl = require "util.sasl".new; | |
| 4 local base64 = require "util.encodings".base64.encode; | |
| 5 | |
| 6 local provider = {}; | |
| 7 | |
| 8 local oauth_client_id = module:get_option_string("oauth_client_id", ""); | |
| 9 local oauth_client_secret = module:get_option_string("oauth_client_secret", ""); | |
| 10 local oauth_url = module:get_option_string("oauth_url", ""); | |
| 11 | |
| 12 if oauth_client_id == "" then error("oauth_client_id required") end | |
| 13 if oauth_client_secret == "" then error("oauth_client_secret required") end | |
| 14 if oauth_url == "" then error("oauth_url required") end | |
| 15 | |
| 16 -- globals required by socket.http | |
| 17 if rawget(_G, "PROXY") == nil then | |
| 18 rawset(_G, "PROXY", false) | |
| 19 end | |
| 20 if rawget(_G, "base_parsed") == nil then | |
| 21 rawset(_G, "base_parsed", false) | |
| 22 end | |
| 23 | |
| 24 local function interp(s, tab) | |
| 25 -- String interpolation, so that we can make the oauth_url configurable | |
| 26 -- e.g. oauth_url = "https://api.github.com/applications/{{oauth_client_id}}/tokens/{{password}}"; | |
| 27 -- | |
| 28 -- See: http://lua-users.org/wiki/StringInterpolation | |
| 29 return (s:gsub('(%b{})', function(w) return tab[w:sub(3, -3)] or w end)) | |
| 30 end | |
| 31 | |
| 32 function provider.test_password(sasl, username, password, realm) | |
| 33 log("debug", "Testing signed OAuth2 for user %s at realm %s", username, realm); | |
| 34 -- TODO: determine, based on the "realm" which OAuth provider to verify with. | |
| 35 module:log("debug", "sync_http_auth()"); | |
| 36 local https = require "ssl.https"; | |
| 37 local url = interp(oauth_url, {oauth_client_id = oauth_client_id, password = password}); | |
| 38 | |
| 39 module:log("debug", "The URL is: "..url); | |
| 40 local _, code, headers, status = https.request{ | |
| 41 url = url, | |
| 42 headers = { | |
| 43 Authorization = "Basic "..base64(oauth_client_id..":"..oauth_client_secret); | |
| 44 } | |
| 45 }; | |
| 46 if type(code) == "number" and code >= 200 and code <= 299 then | |
| 47 module:log("debug", "OAuth provider confirmed valid password"); | |
| 48 return 'johnny', true; | |
| 49 else | |
| 50 module:log("warn", "OAuth provider returned status code: "..code); | |
| 51 end | |
| 52 module:log("warn", "OAuth failed. Invalid username or password."); | |
| 53 return nil, false; | |
| 54 end | |
| 55 | |
| 56 function provider.users() | |
| 57 return function() | |
| 58 return nil; | |
| 59 end | |
| 60 end | |
| 61 | |
| 62 function provider.set_password(username, password) | |
| 63 return nil, "Changing passwords not supported"; | |
| 64 end | |
| 65 | |
| 66 function provider.user_exists(username) | |
| 67 return true; | |
| 68 end | |
| 69 | |
| 70 function provider.create_user(username, password) | |
| 71 return nil, "User creation not supported"; | |
| 72 end | |
| 73 | |
| 74 function provider.delete_user(username) | |
| 75 return nil , "User deletion not supported"; | |
| 76 end | |
| 77 | |
| 78 function provider.get_sasl_handler() | |
| 79 local supported_mechanisms = {}; | |
| 80 supported_mechanisms["OAUTHBEARER"] = true; | |
| 81 | |
| 82 return new_sasl(host, { | |
| 83 oauthbearer = function(sasl, username, password, realm) | |
| 84 return provider.test_password(sasl, username, password, realm); | |
| 85 end, | |
| 86 mechanisms = supported_mechanisms | |
| 87 }); | |
| 88 end | |
| 89 | |
| 90 module:provides("auth", provider); |
