mod_audit/mod_audit.lua
author Jonas Schäfer <jonas@wielicki.name>
Tue, 26 Apr 2022 22:37:13 +0200
changeset 4937 08dea42a302a
parent 4936 530d116b7f68
child 4938 ae83200fb55f
permissions -rw-r--r--
mod_audit*: fix luacheck warnings
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4936
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     1
module:set_global();
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     2
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     3
local time_now = os.time;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     4
local st = require "util.stanza";
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     5
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     6
local host_wide_user = "@";
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     7
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     8
local stores = {};
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
     9
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    10
local function get_store(self, host)
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    11
	local store = rawget(self, host);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    12
	if store then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    13
		return store
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    14
	end
4937
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4936
diff changeset
    15
	store = module:context(host):open_store("audit", "archive");
4936
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    16
	rawset(self, host, store);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    17
	return store;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    18
end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    19
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    20
setmetatable(stores, { __index = get_store });
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    21
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    22
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    23
local function session_extra(session)
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    24
	local attr = {
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    25
		xmlns = "xmpp:prosody.im/audit",
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    26
	};
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    27
	if session.id then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    28
		attr.id = session.id;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    29
	end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    30
	if session.type then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    31
		attr.type = session.type;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    32
	end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    33
	local stanza = st.stanza("session", attr);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    34
	if session.ip then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    35
		stanza:text_tag("remote-ip", session.ip);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    36
	end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    37
	return stanza
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    38
end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    39
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    40
local function audit(host, user, source, event_type, extra)
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    41
	if not host or host == "*" then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    42
		error("cannot log audit events for global");
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    43
	end
4937
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4936
diff changeset
    44
	local user_key = user or host_wide_user;
4936
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    45
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    46
	local attr = {
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    47
		["source"] = source,
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    48
		["type"] = event_type,
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    49
	};
4937
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4936
diff changeset
    50
	if user_key ~= host_wide_user then
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4936
diff changeset
    51
		attr.user = user_key;
4936
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    52
	end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    53
	local stanza = st.stanza("audit-event", attr);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    54
	if extra ~= nil then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    55
		if extra.session then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    56
			local child = session_extra(extra.session);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    57
			if child then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    58
				stanza:add_child(child);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    59
			end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    60
		end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    61
		if extra.custom then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    62
			for _, child in extra.custom do
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    63
				if not st.is_stanza(child) then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    64
					error("all extra.custom items must be stanzas")
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    65
				end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    66
				stanza:add_child(child);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    67
			end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    68
		end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    69
	end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    70
4937
08dea42a302a mod_audit*: fix luacheck warnings
Jonas Schäfer <jonas@wielicki.name>
parents: 4936
diff changeset
    71
	local id, err = stores[host]:append(nil, nil, stanza, time_now(), user_key);
4936
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    72
	if err then
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    73
		module:log("error", "failed to persist audit event: %s", err);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    74
		return
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    75
	else
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    76
		module:log("debug", "persisted audit event %s as %s", stanza:top_tag(), id);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    77
	end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    78
end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    79
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    80
local module_api = getmetatable(module).__index;
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    81
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    82
function module_api:audit(user, event_type, extra)
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    83
	audit(self.host, user, "mod_" .. self:get_name(), event_type, extra);
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    84
end
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    85
530d116b7f68 mod_audit*: modules for audit logging in prosody
Jonas Schäfer <jonas@wielicki.name>
parents:
diff changeset
    86
module:hook("audit", audit, 0);