File

plugins/mod_tokenauth.lua @ 11769:071715a18394

mod_pubsub: Move reversal of item order in <items> Examples in XEP-0060 suggest that items should be listed in chronological order, but we get them from the archive in reverse order. However when requesting specific items by id the results keep that order and we don't want to flip it again. At some point it would likely be best to use the archive API directly instead of this util.cache-compatible wrapper.
author Kim Alvefur <zash@zash.se>
date Sun, 05 Sep 2021 18:42:44 +0200
parent 10675:5efd6865486c
child 12649: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