Mercurial > prosody-modules
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 4937:3ddab718f717 | 4938:bc8832c6696b |
|---|---|
| 1 module:set_global(); | |
| 2 | |
| 3 local time_now = os.time; | |
| 4 local st = require "util.stanza"; | |
| 5 local moduleapi = require "core.moduleapi"; | |
| 6 | |
| 7 local host_wide_user = "@"; | |
| 8 | |
| 9 local stores = {}; | |
| 10 | |
| 11 local function get_store(self, host) | |
| 12 local store = rawget(self, host); | |
| 13 if store then | |
| 14 return store | |
| 15 end | |
| 16 store = module:context(host):open_store("audit", "archive"); | |
| 17 rawset(self, host, store); | |
| 18 return store; | |
| 19 end | |
| 20 | |
| 21 setmetatable(stores, { __index = get_store }); | |
| 22 | |
| 23 | |
| 24 local function session_extra(session) | |
| 25 local attr = { | |
| 26 xmlns = "xmpp:prosody.im/audit", | |
| 27 }; | |
| 28 if session.id then | |
| 29 attr.id = session.id; | |
| 30 end | |
| 31 if session.type then | |
| 32 attr.type = session.type; | |
| 33 end | |
| 34 local stanza = st.stanza("session", attr); | |
| 35 if session.ip then | |
| 36 stanza:text_tag("remote-ip", session.ip); | |
| 37 end | |
| 38 return stanza | |
| 39 end | |
| 40 | |
| 41 local function audit(host, user, source, event_type, extra) | |
| 42 if not host or host == "*" then | |
| 43 error("cannot log audit events for global"); | |
| 44 end | |
| 45 local user_key = user or host_wide_user; | |
| 46 | |
| 47 local attr = { | |
| 48 ["source"] = source, | |
| 49 ["type"] = event_type, | |
| 50 }; | |
| 51 if user_key ~= host_wide_user then | |
| 52 attr.user = user_key; | |
| 53 end | |
| 54 local stanza = st.stanza("audit-event", attr); | |
| 55 if extra ~= nil then | |
| 56 if extra.session then | |
| 57 local child = session_extra(extra.session); | |
| 58 if child then | |
| 59 stanza:add_child(child); | |
| 60 end | |
| 61 end | |
| 62 if extra.custom then | |
| 63 for _, child in extra.custom do | |
| 64 if not st.is_stanza(child) then | |
| 65 error("all extra.custom items must be stanzas") | |
| 66 end | |
| 67 stanza:add_child(child); | |
| 68 end | |
| 69 end | |
| 70 end | |
| 71 | |
| 72 local id, err = stores[host]:append(nil, nil, stanza, time_now(), user_key); | |
| 73 if err then | |
| 74 module:log("error", "failed to persist audit event: %s", err); | |
| 75 return | |
| 76 else | |
| 77 module:log("debug", "persisted audit event %s as %s", stanza:top_tag(), id); | |
| 78 end | |
| 79 end | |
| 80 | |
| 81 function moduleapi.audit(module, user, event_type, extra) | |
| 82 audit(module.host, user, "mod_" .. module:get_name(), event_type, extra); | |
| 83 end | |
| 84 | |
| 85 module:hook("audit", audit, 0); |
