module:set_global();
local http = require "util.http";
local jid = require "util.jid";
local json = require "util.json";
local usermanager = require "core.usermanager";
local errors = require "util.error";
local function oauth_error(err_name, err_desc)
return errors.new({
type = "modify";
condition = "bad-request";
code = err_name == "invalid_client" and 401 or 400;
text = err_desc and (err_name..": "..err_desc) or err_name;
context = { oauth2_response = { error = err_name, error_description = err_desc } };
});
end
local function new_access_token(username, host, scope, ttl)
return {
token_type = "bearer";
access_token = "test-token";
expires_in = ttl;
-- TODO: include refresh_token when implemented
};
end
local grant_type_handlers = {};
function grant_type_handlers.password(params)
local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)"));
local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'"));
local request_username, request_host = jid.prepped_split(request_jid);
if params.scope then
return oauth_error("invalid_scope", "unknown scope requested");
end
if not (request_username and request_host) or not (hosts[request_host]) then
return oauth_error("invalid_request", "invalid JID");
end
if usermanager.test_password(request_username, request_host, request_password) then
return json.encode(new_access_token(request_username, request_host, nil, nil));
end
return oauth_error("invalid_grant", "incorrect credentials");
end
function handle_token_grant(event)
local params = http.formdecode(event.request.body);
if not params then
return oauth_error("invalid_request");
end
local grant_type = params.grant_type
local grant_handler = grant_type_handlers[grant_type];
if not grant_handler then
return oauth_error("unsupported_grant_type");
end
return grant_handler(params);
end
module:depends("http");
module:provides("http", {
route = {
["POST /token"] = handle_token_grant;
};
});
local http_server = require "net.http.server";
module:hook_object_event(http_server, "http-error", function (event)
local oauth2_response = event.error and event.error.context and event.error.context.oauth2_response;
if not oauth2_response then
return;
end
event.response.headers.content_type = "application/json";
event.response.status_code = event.error.code or 400;
return json.encode(oauth2_response);
end, 5);