Mercurial > prosody-modules
view mod_blocking/mod_blocking.lua @ 5416:2393dbae51ed
mod_http_oauth2: Add option for specifying TTL of registered clients
Meant to simplify configuration, since TTL vs ignoring expiration is
expected to be the main thing one would want to configure.
Unsure what the implications of having unlimited lifetime of clients
are, given no way to revoke them currently, short of rotating the
signing secret.
On one hand, it would be annoying to have the client expire.
On the other hand, it is trivial to re-register it.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 04 May 2023 18:41:33 +0200 |
parents | 1856c3aae92d |
children |
line wrap: on
line source
local jid_split = require "util.jid".split; local st = require "util.stanza"; local datamanager = require"util.datamanager"; local xmlns_blocking = "urn:xmpp:blocking"; module:add_feature("urn:xmpp:blocking"); -- Add JID to default privacy list function add_blocked_jid(username, host, jid) local privacy_lists = datamanager.load(username, host, "privacy") or {lists = {}}; local default_list_name = privacy_lists.default; if not privacy_lists.lists then privacy_lists.lists = {} end if not default_list_name then default_list_name = "blocklist"; privacy_lists.default = default_list_name; end local default_list = privacy_lists.lists[default_list_name]; if not default_list then default_list = { name = default_list_name, items = {} }; privacy_lists.lists[default_list_name] = default_list; end local items = default_list.items; local order = items[1] and items[1].order or 0; -- Must come first for i=1,#items do -- order must be unique local item = items[i]; item.order = item.order + 1; if item.type == "jid" and item.action == "deny" and item.value == jid then return false; end end table.insert(items, 1, { type = "jid" , action = "deny" , value = jid , message = false , ["presence-out"] = false , ["presence-in"] = false , iq = false , order = order }); datamanager.store(username, host, "privacy", privacy_lists); return true; end -- Remove JID from default privacy list function remove_blocked_jid(username, host, jid) local privacy_lists = datamanager.load(username, host, "privacy") or {}; local default_list_name = privacy_lists.default; if not default_list_name then return; end local default_list = privacy_lists.lists[default_list_name]; if not default_list then return; end local items = default_list.items; local item, removed = nil, false; for i=1,#items do -- order must be unique item = items[i]; if item.type == "jid" and item.action == "deny" and item.value == jid then table.remove(items, i); removed = true; break; end end if removed then datamanager.store(username, host, "privacy", privacy_lists); end return removed; end function remove_all_blocked_jids(username, host) local privacy_lists = datamanager.load(username, host, "privacy") or {}; local default_list_name = privacy_lists.default; if not default_list_name then return; end local default_list = privacy_lists.lists[default_list_name]; if not default_list then return; end local items = default_list.items; local item; for i=#items,1,-1 do -- order must be unique item = items[i]; if item.type == "jid" and item.action == "deny" then table.remove(items, i); end end datamanager.store(username, host, "privacy", privacy_lists); return true; end function get_blocked_jids(username, host) -- Return array of blocked JIDs in default privacy list local privacy_lists = datamanager.load(username, host, "privacy") or {}; local default_list_name = privacy_lists.default; if not default_list_name then return {}; end local default_list = privacy_lists.lists[default_list_name]; if not default_list then return {}; end local items = default_list.items; local item; local jid_list = {}; for i=1,#items do -- order must be unique item = items[i]; if item.type == "jid" and item.action == "deny" then jid_list[#jid_list+1] = item.value; end end return jid_list; end local function send_push_iqs(username, host, command_type, jids) local bare_jid = username.."@"..host; local stanza_content = st.stanza(command_type, { xmlns = xmlns_blocking }); for _, jid in ipairs(jids) do stanza_content:tag("item", { jid = jid }):up(); end for resource, session in pairs(prosody.bare_sessions[bare_jid].sessions) do local iq_push_stanza = st.iq({ type = "set", to = bare_jid.."/"..resource, id = "blocking-push" }); iq_push_stanza:add_child(stanza_content); session.send(iq_push_stanza); end end function handle_blocking_command(event) local session, stanza = event.origin, event.stanza; local username, host = jid_split(stanza.attr.from); if stanza.attr.type == "set" then if stanza.tags[1].name == "block" then local block = stanza.tags[1]; local block_jid_list = {}; for item in block:childtags() do block_jid_list[#block_jid_list+1] = item.attr.jid; end if #block_jid_list == 0 then session.send(st.error_reply(stanza, "modify", "bad-request")); else for _, jid in ipairs(block_jid_list) do add_blocked_jid(username, host, jid); end session.send(st.reply(stanza)); send_push_iqs(username, host, "block", block_jid_list); end return true; elseif stanza.tags[1].name == "unblock" then local unblock = stanza.tags[1]; local unblock_jid_list = {}; for item in unblock:childtags() do unblock_jid_list[#unblock_jid_list+1] = item.attr.jid; end if #unblock_jid_list == 0 then remove_all_blocked_jids(username, host); else for _, jid_to_unblock in ipairs(unblock_jid_list) do remove_blocked_jid(username, host, jid_to_unblock); end end session.send(st.reply(stanza)); send_push_iqs(username, host, "unblock", unblock_jid_list); return true; end elseif stanza.attr.type == "get" and stanza.tags[1].name == "blocklist" then local reply = st.reply(stanza):tag("blocklist", { xmlns = xmlns_blocking }); local blocked_jids = get_blocked_jids(username, host); for _, jid in ipairs(blocked_jids) do reply:tag("item", { jid = jid }):up(); end session.send(reply); return true; end end module:hook("iq/self/urn:xmpp:blocking:blocklist", handle_blocking_command); module:hook("iq/self/urn:xmpp:blocking:block", handle_blocking_command); module:hook("iq/self/urn:xmpp:blocking:unblock", handle_blocking_command);