mod_cloud_notify_filters/mod_cloud_notify_filters.lua
changeset 4340 6872e55cfb92
child 5306 ba94a5301985
equal deleted inserted replaced
4339:e03dadd4f2d1 4340:6872e55cfb92
       
     1 local jid = require "util.jid";
       
     2 
       
     3 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
       
     4 
       
     5 local xmlns_push = "urn:xmpp:push:0";
       
     6 local xmlns_push_filter_unknown = "tigase:push:filter:ignore-unknown:0";
       
     7 local xmlns_push_filter_muted = "tigase:push:filter:muted:0";
       
     8 local xmlns_push_filter_groupchat = "tigase:push:filter:groupchat:0";
       
     9 local xmlns_references = "urn:xmpp:reference:0";
       
    10 
       
    11 -- https://xeps.tigase.net//docs/push-notifications/encrypt/#41-discovering-support
       
    12 local function account_disco_info(event)
       
    13 	event.reply:tag("feature", {var=xmlns_push_filter_unknown}):up();
       
    14 	event.reply:tag("feature", {var=xmlns_push_filter_muted}):up();
       
    15 	event.reply:tag("feature", {var=xmlns_push_filter_groupchat}):up();
       
    16 end
       
    17 module:hook("account-disco-info", account_disco_info);
       
    18 
       
    19 function handle_register(event)
       
    20 	local enable = event.stanza:get_child("enable", xmlns_push);
       
    21 
       
    22 	local filter_unknown = enable:get_child("ignore-unknown", xmlns_push_filter_unknown);
       
    23 	if filter_unknown then
       
    24 		event.push_info.filter_unknown = true;
       
    25 	end
       
    26 
       
    27 	local filter_muted = enable:get_child("muted", xmlns_push_filter_muted);
       
    28 	if filter_muted then
       
    29 		local muted_jids = {};
       
    30 		for item in filter_muted:childtags("item") do
       
    31 			muted_jids[jid.prep(item.attr.jid)] = true;
       
    32 		end
       
    33 		event.push_info.muted_jids = muted_jids;
       
    34 	end
       
    35 
       
    36 	local filter_groupchat = enable:get_child("groupchat", xmlns_push_filter_groupchat);
       
    37 	if filter_groupchat then
       
    38 		local groupchat_rules = {};
       
    39 		for item in filter_groupchat:childtags("room") do
       
    40 			groupchat_rules[jid.prep(item.attr.jid)] = {
       
    41 				when = item.attr.allow;
       
    42 				nick = item.attr.nick;
       
    43 			};
       
    44 		end
       
    45 		event.push_info.groupchat_rules = groupchat_rules;
       
    46 	end
       
    47 end
       
    48 
       
    49 function handle_push(event)
       
    50 	local push_info = event.push_info;
       
    51 	local stanza = event.original_stanza;
       
    52 	local user_name, user_host = jid.split(stanza.attr.to);
       
    53 	local sender_jid = jid.bare(stanza.attr.from);
       
    54 
       
    55 	if push_info.filter_unknown then
       
    56 		if user_host == module.host and not is_contact_subscribed(user_name, user_host, sender_jid) then
       
    57 			event.reason = "Filtering: unknown sender";
       
    58 			return true;
       
    59 		end
       
    60 	end
       
    61 
       
    62 	if push_info.muted_jids then
       
    63 		if push_info.muted_jids[sender_jid] then
       
    64 			event.reason = "Filtering: muted";
       
    65 			return true;
       
    66 		end
       
    67 	end
       
    68 
       
    69 	if stanza.attr.type == "groupchat" and push_info.groupchat_rules then
       
    70 		local rule = push_info.groupchat_rules[sender_jid];
       
    71 		if rule then
       
    72 			if rule.when == "never" then
       
    73 				event.reason = "Filtering: muted group chat";
       
    74 				return true;
       
    75 			elseif rule.when == "mentioned" then
       
    76 				local mentioned = false;
       
    77 				local our_uri = "xmpp:"..jid.bare(stanza.attr.to);
       
    78 				local our_muc_uri = rule.nick and "xmpp:"..sender_jid.."/"..rule.nick;
       
    79 				for reference in stanza:childtags("reference", xmlns_references) do
       
    80 					if reference.attr.type == "mention" then
       
    81 						local mention_uri = reference.attr.uri;
       
    82 						if mention_uri == our_uri or mention_uri == our_muc_uri then
       
    83 							mentioned = true;
       
    84 							break;
       
    85 						end
       
    86 					end
       
    87 				end
       
    88 				if not mentioned then
       
    89 					event.reason = "Filtering: not mentioned";
       
    90 					return true;
       
    91 				end
       
    92 			end
       
    93 		end
       
    94 	end
       
    95 end
       
    96 
       
    97 module:hook("cloud_notify/registration", handle_register);
       
    98 module:hook("cloud_notify/push", handle_push);
       
    99