Software /
code /
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 |
child | 3115: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); |