Software /
code /
prosody-modules
File
mod_blocking/mod_blocking.lua @ 5425:3b30635d215c
mod_http_oauth2: Support granting zero role-scopes
It seems Very Bad that if you uncheck all roles on the consent page, you
get the default scopes, which seems the opposite of what you probably
intended. Currently, mod_tokenauth will do the same thing, so work is
needed there too to allow issuing tokens without roles.
A token without a role could be used for OIDC login, and not much else.
This seems like a valuable thing to support.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 07 May 2023 19:29:15 +0200 |
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);