File

mod_export_skeletons/mod_export_skeletons.lua @ 5149:fa56ed2bacab

mod_unified_push: Add support for multiple token backends, including stoage Now that we have ACLs by default, it is no longer necessary to be completely stateless. On 0.12, using storage has benefits over JWT, because it does not expose client JIDs to the push apps/services. In trunk, PASETO is stateless and does not expose client JIDs.
author Matthew Wild <mwild1@gmail.com>
date Sat, 14 Jan 2023 14:31:37 +0000
parent 4821:17fbe82d4bfe
line wrap: on
line source


local t_insert = table.insert;
local t_sort = table.sort;

local sm = require "core.storagemanager";
local um = require "core.usermanager";

local argparse = require "util.argparse";
local dt = require "util.datetime";
local jid = require "util.jid";
local st = require "util.stanza";

local function skeleton(s)
	local o = st.stanza(s.name, { xmlns = s.attr.xmlns });

	local children = {};
	for _, child in ipairs(s.tags) do t_insert(children, skeleton(child)) end
	t_sort(children, function(a, b)
		if a.attr.xmlns == b.attr.xmlns then return a.name < b.name; end
		return (a.attr.xmlns or "") < (b.attr.xmlns or "");
	end);
	for _, child in ipairs(children) do o:add_direct_child(child); end
	return o;
end

local function classify_jid(s)
	if not s then return "" end
	local u, h, r = jid.split(s);
	if r then
		return "full"
	elseif u then
		return "bare"
	elseif h then
		return "host"
	else
		return "invalid"
	end
end

function module.command(arg)
	local opts = argparse.parse(arg, { value_params = { store = true; with = true; start = true; ["end"] = true } });
	local store = opts.store or "archive"; -- so you can pass 'archive2'
	opts.store = nil;
	local query = { with = jid.prep(opts.with); start = dt.parse(opts.start); ["end"] = dt.parse(opts["end"]) };
	local host_initialized = {};
	for _, export_jid in ipairs(arg) do

		local username, host = jid.split(export_jid);
		if not host_initialized[host] then
			sm.initialize_host(host);
			um.initialize_host(host);
			host_initialized[host] = true;
		end

		local archive = module:context(host):open_store(store, "archive");
		local iter, total = assert(archive:find(username, query))
		if total then io.stderr:write(string.format("Processing %d entries\n", total)); end
		for _, item in iter do
			local clean = skeleton(item);

			-- Normalize top level attributes
			clean.attr.type = item.attr.type;
			if clean.attr.type == nil and clean.name == "message" then clean.attr.type = "normal"; end
			clean.attr.id = string.rep("x", math.floor(math.log(1+#(item.attr.id or ""), 2)));
			clean.attr.from = classify_jid(item.attr.from);
			clean.attr.to = classify_jid(item.attr.to);
			print(clean);
		end

	end
end