view plugins/mod_tokenauth.lua @ 12578:10bb58ad5583

executables: Reject Lua 5.1 early Prevents attempting to load libraries that may no longer be found and crashing with a traceback. Platforms like Debian where multiple Lua versions can be installed at the same time and 'lua' pointing to one of the installed interpreters via symlinks, there's the possibility that prosody/prosodyctl may be invoked with Lua 5.1, which will no longer have any of the rest of Prosody libraries available to be require(), and thus would immediately fail with an unfriendly traceback. Checking and aborting early with a friendlier message and reference to more information is better. Part of #1600
author Kim Alvefur <zash@zash.se>
date Sat, 02 Jul 2022 17:27:39 +0200
parents 5efd6865486c
children 86e1187f6274
line wrap: on
line source

local id = require "util.id";
local jid = require "util.jid";
local base64 = require "util.encodings".base64;

local token_store = module:open_store("auth_tokens", "map");

function create_jid_token(actor_jid, token_jid, token_scope, token_ttl)
	token_jid = jid.prep(token_jid);
	if not actor_jid or token_jid ~= actor_jid and not jid.compare(token_jid, actor_jid) then
		return nil, "not-authorized";
	end

	local token_username, token_host, token_resource = jid.split(token_jid);

	if token_host ~= module.host then
		return nil, "invalid-host";
	end

	local token_info = {
		owner = actor_jid;
		created = os.time();
		expires = token_ttl and (os.time() + token_ttl) or nil;
		jid = token_jid;
		session = {
			username = token_username;
			host = token_host;
			resource = token_resource;

			auth_scope = token_scope;
		};
	};

	local token_id = id.long();
	local token = base64.encode("1;"..jid.join(token_username, token_host)..";"..token_id);
	token_store:set(token_username, token_id, token_info);

	return token, token_info;
end

local function parse_token(encoded_token)
	local token = base64.decode(encoded_token);
	if not token then return nil; end
	local token_jid, token_id = token:match("^1;([^;]+);(.+)$");
	if not token_jid then return nil; end
	local token_user, token_host = jid.split(token_jid);
	return token_id, token_user, token_host;
end

function get_token_info(token)
	local token_id, token_user, token_host = parse_token(token);
	if not token_id then
		return nil, "invalid-token-format";
	end
	if token_host ~= module.host then
		return nil, "invalid-host";
	end

	local token_info, err = token_store:get(token_user, token_id);
	if not token_info then
		if err then
			return nil, "internal-error";
		end
		return nil, "not-authorized";
	end

	if token_info.expires and token_info.expires < os.time() then
		return nil, "not-authorized";
	end

	return token_info
end

function revoke_token(token)
	local token_id, token_user, token_host = parse_token(token);
	if not token_id then
		return nil, "invalid-token-format";
	end
	if token_host ~= module.host then
		return nil, "invalid-host";
	end
	return token_store:set(token_user, token_id, nil);
end