Mercurial > prosody-modules
view mod_compat_roles/mod_compat_roles.lua @ 5298:12f7d8b901e0
mod_audit: Support for adding location (GeoIP) to audit events
This can be more privacy-friendly than logging full IP addresses, and also
more informative to a user - IP addresses don't mean much to the average
person, however if they see activity from outside their expected country, they
can immediately identify suspicious activity.
As with IPs, this field is configurable for deployments that would like to
disable it. Location is also not logged when the geoip library is not
available.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 01 Apr 2023 13:11:53 +0100 |
parents | f03f4ec859a3 |
children | 825c6fb76c48 |
line wrap: on
line source
-- Export a module:may() that works on Prosody 0.12 and earlier -- (i.e. backed by is_admin). -- This API is safe because Prosody 0.12 and earlier do not support -- per-session roles - all authorization is based on JID alone. It is not -- safe on versions that support per-session authorization. module:set_global(); local moduleapi = require "core.moduleapi"; -- If module.may already exists, abort if moduleapi.may then return; end local jid_split = require "util.jid".split; local um_is_admin = require "core.usermanager".is_admin; local function get_jid_role_name(jid, host) if um_is_admin(jid, "*") then return "prosody:operator"; elseif um_is_admin(jid, host) then return "prosody:admin"; end return nil; end local function get_user_role_name(username, host) return get_jid_role_name(username.."@"..host, host); end -- permissions[host][role_name][permission_name] = is_permitted local permissions = {}; local role_inheritance = { ["prosody:operator"] = "prosody:admin"; ["prosody:admin"] = "prosody:user"; ["prosody:user"] = "prosody:restricted"; }; local function role_may(host, role_name, permission) local host_roles = permissions[host]; if not host_roles then return false; end local role_permissions = host_roles[role_name]; if not role_permissions then return false; end local next_role = role_inheritance[role_name]; return not not permissions[role_name][permission] or (next_role and role_may(host, next_role, permission)); end function moduleapi.may(self, action, context) if action:byte(1) == 58 then -- action begins with ':' action = self.name..action; -- prepend module name end if type(context) == "string" then -- check JID permissions local role; local node, host = jid_split(context); if host == self.host then role = get_user_role_name(node, self.host); else role = get_jid_role_name(context, self.host); end if not role then self:log("debug", "Access denied: JID <%s> may not %s (no role found)", context, action); return false; end local permit = role_may(self.host, role, action); if not permit then self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", context, action, role.name); end return permit; end local session = context.origin or context.session; if type(session) ~= "table" then error("Unable to identify actor session from context"); end if session.type == "s2sin" or (session.type == "c2s" and session.host ~= self.host) then local actor_jid = context.stanza.attr.from; local role_name = get_jid_role_name(actor_jid); if not role_name then self:log("debug", "Access denied: JID <%s> may not %s (no role found)", actor_jid, action); return false; end local permit = role_may(self.host, role_name, action, context); if not permit then self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", actor_jid, action, role_name); end return permit; end end function moduleapi.default_permission(self, role_name, permission) local p = permissions[self.host]; if not p then p = {}; permissions[self.host] = p; end local r = p[role_name]; if not r then r = {}; p[role_name] = r; end r[permission] = true; end function moduleapi.default_permissions(self, role_name, permission_list) for _, permission in ipairs(permission_list) do self:default_permission(role_name, permission); end end function module.add_host(host_module) permissions[host_module.host] = {}; function host_module.unload() permissions[host_module.host] = nil; end end