Mercurial > prosody-modules
view mod_audit/mod_audit.lua @ 5255:001c8fdc91a4
mod_http_oauth2: Add support for the "openid" scope
This "openid" scope is there to signal access to the userinfo endpoint,
which is needed for OIDC support.
We don't actually check this later because the userinfo endpoint only
returns info embedded in the token itself, but in the future we may want
to check this more carefully.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 16 Mar 2023 17:06:35 +0100 |
parents | f3123cbbd894 |
children | 12f7d8b901e0 |
line wrap: on
line source
module:set_global(); local audit_log_limit = module:get_option_number("audit_log_limit", 10000); local cleanup_after = module:get_option_string("audit_log_expires_after", "2w"); local attach_ips = module:get_option_boolean("audit_log_ips", true); local attach_ipv4_prefix = module:get_option_number("audit_log_ipv4_prefix", nil); local attach_ipv6_prefix = module:get_option_number("audit_log_ipv6_prefix", nil); local time_now = os.time; local ip = require "util.ip"; 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 get_ip_network(ip_addr) local _ip = ip.new_ip(ip_addr); local proto = _ip.proto; local network; if proto == "IPv4" and attach_ipv4_prefix then network = ip.truncate(_ip, attach_ipv4_prefix).normal.."/"..attach_ipv4_prefix; elseif proto == "IPv6" and attach_ipv6_prefix then network = ip.truncate(_ip, attach_ipv6_prefix).normal.."/"..attach_ipv6_prefix; end return network; end 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 attach_ips and session.ip then local remote_ip, network = session.ip; if attach_ipv4_prefix or attach_ipv6_prefix then network = get_ip_network(remote_ip); end stanza:text_tag("remote-ip", network or remote_ip); end if session.client_id then stanza:text_tag("client", session.client_id); 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