Mercurial > prosody-modules
diff mod_audit/mod_audit.lua @ 4938:bc8832c6696b
upstream merge
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 11 May 2022 12:44:32 +0200 |
parents | ae83200fb55f |
children | 4a5837591380 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_audit/mod_audit.lua Wed May 11 12:44:32 2022 +0200 @@ -0,0 +1,85 @@ +module:set_global(); + +local time_now = os.time; +local st = require "util.stanza"; +local moduleapi = require "core.moduleapi"; + +local host_wide_user = "@"; + +local stores = {}; + +local function get_store(self, host) + local store = rawget(self, host); + if store then + return store + end + store = module:context(host):open_store("audit", "archive"); + rawset(self, host, store); + return store; +end + +setmetatable(stores, { __index = get_store }); + + +local function session_extra(session) + local attr = { + xmlns = "xmpp:prosody.im/audit", + }; + if session.id then + attr.id = session.id; + end + if session.type then + attr.type = session.type; + end + local stanza = st.stanza("session", attr); + if session.ip then + stanza:text_tag("remote-ip", session.ip); + end + return stanza +end + +local function audit(host, user, source, event_type, extra) + if not host or host == "*" then + error("cannot log audit events for global"); + end + local user_key = user or host_wide_user; + + local attr = { + ["source"] = source, + ["type"] = event_type, + }; + if user_key ~= host_wide_user then + attr.user = user_key; + end + local stanza = st.stanza("audit-event", attr); + if extra ~= nil then + if extra.session then + local child = session_extra(extra.session); + if child then + stanza:add_child(child); + end + end + if extra.custom then + for _, child in extra.custom do + if not st.is_stanza(child) then + error("all extra.custom items must be stanzas") + end + stanza:add_child(child); + end + end + end + + local id, err = stores[host]:append(nil, nil, stanza, time_now(), user_key); + if err then + module:log("error", "failed to persist audit event: %s", err); + return + else + module:log("debug", "persisted audit event %s as %s", stanza:top_tag(), id); + end +end + +function moduleapi.audit(module, user, event_type, extra) + audit(module.host, user, "mod_" .. module:get_name(), event_type, extra); +end + +module:hook("audit", audit, 0);