mod_http_xep227: Add support for import via APIs rather than direct store manipulation
In particular this transitions PEP nodes and data to be imported via mod_pep's
APIs, fixing issues with importing at runtime while PEP data may already be
live in RAM.
Next obvious candidate for this approach is rosters, so clients get immediate
roster pushes and other special handling (such as emitting subscribes to reach
the desired subscription state).
local jid = require "util.jid";
local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
local xmlns_push = "urn:xmpp:push:0";
local xmlns_push_filter_unknown = "tigase:push:filter:ignore-unknown:0";
local xmlns_push_filter_muted = "tigase:push:filter:muted:0";
local xmlns_push_filter_groupchat = "tigase:push:filter:groupchat:0";
local xmlns_references = "urn:xmpp:reference:0";
-- https://xeps.tigase.net//docs/push-notifications/encrypt/#41-discovering-support
local function account_disco_info(event)
event.reply:tag("feature", {var=xmlns_push_filter_unknown}):up();
event.reply:tag("feature", {var=xmlns_push_filter_muted}):up();
event.reply:tag("feature", {var=xmlns_push_filter_groupchat}):up();
end
module:hook("account-disco-info", account_disco_info);
function handle_register(event)
local enable = event.stanza:get_child("enable", xmlns_push);
local filter_unknown = enable:get_child("ignore-unknown", xmlns_push_filter_unknown);
if filter_unknown then
event.push_info.filter_unknown = true;
end
local filter_muted = enable:get_child("muted", xmlns_push_filter_muted);
if filter_muted then
local muted_jids = {};
for item in filter_muted:childtags("item") do
muted_jids[jid.prep(item.attr.jid)] = true;
end
event.push_info.muted_jids = muted_jids;
end
local filter_groupchat = enable:get_child("groupchat", xmlns_push_filter_groupchat);
if filter_groupchat then
local groupchat_rules = {};
for item in filter_groupchat:childtags("room") do
groupchat_rules[jid.prep(item.attr.jid)] = {
when = item.attr.allow;
nick = item.attr.nick;
};
end
event.push_info.groupchat_rules = groupchat_rules;
end
end
function handle_push(event)
local push_info = event.push_info;
local stanza = event.original_stanza;
local user_name, user_host = jid.split(stanza.attr.to);
local sender_jid = jid.bare(stanza.attr.from);
if push_info.filter_unknown then
if user_host == module.host and not is_contact_subscribed(user_name, user_host, sender_jid) then
event.reason = "Filtering: unknown sender";
return true;
end
end
if push_info.muted_jids then
if push_info.muted_jids[sender_jid] then
event.reason = "Filtering: muted";
return true;
end
end
if stanza.attr.type == "groupchat" and push_info.groupchat_rules then
local rule = push_info.groupchat_rules[sender_jid];
if rule then
if rule.when == "never" then
event.reason = "Filtering: muted group chat";
return true;
elseif rule.when == "mentioned" then
local mentioned = false;
local our_uri = "xmpp:"..jid.bare(stanza.attr.to);
local our_muc_uri = rule.nick and "xmpp:"..sender_jid.."/"..rule.nick;
for reference in stanza:childtags("reference", xmlns_references) do
if reference.attr.type == "mention" then
local mention_uri = reference.attr.uri;
if mention_uri == our_uri or mention_uri == our_muc_uri then
mentioned = true;
break;
end
end
end
if not mentioned then
event.reason = "Filtering: not mentioned";
return true;
end
end
end
end
end
module:hook("cloud_notify/registration", handle_register);
module:hook("cloud_notify/push", handle_push);