mod_http_oauth2/mod_http_oauth2.lua
changeset 3907 cfeb93b80621
child 3912 8ac5d9933106
equal deleted inserted replaced
3906:341850e8866f 3907: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);