Software /
code /
prosody-modules
File
mod_blocking/mod_blocking.lua @ 5185:09d6bbd6c8a4
mod_http_oauth2: Fix treatment of 'redirect_uri' parameter in code flow
It's optional and the one stored in the client registration should
really be used instead. RFC 6749 says an URI provided as parameter MUST
be validated against the stored one but does not say how.
Given that the client needs their secret to proceed, it seems fine to
leave this for later.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 02 Mar 2023 22:00:42 +0100 |
parent | 3318:1856c3aae92d |
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);