Mercurial > prosody-modules
view mod_restrict_xmpp/mod_restrict_xmpp.lua @ 5585:5b316088bef5
mod_rest: Use logger of HTTP request in trunk
In Prosody trunk rev c975dafa4303 each HTTP request gained its own log
sink, to make it easy to log things related to each request and group
those messages. Especially where async is used, spreading the request
and response apart as mod_rest does with iq stanzas, this grouped
logging should help find related messages.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 07 Jul 2023 00:10:37 +0200 |
parents | 825c6fb76c48 |
children | 111e970213a0 |
line wrap: on
line source
local array = require "util.array"; local it = require "util.iterators"; local set = require "util.set"; local st = require "util.stanza"; local normal_user_role = "prosody:registered"; local limited_user_role = "prosody:guest"; local features = require "core.features"; -- COMPAT if not features.available:contains("split-user-roles") then normal_user_role = "prosody:user"; limited_user_role = "prosody:restricted"; end module:default_permission(normal_user_role, "xmpp:federate"); module:hook("route/remote", function (event) if not module:may("xmpp:federate", event) then if event.stanza.attr.type ~= "result" and event.stanza.attr.type ~= "error" then module:log("warn", "Access denied: xmpp:federate for %s -> %s", event.stanza.attr.from, event.stanza.attr.to); local reply = st.error_reply(event.stanza, "auth", "forbidden"); event.origin.send(reply); end return true; end end); local iq_namespaces = { ["jabber:iq:roster"] = "contacts"; ["jabber:iq:private"] = "storage"; ["vcard-temp"] = "profile"; ["urn:xmpp:mam:0"] = "history"; ["urn:xmpp:mam:1"] = "history"; ["urn:xmpp:mam:2"] = "history"; ["urn:xmpp:carbons:0"] = "carbons"; ["urn:xmpp:carbons:1"] = "carbons"; ["urn:xmpp:carbons:2"] = "carbons"; ["urn:xmpp:blocking"] = "blocklist"; ["http://jabber.org/protocol/pubsub"] = "pep"; ["http://jabber.org/protocol/disco#info"] = "disco"; }; local legacy_storage_nodes = { ["storage:bookmarks"] = "bookmarks"; ["storage:rosternotes"] = "contacts"; ["roster:delimiter"] = "contacts"; ["storage:metacontacts"] = "contacts"; }; local pep_nodes = { ["storage:bookmarks"] = "bookmarks"; ["urn:xmpp:bookmarks:1"] = "bookmarks"; ["urn:xmpp:avatar:data"] = "profile"; ["urn:xmpp:avatar:metadata"] = "profile"; ["http://jabber.org/protocol/nick"] = "profile"; ["eu.siacs.conversations.axolotl.devicelist"] = "omemo"; ["urn:xmpp:omemo:1:devices"] = "omemo"; ["urn:xmpp:omemo:1:bundles"] = "omemo"; ["urn:xmpp:omemo:2:devices"] = "omemo"; ["urn:xmpp:omemo:2:bundles"] = "omemo"; }; module:hook("pre-iq/bare", function (event) if not event.to_self then return; end local origin, stanza = event.origin, event.stanza; local typ = stanza.attr.type; if typ ~= "set" and typ ~= "get" then return; end local action = typ == "get" and "read" or "write"; local payload = stanza.tags[1]; local ns = payload and payload.attr.xmlns; local proto = iq_namespaces[ns]; if proto == "pep" then local pubsub = payload:get_child("pubsub", "http://jabber.org/protocol/pubsub"); local node = pubsub and #pubsub.tags == 1 and pubsub.tags[1].attr.node or nil; proto = pep_nodes[node] or "pep"; if proto == "pep" and node and node:match("^eu%.siacs%.conversations%.axolotl%.bundles%.%d+$") then proto = "omemo"; -- COMPAT w/ original OMEMO end elseif proto == "storage" then local data = payload.tags[1]; proto = data and legacy_storage_nodes[data.attr.xmlns] or "legacy-storage"; elseif proto == "carbons" then -- This allows access to live messages proto, action = "messages", "read"; elseif proto == "history" then action = "read"; end local permission_name = "xmpp:account:"..(proto and (proto..":") or "")..action; if not module:may(permission_name, event) then module:log("warn", "Access denied: %s ({%s}%s) for %s", permission_name, ns, payload.name, origin.full_jid or origin.id); origin.send(st.error_reply(stanza, "auth", "forbidden", "You do not have permission to make this request ("..permission_name..")")); return true; end end); --module:default_permission("prosody:restricted", "xmpp:account:read"); --module:default_permission("prosody:restricted", "xmpp:account:write"); module:default_permission(limited_user_role, "xmpp:account:messages:read"); module:default_permission(limited_user_role, "xmpp:account:messages:write"); for _, property_list in ipairs({ iq_namespaces, legacy_storage_nodes, pep_nodes }) do for account_property in set.new(array.collect(it.values(property_list))) do module:default_permission(limited_user_role, "xmpp:account:"..account_property..":read"); module:default_permission(limited_user_role, "xmpp:account:"..account_property..":write"); end end module:default_permission("prosody:restricted", "xmpp:account:presence:write"); module:hook("pre-presence/bare", function (event) if not event.to_self then return; end local stanza = event.stanza; if not module:may("xmpp:account:presence:write", event) then module:log("warn", "Access denied: xmpp:account:presence:write for %s", event.origin.full_jid or event.origin.id); event.origin.send(st.error_reply(stanza, "auth", "forbidden", "You do not have permission to send account presence")); return true; end local priority = stanza:get_child_text("priority"); if priority ~= "-1" then if not module:may("xmpp:account:messages:read", event) then module:log("warn", "Access denied: xmpp:account:messages:read for %s", event.origin.full_jid or event.origin.id); event.origin.send(st.error_reply(stanza, "auth", "forbidden", "You do not have permission to receive messages (use presence priority -1)")); return true; end end end);