Mercurial > prosody-modules
comparison mod_http_oauth2/mod_http_oauth2.lua @ 3903:cfeb93b80621
mod_http_oauth2: OAuth2 API (work in progress for developers only)
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 23 Feb 2020 21:36:53 +0000 |
| parents | |
| children | 8ac5d9933106 |
comparison
equal
deleted
inserted
replaced
| 3902:341850e8866f | 3903:cfeb93b80621 |
|---|---|
| 1 module:set_global(); | |
| 2 | |
| 3 local http = require "util.http"; | |
| 4 local jid = require "util.jid"; | |
| 5 local json = require "util.json"; | |
| 6 local usermanager = require "core.usermanager"; | |
| 7 local errors = require "util.error"; | |
| 8 | |
| 9 local function oauth_error(err_name, err_desc) | |
| 10 return errors.new({ | |
| 11 type = "modify"; | |
| 12 condition = "bad-request"; | |
| 13 code = err_name == "invalid_client" and 401 or 400; | |
| 14 text = err_desc and (err_name..": "..err_desc) or err_name; | |
| 15 context = { oauth2_response = { error = err_name, error_description = err_desc } }; | |
| 16 }); | |
| 17 end | |
| 18 | |
| 19 local function new_access_token(username, host, scope, ttl) | |
| 20 return { | |
| 21 token_type = "bearer"; | |
| 22 access_token = "test-token"; | |
| 23 expires_in = ttl; | |
| 24 -- TODO: include refresh_token when implemented | |
| 25 }; | |
| 26 end | |
| 27 | |
| 28 local grant_type_handlers = {}; | |
| 29 | |
| 30 function grant_type_handlers.password(params) | |
| 31 local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)")); | |
| 32 local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'")); | |
| 33 local request_username, request_host = jid.prepped_split(request_jid); | |
| 34 if params.scope then | |
| 35 return oauth_error("invalid_scope", "unknown scope requested"); | |
| 36 end | |
| 37 if not (request_username and request_host) or not (hosts[request_host]) then | |
| 38 return oauth_error("invalid_request", "invalid JID"); | |
| 39 end | |
| 40 if usermanager.test_password(request_username, request_host, request_password) then | |
| 41 return json.encode(new_access_token(request_username, request_host, nil, nil)); | |
| 42 end | |
| 43 return oauth_error("invalid_grant", "incorrect credentials"); | |
| 44 end | |
| 45 | |
| 46 function handle_token_grant(event) | |
| 47 local params = http.formdecode(event.request.body); | |
| 48 if not params then | |
| 49 return oauth_error("invalid_request"); | |
| 50 end | |
| 51 local grant_type = params.grant_type | |
| 52 local grant_handler = grant_type_handlers[grant_type]; | |
| 53 if not grant_handler then | |
| 54 return oauth_error("unsupported_grant_type"); | |
| 55 end | |
| 56 return grant_handler(params); | |
| 57 end | |
| 58 | |
| 59 module:depends("http"); | |
| 60 module:provides("http", { | |
| 61 route = { | |
| 62 ["POST /token"] = handle_token_grant; | |
| 63 }; | |
| 64 }); | |
| 65 | |
| 66 local http_server = require "net.http.server"; | |
| 67 | |
| 68 module:hook_object_event(http_server, "http-error", function (event) | |
| 69 local oauth2_response = event.error and event.error.context and event.error.context.oauth2_response; | |
| 70 if not oauth2_response then | |
| 71 return; | |
| 72 end | |
| 73 event.response.headers.content_type = "application/json"; | |
| 74 event.response.status_code = event.error.code or 400; | |
| 75 return json.encode(oauth2_response); | |
| 76 end, 5); |
